En el encabezado “graphics.h” de la biblioteca BGI hay una función rebanada de pastel en ese archivo de encabezado, su sintaxis es:
#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]
¿Podemos hacer un pastel en C/C++ sin usar esta función integrada de la biblioteca BGI? Por favor, ayuda. Intenté hacerlo con la ayuda de los algoritmos de generación de líneas y círculos de punto medio.
Mi código hasta ahora:
#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();
}
Pude hacer la parte del cálculo donde usé la ecuación paramétrica del círculo, pero no pude generar la figura usando el graphics.h
función. Un poco de ayuda estaría bien. Gracias de antemano.
Mientras ejecuto este programa, recibo este 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)
¿Por qué no usar vectores?


Asi que (0,0)
pastel centrado de radio r
Esta determinado por:
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
el CW/CCW se determina calculando el producto cruzado 3D y examinando el signo de los resultados en la coordenada z…
por lo tanto, procese todos los píxeles en el círculo descrito en el cuadrado y renderice todos los píxeles que cumplan con las 3 condiciones.
Algo como esto:
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
}
Sin embargo, no uso BGI, así que simplemente cambie el Pixels[sy][sx]=c;
con tu putpixel(sx,sy,c);
y elimine los intervalos de verificación obsoletos para sx,sy
. Quitar también la resolución. xs,ys
y Pixels
variables
Aquí vista previa para (xs2,ys2
es el mío en medio de la pantalla):
pie(xs2,ys2,ys2-200,10,50,0x00FF0000);

Tenga en cuenta que tengo color RGB de 32 bits en lugar de los de 8 bits indexados y los ángulos están en grados. También tenga en cuenta que el eje y de la mina apunta hacia abajo, por lo que el ángulo de incremento va en el sentido de las agujas del reloj a partir del eje x (apuntando hacia la derecha)
Sin embargo, esto solo funciona para tartas por debajo de 180 grados. Para los más grandes, debe invertir las condiciones del producto cruzado para que se representen cuando no estén dentro de la parte del pastel no llena, en lugar de algo como esto:
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);
El código se puede optimizar aún más, por ejemplo x*uy
se puede cambiar a la adición en el ciclo como for(...,xuy=x*uy;...;...,xuy+=uy)
eliminando la multiplicación lenta de los bucles internos. Lo mismo ocurre con las 4 termias en las condiciones de productos cruzados.
[edit1] Para ser más claro tenemos algo como esto:
for (x=-r,xx=x*x,sx=x0+x;x<=+r;x++,xx=x*x,sx++)
{
if (...(x*uy)...) { do something }
}
la (x*uy)
se calcula en cada iteración de x
. Él x
está aumentando, por lo que podemos calcular el valor de (x*uy)
del valor anterior ((x-1)*uy)+uy
que no necesita multiplicación como ((x-1)*uy)
es el valor de la última iteración. Entonces, agregar una sola variable que lo contiene puede eliminar la multiplicación repetida:
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 }
}
entonces la multiplicación inicial se hace solo una vez y de ahí su suma…
Además, esta forma de renderizar es totalmente paralelizable…
No hay ningún intento de dibujar nada en su código.
– Jabberwocky
3 oct 2019 a las 15:49
@RichardCritten estoy usando el “compilador gcc”[ubuntu 16.0.4]
– usuario10626935
3 oct 2019 a las 15:52
@Jabberwocky “¡No use herramientas que sean más antiguas que usted!” ¡ahora se ha agregado a mi lista de Great Life Quotes! (Junto con cosas como “¡Nunca comas nada más grande que tu cabeza!”)
– Adrián Mole
3 oct 2019 a las 15:53
@NetranjitBorgohain necesita mostrarnos su código defectuoso. El código en su pregunta no contiene ningún intento de dibujar nada, por lo tanto, no podemos decir qué está mal.
– Jabberwocky
3 oct 2019 a las 16:03
La función de círculo no funcionará de fábrica porque SOLO hace un círculo. Puede borrar la parte del círculo que no desea dibujar sobre él, pero probablemente esté mejor usando una función de dibujar arco. Una alternativa inferior es volver a implementar la función de círculo y detenerse en parte, lo que da como resultado un arco.
– usuario4581301
3 oct 2019 a las 19:12