📄 fillet.c
字号:
/*Joining Two Lines with a Circular Arc FilletRobert D. Miller*/#include "math.h"#include "stdio.h"#include "stdlib.h"#define pi 3.14159265358974#define halfpi 1.5707963267949#define threepi2 4.71238898038469#define twopi 6.28318530717959#define degree 57.29577951308232088#define radian 0.01745329251994329577typedef struct point { float x; float y;} point;point gv1, gv2;float xx, yy, sa, sb, qx, qy, rx, ry;int x1, yy1, x2, y2;float arccos();float arcsin();float cross2();float dot2();void moveto(); /* External draw routine */void lineto(); /* External draw routine */void drawarc();float linetopoint();void pointperp();void fillet();float cross2(v1,v2) point v1, v2;{ return (v1.x*v2.y - v2.x*v1.y); }float dot2(v1,v2) /* Return angle subtended by two vectors. */ point v1, v2;{ float d, t; d= (float) sqrt(((v1.x*v1.x)+(v1.y*v1.y)) * ((v2.x*v2.x)+(v2.y*v2.y))); if (d != (float) 0.0) { t= (v1.x*v2.x+v1.y*v2.y)/d; return (arccos(t)); } else return ((float) 0.0);}/* Draw circular arc in one degree increments. Center is (xc,yc) with radius r, beginning at starting angle, startang through angle ang. If ang < 0 arc is draw clockwise. */void drawarc(xc, yc, r, startang, ang)float xc, yc, r, startang, ang;{#define sindt 0.017452406#define cosdt 0.999847695float a, x, y, sr;int k; a= (float) startang*radian; x= (float) r*cos(a); y= (float) r*sin(a); moveto(xc+x, yc+y, 3); if (ang >= (float) 0.0) sr= (float) sindt; else sr= (float) -sindt; for (k= 1; k <= (int) floor(fabs(ang)); k++) { x= x*cosdt-y*sr; y= x*sr+y*cosdt; lineto(xc+x,yc+y); }return;}/* Find a,b,c in Ax + By + C = 0 for line p1,p2. */void linecoef(a,b,c,p1,p2)float *a, *b, *c;point p1, p2;{ *c= (p2.x*p1.y)-(p1.x*p2.y); *a= p2.y-p1.y; *b= p1.x-p2.x;return;}/* Return signed distance from line Ax + By + C = 0 to point P. */float linetopoint(a,b,c,p)float a, b, c;point p;{float d, lp; d= sqrt((a*a)+(b*b)); if (d == 0.0) lp = 0.0; else lp= (a*p.x+b*p.y+c)/d;return ((float) lp);}/* Given line l = ax + by + c = 0 and point p, compute x,y so p(x,y) is perpendicular to l. */void pointperp(x, y, a, b, c, p)float *x, *y, a, b, c;point p;{float d, cp; *x= 0.0; *y= 0.0; d= a*a +b*b; cp= a*p.y-b*p.x; if (d != 0.0) { *x= (-a*c-b*cp)/d; *y= (a*cp-b*c)/d; }return;}/* Compute a circular arc fillet between lines L1 (p1 to p2) and L2 (p3 to p4) with radius R. The circle center is xc,yc. */void fillet(p1, p2, p3, p4, r, xc, yc, pa, aa)point *p1, *p2, *p3, *p4;float r, *xc, *yc, *pa, *aa;{float a1, b1, c1, a2, b2, c2, c1p, c2p, d1, d2, xa, xb, ya, yb, d, rr;point mp, pc; linecoef(&a1,&b1,&c1,*p1,*p2); linecoef(&a2,&b2,&c2,*p3,*p4); if ((a1*b2) == (a2*b1)) /* Parallel or coincident lines /* goto xit; mp.x= ((*p3).x + (*p4).x)/2.0; mp.y= ((*p3).y + (*p4).y)/2.0; d1= linetopoint(a1,b1,c1,mp); /* Find distance p1p2 to p3 */ if (d1 == 0.0) goto xit; mp.x= ((*p1).x + (*p2).x)/2.0; mp.y= ((*p1).y + (*p2).y)/2.0; d2= linetopoint(a2,b2,c2,mp); /* Find distance p3p4 to p2 */ if (d2 == 0.0) goto xit; rr= r; if (d1 <= 0.0) rr= -rr; c1p= c1-rr*sqrt((a1*a1)+(b1*b1)); /* Line parallel l1 at d */ rr= r; if (d2 <= 0.0) rr= -rr; c2p= c2-rr*sqrt((a2*a2)+(b2*b2)); /* Line parallel l2 at d */ d= a1*b2-a2*b1; *xc= (c2p*b1-c1p*b2)/d; /* Intersect constructed lines */ *yc= (c1p*a2-c2p*a1)/d; /* to find center of arc */ pc.x= *xc; pc.y= *yc; pointperp(&xa,&ya,a1,b1,c1,pc); /* Clip or extend lines as required */ pointperp(&xb,&yb,a2,b2,c2,pc); (*p2).x= xa; (*p2).y= ya; (*p3).x= xb; (*p3).y= yb; gv1.x= xa-*xc; gv1.y= ya-*yc; gv2.x= xb-*xc; gv2.y= yb-*yc; *pa= (float) atan2(gv1.y,gv1.x); /* Beginning angle for arc */ *aa= dot2(gv1,gv2); if (cross2(gv1,gv2) < 0.0) *aa= -*aa; /* Angle subtended by arc */xit:return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -