#include #include #include #include "list.h" #include "types.h" #include "intcgm.h" #include "intcgm6.h" #include "ellipse.h" #ifndef PI #define PI 3.14159265358979323846 #endif #define ANGMIN 0.00001 /* Adjust the circle parametrization for the elipsis parametrization */ double cgm_AdjArc ( double arc, double w, double h ) { double value; if ((fabs(w*sin(arc))<1e-99) && (fabs(h*cos(arc))<1e-99)) value = 0.0; else value = atan2(w*sin(arc), h*cos(arc)); if ( arc > PI ) value += 2*PI; if ( arc < -PI ) value -= 2*PI; return value; } /* Desenha um arco de Elipse */ void cgm_ElpArc ( double xc, double yc, double w, double h, double r, double a1, double a2, int n, int tipo ) { /* Onde: (xc,yc) Centro (w,h) Largura e altura (diametro na direcao dos eixos principais) r Inclinacao dos eixos principais com relacao x e y a1,a2 Angulos incial e final do arco [-360,+360] Note-se que o sentido e' dado pela diferenca a2-a1, ou seja, 30 a 330 e' trigonometrico 30 a -30 e' horario n Numero de segmentos da poligonal equivalente (64 parece ser um bom numero) tipo 0=aberto 1=fechado(torta) 2=fechado(corda) */ double da, c, s, sx, sy, ang, xant, yant; double px, py, tx, ty, txant, tyant, dx, dy; int i, inicio; /* Reduz de diametro a raio */ w = w/2; h = h/2; /* Transforma graus em radianos e ajusta a os angulos da parametrizacao */ a1 = cgm_AdjArc(a1,w,h); a2 = cgm_AdjArc(a2,w,h); if ( a2>a1 ) ang = a2 - a1; else ang = 2*PI - ( a1 - a2 ); /* Gera os pontos do arco centrado na origem com os eixos em x e y */ da = ang/n; c = cos(da); s = sin(da); sx = -w*s/h; sy = h*s/w; if ( tipo==1 || tipo==2 ) { long int cor; cor = cgm_getcolor ( intcgm_fill_att.color ); cdCanvasSetForeground (intcgm_canvas, cor ); cdCanvasBegin(intcgm_canvas, cgm_setintstyle(intcgm_fill_att.int_style) ); } else { long int cor; int size = (int)floor(intcgm_line_att.width+.5); cdCanvasLineStyle (intcgm_canvas, intcgm_line_att.type ); cdCanvasLineWidth (intcgm_canvas, size>0? size: 1 ); cor = cgm_getcolor ( intcgm_line_att.color ); cdCanvasSetForeground (intcgm_canvas, cor ); } dx = (fabs(r)>ANGMIN) ? sin(r) : 0; dy = (fabs(r)>ANGMIN) ? cos(r) : 1; xant = w*cos(a1); yant = h*sin(a1); txant = xc+dy*xant-dx*yant; /* Inclina (se for o caso) e translada */ tyant = yc+dx*xant+dy*yant; /* Inclina (se for o caso) e translada */ if ( tipo==1 ) { cdCanvasVertex (intcgm_canvas, cgm_vdcx2canvas(xc), cgm_vdcy2canvas(yc) ); cdCanvasVertex (intcgm_canvas, cgm_vdcx2canvas(txant), cgm_vdcy2canvas(tyant) ); inicio = 2; } else if ( tipo==2 ) { cdCanvasVertex (intcgm_canvas, cgm_vdcx2canvas(txant), cgm_vdcy2canvas(tyant) ); inicio = 1; } for ( i=inicio; i<=(n+inicio-1); i++ ) { px = c*xant+sx*yant; py = sy*xant+c*yant; tx = xc+dy*px-dx*py; /* Inclina (se for o caso) e translada */ ty = yc+dx*px+dy*py; /* Inclina (se for o caso) e translada */ if ( tipo==0 ) cdCanvasLine (intcgm_canvas, cgm_vdcx2canvas(txant), cgm_vdcy2canvas(tyant), cgm_vdcx2canvas(tx), cgm_vdcy2canvas(ty) ); else cdCanvasVertex (intcgm_canvas, cgm_vdcx2canvas(tx), cgm_vdcy2canvas(ty) ); xant = px; yant = py; txant = tx; tyant = ty; } /* Desenha */ if ( tipo==1 || tipo==2 ) cdCanvasEnd(intcgm_canvas); }