/* * miscellaneous geometric functions * dadd(p,q) a+b * dsub(p,q) a-b * dlerp(p,d,a) p+a*d * dlen(p) sqrt(p.x^2 + p.y^2) * datan2(x,y) atan2(x, y) in degrees * same(x,y) fabs(x-y)<(.1 pixel) * deqpt(p,q) same(p.x, q.x) && same(p.y, q.y) * D2P(p) convert Dpoint (inch coords, y up) to Point (pixel coords, y down), * mapping origin to lower left corner of screen window * P2D(p) convert Point to Dpoint, inverse of D2P * dmul(p, a) p*a * dreflect(p,q,r) reflect p through line [q,r] * dmidpt(p,q) (p+q)/2 * circumcenter(p,q,r) circumcenter of triangle pqr * triarea(p,q,r) area of triangle pqr * circintercirc(c0,r0,c1,r1,i0,i1) * store intersection points of circles (c0,r0) and (c1,r1) in *i0 * and *i1. return the number of intersections. * segintercircle(p0,p1,cen,r,i0,i1) * store intersections of line segment [p0,p1] and circle (cen,r) in * *i0 and *i1. return the number of intersections. * seginterseg(p0,p1,q0,q1,i) * store intersection of segment [p0,p1] with [q0,q1] in *i. return * number of intersections (0 or 1). * seginterarc(p0,p1,a0,a1,a2,i0,i1) * store intersections of line segment [p0,p1] and arc (a0,a1,a2) in * *i0 and *i1. return the number of intersections. * dptinrect(p,r) is point p in rectangle r? * drectxrect(r1,r2) do rectangles r1 and r2 intersect? * drcanon(r) make rectangle canonical (min.x<=max.x && min.y<=max.y) * pldist(p,q,r) distance of point p from segment [q,r] * dunion(r, s) smallest rectangle containing two rectangles */ #include "art.h" Dpoint dadd(Dpoint p, Dpoint q){ p.x+=q.x; p.y+=q.y; return p; } Dpoint dsub(Dpoint p, Dpoint q){ p.x-=q.x; p.y-=q.y; return p; } Dpoint dlerp(Dpoint p, Dpoint dp, Flt alpha){ p.x+=dp.x*alpha; p.y+=dp.y*alpha; return p; } Dpoint dcomb2(Dpoint p, Flt wp, Dpoint q, Flt wq){ Flt den=wp+wq; p.x=(p.x*wp+q.x*wq)/den; p.y=(p.y*wp+q.y*wq)/den; return p; } Dpoint dcomb3(Dpoint p, Flt wp, Dpoint q, Flt wq, Dpoint r, Flt wr){ Flt den=wp+wq+wr; p.x=(p.x*wp+q.x*wq+r.x*wr)/den; p.y=(p.y*wp+q.y*wq+r.y*wr)/den; return p; } Flt dlen(Dpoint p){ return sqrt(p.x*p.x+p.y*p.y); } /* * arctangent in degrees */ Flt datan2(Flt x, Flt y){ return degrees(atan2(x, y)); } /* * the angle subtended by pq at the origin */ Flt angle(Dpoint p, Dpoint q){ return datan2(p.x*q.y+p.y*q.x, p.x*q.x-p.y*q.y); } /* * absolute equality comparison */ int same(Flt a, Flt b){ return fabs(a-b)=den) return p1; return dlerp(p0, q, num/den); } /* * Compute intersections of circles centered at c[01] with * radii r[01]. Return number of intersections, store values * through i[01] */ int circintercirc(Dpoint c0, Flt r0, Dpoint c1, Flt r1, Dpoint *i){ Flt r0sq=r0*r0, r1sq=r1*r1; Dpoint c10=dsub(c1, c0), p, d; Flt dsq=c10.x*c10.x+c10.y*c10.y; Flt rdiff, rsum, root, dinv, alpha; if(dsq<=SMALL*SMALL) return 0; /* common origin */ rdiff=r1sq-r0sq; rsum=r0sq+r1sq; root=2.*rsum*dsq-dsq*dsq-rdiff*rdiff; if(root<-SMALL) return 0; /* circles don't touch */ dinv=.5/dsq; alpha=.5-rdiff*dinv; p=dlerp(c0, c10, alpha); if(root=0.){ *i++=ia[j]; ninter++; } return ninter; } int circinterarc(Dpoint cen, Flt r, Dpoint a0, Dpoint a1, Dpoint a2, Dpoint *i){ Dpoint acen, ia[2]; Flt ar, area; int ninter=0, n, j; if(pldist(a0, a1, a2)=0.){ *i++=ia[j]; ninter++; } return ninter; } int arcinterarc(Dpoint a0, Dpoint a1, Dpoint a2, Dpoint b0, Dpoint b1, Dpoint b2, Dpoint *i){ Dpoint acen, ia[2]; Flt ar, area; int ninter=0, n, j; if(pldist(a0, a1, a2)=0.){ *i++=ia[j]; ninter++; } return ninter; } int dptinrect(Dpoint p, Drectangle r){ return r.min.x<=p.x && p.x<=r.max.x && r.min.y<=p.y && p.y<=r.max.y; } int drectxrect(Drectangle r1, Drectangle r2){ return r1.min.x<=r2.max.x && r2.min.x<=r1.max.x && r1.min.y<=r2.max.y && r2.min.y<=r1.max.y; } Drectangle drcanon(Drectangle r){ Flt t; if(r.min.x>r.max.x){ t=r.min.x; r.min.x=r.max.x; r.max.x=t; } if(r.min.y>r.max.y){ t=r.min.y; r.min.y=r.max.y; r.max.y=t; } return r; } /* * distance from point p to line [p0,p1] */ Flt pldist(Dpoint p, Dpoint p0, Dpoint p1){ Dpoint d, e; Flt dd, de, dsq; d=dsub(p1, p0); e=dsub(p, p0); dd=d.x*d.x+d.y*d.y; de=d.x*e.x+d.y*e.y; if(ddr.max.x) r.max.x=s.max.x; if(s.max.y>r.max.y) r.max.y=s.max.y; return r; } Drectangle draddp(Drectangle r, Dpoint p){ return Drpt(dadd(r.min, p), dadd(r.max, p)); }