#include "art.h" /* * return the closest point on box ip to point testp. */ Dpoint nearbox(Item *ip, Dpoint testp){ Dpoint p=testp, p0=ip->p[0], p1=ip->p[1]; Flt d0, d1, d2, d3; if(p0.x>p1.x){ d0=p0.x; p0.x=p1.x; p1.x=d0; } if(p0.y>p1.y){ d0=p0.y; p0.y=p1.y; p1.y=d0; } if(p.xp1.x) p.x=p1.x; if(p.yp1.y) p.y=p1.y; d0=p.x-p0.x; d1=p1.x-p.x; d2=p.y-p0.y; d3=p1.y-p.y; if(d0p[0]); Point p1=D2P(ip->p[1]); segment(b, p0, Pt(p1.x, p0.y), bits, c); segment(b, Pt(p1.x, p0.y), p1, bits, c); segment(b, p1, Pt(p0.x, p1.y), bits, c); segment(b, Pt(p0.x, p1.y), p0, bits, c); } #define right(p) Dpt((p).x+1, (p).y) #define up(p) Dpt((p).x, (p).y+1) #define left(p) Dpt((p).x-1, (p).y) #define down(p) Dpt((p).x, (p).y-1) void editbox(void){ Item *s=selection; Dpoint hs, cen, p, p01, p10; Flt rad, r; int which; if(s->p[0].x>s->p[1].x){ r=s->p[0].x; s->p[0].x=s->p[1].x; s->p[1].x=r; } if(s->p[0].y>s->p[1].y){ r=s->p[0].y; s->p[0].y=s->p[1].y; s->p[1].y=r; } cen=dmidpt(s->p[0], s->p[1]); hs=dsub(s->p[1], cen); p=Dpt(cen.x-hs.x, cen.y-hs.y); rad=dist(arg[0], p); which=0; p=Dpt(cen.x-hs.x, cen.y ); if((r=dist(arg[0], p))p[0].x, s->p[1].y); p10=Dpt(s->p[1].x, s->p[0].y); msg("case %d", which); switch(which){ case 0: /* s->p[1] fixed */ hotline(s->p[1], left(s->p[1]), L); hotline(s->p[1], down(s->p[1]), L); track(movep, 0, s); break; case 1: /* p10, s->p[1] fixed */ hotline(p10, s->p[1], L|R); hotline(p10, down(p01), L); hotline(s->p[1], down(s->p[1]), L); track(movex0, 0, s); break; case 2: /* p10 fixed */ hotline(p10, right(p01), L); hotline(p10, down(p01), L); track(movex0y1, 0, s); break; case 3: /* p01, s->p[1] fixed */ hotline(p01, s->p[1], L|R); hotline(p01, left(p10), L); hotline(s->p[1], left(s->p[1]), L); track(movey0, 0, s); break; case 4: /* all moving */ track(moveall, 0, s); break; case 5: /* p10, s->p[0] fixed */ hotline(p10, s->p[0], L|R); hotline(p10, left(p01), L); hotline(s->p[0], left(s->p[0]), L); track(movey1, 0, s); break; case 6: /* p01 fixed */ hotline(p01, left(p10), L); hotline(p01, up(p10), L); track(movex1y0, 0, s); break; case 7: /* p01, s->p[0] fixed */ hotline(p01, s->p[0], L|R); hotline(p01, up(p10), L); hotline(s->p[0], up(s->p[0]), L); track(movex1, 0, s); break; case 8: /* s->p[0] fixed */ hotline(s->p[0], right(s->p[0]), L); hotline(s->p[0], up(s->p[0]), L); track(movep, 1, s); break; } } void translatebox(Item *ip, Dpoint delta){ ip->p[0]=dadd(ip->p[0], delta); ip->p[1]=dadd(ip->p[1], delta); } void deletebox(Item *ip){ } void writebox(Item *ip, int f){ fprint(f, "b %.3f %.3f %.3f %.3f\n", ip->p[0].x, ip->p[0].y, ip->p[1].x, ip->p[1].y); } void activatebox(Item *ip){ hotline(ip->p[0], Dpt(ip->p[0].x, ip->p[1].y), L|R); hotline(Dpt(ip->p[0].x, ip->p[1].y), ip->p[1], L|R); hotline(ip->p[1], Dpt(ip->p[1].x, ip->p[0].y), L|R); hotline(Dpt(ip->p[1].x, ip->p[0].y), ip->p[0], L|R); } /* * This should really check that the boundary of ip intersects r. * Now it checks that the interior of ip intersects r. */ int inboxbox(Item *ip, Drectangle r){ return drectxrect(drcanon(Drpt(ip->p[0], ip->p[1])), r); } Drectangle bboxbox(Item *ip){ return drcanon(Drpt(ip->p[0], ip->p[1])); } Dpoint nearvertbox(Item *ip, Dpoint testp){ Dpoint hs, cen, p, close; Flt rad, r; cen=dmidpt(ip->p[0], ip->p[1]); hs=dsub(ip->p[1], cen); p=Dpt(cen.x-hs.x, cen.y-hs.y); rad=dist(testp, p); close=p; p=Dpt(cen.x-hs.x, cen.y ); if((r=dist(testp, p))