6 * Routines whose names end in 3 work on points in Affine 3-space.
7 * They ignore w in all arguments and produce w=1 in all results.
8 * Routines whose names end in 4 work on points in Projective 3-space.
10 Point3 add3(Point3 a, Point3 b){
17 Point3 sub3(Point3 a, Point3 b){
24 Point3 neg3(Point3 a){
31 Point3 div3(Point3 a, double b){
38 Point3 mul3(Point3 a, double b){
45 int eqpt3(Point3 p, Point3 q){
46 return p.x==q.x && p.y==q.y && p.z==q.z;
49 * Are these points closer than eps, in a relative sense
51 int closept3(Point3 p, Point3 q, double eps){
52 return 2.*dist3(p, q)<eps*(len3(p)+len3(q));
54 double dot3(Point3 p, Point3 q){
55 return p.x*q.x+p.y*q.y+p.z*q.z;
57 Point3 cross3(Point3 p, Point3 q){
65 double len3(Point3 p){
66 return sqrt(p.x*p.x+p.y*p.y+p.z*p.z);
68 double dist3(Point3 p, Point3 q){
72 return sqrt(p.x*p.x+p.y*p.y+p.z*p.z);
74 Point3 unit3(Point3 p){
75 double len=sqrt(p.x*p.x+p.y*p.y+p.z*p.z);
82 Point3 midpt3(Point3 p, Point3 q){
89 Point3 lerp3(Point3 p, Point3 q, double alpha){
97 * Reflect point p in the line joining p0 and p1
99 Point3 reflect3(Point3 p, Point3 p0, Point3 p1){
103 return add3(a, mul3(b, 2*dot3(a, b)/dot3(b, b)));
106 * Return the nearest point on segment [p0,p1] to point testp
108 Point3 nearseg3(Point3 p0, Point3 p1, Point3 testp){
114 if(num<=0) return p0;
116 if(num>=den) return p1;
117 return add3(p0, mul3(q, num/den));
120 * distance from point p to segment [p0,p1]
122 #define SMALL 1e-8 /* what should this value be? */
123 double pldist3(Point3 p, Point3 p0, Point3 p1){
130 if(dd<SMALL*SMALL) return len3(e);
131 dsq=dot3(e, e)-de*de/dd;
132 if(dsq<SMALL*SMALL) return 0;
136 * vdiv3(a, b) is the magnitude of the projection of a onto b
137 * measured in units of the length of b.
138 * vrem3(a, b) is the component of a perpendicular to b.
140 double vdiv3(Point3 a, Point3 b){
141 return (a.x*b.x+a.y*b.y+a.z*b.z)/(b.x*b.x+b.y*b.y+b.z*b.z);
143 Point3 vrem3(Point3 a, Point3 b){
144 double quo=(a.x*b.x+a.y*b.y+a.z*b.z)/(b.x*b.x+b.y*b.y+b.z*b.z);
152 * Compute face (plane) with given normal, containing a given point
154 Point3 pn2f3(Point3 p, Point3 n){
159 * Compute face containing three points
161 Point3 ppp2f3(Point3 p0, Point3 p1, Point3 p2){
165 return pn2f3(p0, cross3(p01, p02));
168 * Compute point common to three faces.
169 * Cramer's rule, yuk.
171 Point3 fff2p3(Point3 f0, Point3 f1, Point3 f2){
174 det=dot3(f0, cross3(f1, f2));
175 if(fabs(det)<SMALL){ /* parallel planes, bogus answer */
182 p.x=(f0.w*(f2.y*f1.z-f1.y*f2.z)
183 +f1.w*(f0.y*f2.z-f2.y*f0.z)+f2.w*(f1.y*f0.z-f0.y*f1.z))/det;
184 p.y=(f0.w*(f2.z*f1.x-f1.z*f2.x)
185 +f1.w*(f0.z*f2.x-f2.z*f0.x)+f2.w*(f1.z*f0.x-f0.z*f1.x))/det;
186 p.z=(f0.w*(f2.x*f1.y-f1.x*f2.y)
187 +f1.w*(f0.x*f2.y-f2.x*f0.y)+f2.w*(f1.x*f0.y-f0.x*f1.y))/det;
192 * pdiv4 does perspective division to convert a projective point to affine coordinates.
194 Point3 pdiv4(Point3 a){
202 Point3 add4(Point3 a, Point3 b){
209 Point3 sub4(Point3 a, Point3 b){