简体   繁体   English

在 C 中生成一个“pieslice”,而不使用 graphics.h 的 pieslice()

[英]Generate a “pieslice” in C without using the pieslice() of graphics.h

In the BGI library's "graphics.h" header there is a function pieslice in that header file,its syntax is:在 BGI 库的 "graphics.h" header 中有一个 function pieslice在 header 文件中,它的语法是:

#include <graphics.h>

void pieslice(int x, int y, int stangle, int endangle, int radius);

[x,y are the center of the circle,stangle and endangle are the starting and end angles respectively] [x,y 是圆心,stangle 和 endangle 分别是起始角和结束角]

Can we make a pieslice in C/C++ without using this in-built function of the BGI library.Please help.我们可以在不使用 BGI 库的内置 function 的情况下用 C/C++ 制作一个 pieslice。请帮助。 Tried making it with the help of the lines and mid-point circle generation algorithms.尝试在线条和中点圆生成算法的帮助下制作它。

My code so far:到目前为止我的代码:

#include<stdio.h>
#include<graphics.h>


static const double PI =3.141592

int main()
{
    int gd=DETECT,gm;
    initgraph(&gd,&gm,NULL);
    int xc,yc,r,st_angle,ed_angle,k;
    printf("Enter the centers of pieslice:\n");
    scanf("%d %d",&xc,&yc);
    printf("Enter the radius:\n");
    scanf("%d",&r);
    printf("Enter the starting angle:\n");
    scanf("%d",&st_angle);
    printf("Enter the end angle:\n");
    scanf("%d",&ed_angle);


    for(k=st_angle; k<=ed_angle;k++)
    {   
        double radians =(PI /180.0) * k;
        int X = xc+ cos(radians) * r;
        int Y = yc+ sin(radians) * r;
        putpixel(x,y,WHITE);
        delay(5000);

    }
void wait_for_char()
{

    //Wait for a key press
    int in = 0;

    while (in == 0) {
        in = getchar();
    }
}
getch();
}

I was able to do the calculation part where i used the parametric equation of circle,but unable to generate the figure using the graphics.h function.我能够完成使用圆参数方程的计算部分,但无法使用graphics.h生成图形。h function。 Some help would be nice.一些帮助会很好。 Thank you in advance.先感谢您。

While running this program,i am getting this error:运行此程序时,我收到此错误:

[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
a.out: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
a.out: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
Aborted (core dumped)


why not use vectors?为什么不使用向量?

馅饼

外接正方形

So (0,0) centered pie of radius r is determined by:因此,半径为r(0,0)中心饼图由下式确定:

u = (cos(a0),sin(a0))
v = (cos(a1),sin(a1))
x^2 + y^2 <= r^2 // circle
(x,y) x u ->  CW
(x,y) x v -> CCW

the CW/CCW is determined by computing 3D cross product and examining the sign of results z coordinate...通过计算 3D 叉积并检查结果 z 坐标的符号来确定 CW/CCW...

so process all pixels in circle outscribed square and render all pixels that complies all 3 conditions.因此处理圆形外接正方形中的所有像素并渲染符合所有 3 个条件的所有像素。

Something like this:像这样的东西:

void pie(int x0,int y0,int r,int a0,int a1,DWORD c)
    {
    // variables
    int  x, y,      // circle centered point
        xx,yy,rr,   // x^2,y^2,r^2
        ux,uy,      // u
        vx,vy,      // v
        sx,sy;      // pixel position
    // my Pixel access (remove these 3 lines)
    int **Pixels=Main->pyx;         // Pixels[y][x]
    int   xs=Main->xs;              // resolution
    int   ys=Main->ys;
    // init variables
    rr=r*r;
    ux=double(r)*cos(double(a0)*M_PI/180.0);
    uy=double(r)*sin(double(a0)*M_PI/180.0);
    vx=double(r)*cos(double(a1)*M_PI/180.0);
    vy=double(r)*sin(double(a1)*M_PI/180.0);
    // render                                       |<-- remove these -->|
    for (y=-r,yy=y*y,sy=y0+y;y<=+r;y++,yy=y*y,sy++) if ((sy>=0)&&(sy<ys))
     for (x=-r,xx=x*x,sx=x0+x;x<=+r;x++,xx=x*x,sx++) if ((sx>=0)&&(sx<xs))
      if (xx+yy<=rr)          // inside circle
       if ((x*uy)-(y*ux)<=0)  // x,y is above a0 in clockwise direction
        if ((x*vy)-(y*vx)>=0) // x,y is below a1 in counter clockwise direction
         Pixels[sy][sx]=c; // change for putpixel
    }

However I do not use BGI so just change the Pixels[sy][sx]=c;但是我不使用 BGI,所以只需更改Pixels[sy][sx]=c; with your putpixel(sx,sy,c);用你的putpixel(sx,sy,c); and remove obsolete range check ifs for sx,sy .并删除sx,sy的过时范围检查 ifs。 Also remove the resolution xs,ys and Pixels variables.同时删除分辨率xs,ysPixels变量。

Here preview for ( xs2,ys2 is mine middle of screen):这里预览( xs2,ys2是我的屏幕中间):

pie(xs2,ys2,ys2-200,10,50,0x00FF0000);

预习

Note that I have 32 bit RGB color instead of your indexed 8 bit ones and angles are in degrees.请注意,我有 32 位 RGB 颜色而不是您的索引 8 位颜色,角度以度为单位。 Also note that mine y axis points down so incrementing angle is going clockwise starting from the x axis (pointing to right)另请注意,我的 y 轴指向下方,因此增量角度从 x 轴开始顺时针方向(指向右侧)

This however works only for pies below 180 degrees.然而,这仅适用于 180 度以下的馅饼。 For bigger ones you need to invert the cross product conditions to render when not inside the not filled pie part instead something like this:对于较大的,您需要反转叉积条件以在不在未填充的饼图部分内时进行渲染,而不是像这样:

void pie(int x0,int y0,int r,int a0,int a1,DWORD c) // a0 < a1
    {
    // variables
    int  x, y,      // circle centered point
        xx,yy,rr,   // x^2,y^2,r^2
        ux,uy,      // u
        vx,vy,      // v
        sx,sy;      // pixel position
    // my Pixel access
    int **Pixels=Main->pyx;         // Pixels[y][x]
    int   xs=Main->xs;              // resolution
    int   ys=Main->ys;
    // init variables
    rr=r*r;
    ux=double(r)*cos(double(a0)*M_PI/180.0);
    uy=double(r)*sin(double(a0)*M_PI/180.0);
    vx=double(r)*cos(double(a1)*M_PI/180.0);
    vy=double(r)*sin(double(a1)*M_PI/180.0);
    // handle big/small pies
    x=a1-a0;
    if (x<0) x=-x;
    // render small pies
    if (x<180)
        {
        for (y=-r,yy=y*y,sy=y0+y;y<=+r;y++,yy=y*y,sy++) if ((sy>=0)&&(sy<ys))
         for (x=-r,xx=x*x,sx=x0+x;x<=+r;x++,xx=x*x,sx++) if ((sx>=0)&&(sx<xs))
          if (xx+yy<=rr)           // inside circle
           if (((x*uy)-(y*ux)<=0)  // x,y is above a0 in clockwise direction
             &&((x*vy)-(y*vx)>=0)) // x,y is below a1 in counter clockwise direction
             Pixels[sy][sx]=c;
        }
    else{
        for (y=-r,yy=y*y,sy=y0+y;y<=+r;y++,yy=y*y,sy++) if ((sy>=0)&&(sy<ys))
         for (x=-r,xx=x*x,sx=x0+x;x<=+r;x++,xx=x*x,sx++) if ((sx>=0)&&(sx<xs))
          if (xx+yy<=rr)           // inside circle
           if (((x*uy)-(y*ux)<=0)  // x,y is above a0 in clockwise direction
             ||((x*vy)-(y*vx)>=0)) // x,y is below a1 in counter clockwise direction
             Pixels[sy][sx]=c;
        }
    }

预览 大馅饼

pie(xs2,ys2,ys2-200,50,340,0x00FF0000);

The code can be further optimized for example x*uy can be changed to addition in for cycle like for(...,xuy=x*uy;...;...,xuy+=uy) eliminating slow multiplication from inner loops.代码可以进一步优化,例如x*uy可以更改为 for 循环中的加法,例如for(...,xuy=x*uy;...;...,xuy+=uy)消除内部循环的慢乘法. The same goes for all 4 therms in the cross product conditions.叉积条件下的所有 4 个therm 也是如此。

[edit1] To be more clear we have something like this: [edit1]为了更清楚,我们有这样的事情:

     for (x=-r,xx=x*x,sx=x0+x;x<=+r;x++,xx=x*x,sx++)
       {
       if (...(x*uy)...) { do something }
       }

the (x*uy) is computed on each iteration of x . (x*uy)x的每次迭代中计算。 The x is incrementing so we can compute the value of (x*uy) from the previous value ((x-1)*uy)+uy which does not need multiplication as ((x-1)*uy) is the value from last iteration. x是递增的,所以我们可以从前一个值((x-1)*uy)+uy计算(x*uy)的值,这不需要乘法,因为((x-1)*uy)是来自最后一次迭代。 So adding single variable that holds it can get rid of the repeated multiplication:因此,添加包含它的单个变量可以摆脱重复乘法:

     int xuy; //              ********                       *******
     for (x=-r,xx=x*x,sx=x0+x,xuy=x*uy;x<=+r;x++,xx=x*x,sx++,xuy+=uy)
       {
       if (...(xuy)...) { do something }
       }

so the initial multiplication is done just once and from then its just addition...所以初始乘法只进行一次,然后它只是加法......

Also this way of rendering is fully parallelisable...这种渲染方式也是完全可并行的......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM