#include "art.h"
Image *color;
/*
* return the closest point on circle ip to point testp. If testp==ip->p[0], no such point
* exists, so we return testp.
*/
Dpoint nearcircle(Item *ip, Dpoint testp){
Flt d;
Dpoint p;
p=dsub(testp, ip->p[0]);
d=dlen(p);
if(d==0) return testp;
return dlerp(ip->p[0], p, ip->r/d);
}
void drawcircle(Item *ip, Image *b, Image *color){
ellipse(b, D2P(ip->p[0]), (int)(ip->r*DPI), (int)(ip->r*DPI), 0, color, ZP);
}
void editcircle(void){
if(dist(arg[0], selection->p[0])<.5*selection->r)
track(movep, 0, selection);
else{
hotpoint(selection->p[0]);
track(mover, 0, selection);
}
}
void translatecircle(Item *ip, Dpoint delta){
ip->p[0]=dadd(ip->p[0], delta);
}
void deletecircle(Item *ip){
}
void writecircle(Item *ip, int f){
fprint(f, "c %.3f %.3f %.3f\n", ip->p[0].x, ip->p[0].y, ip->r);
}
void activatecircle(Item *ip){
hotpoint(ip->p[0]);
}
int inboxcircle(Item *ip, Drectangle r){
Dpoint i[2];
return dptinrect(dadd(ip->p[0], Dpt(ip->r, 0.)), r)
|| segintercircle(r.min, Dpt(r.min.x, r.max.y), ip->p[0], ip->r, i)
|| segintercircle(r.min, Dpt(r.max.x, r.min.y), ip->p[0], ip->r, i)
|| segintercircle(r.max, Dpt(r.min.x, r.max.y), ip->p[0], ip->r, i)
|| segintercircle(r.max, Dpt(r.max.x, r.min.y), ip->p[0], ip->r, i);
}
Drectangle bboxcircle(Item *ip){
Drectangle r;
r.min=dsub(ip->p[0], Dpt(ip->r, ip->r));
r.max=dadd(ip->p[0], Dpt(ip->r, ip->r));
return r;
}
Dpoint nearvertcircle(Item *ip, Dpoint testp){
return ip->p[0];
}
Itemfns circlefns={
deletecircle,
writecircle,
activatecircle,
nearcircle,
drawcircle,
editcircle,
translatecircle,
inboxcircle,
bboxcircle,
nearvertcircle,
};
Item *addcircle(Item *head, Dpoint p0, Flt r){
return additem(head, CIRCLE, r, 0, 0, 0, &circlefns, 1, p0);
}
|