Point closest_pt_seg(Point a, Point b, Point p) { double along; if (lng2(b-a) < EPS) return a; along = dot(b-a,p-a)/lng2(b-a); if (along < 0) along = 0; if (along > 1) along = 1; return (b-a)*along + a; }
/* given two lines in 3D space, find distance of closest approach */ double line_line_dist(Point a, Point b, Point c, Point d) { Point perp = cross(b-a,d-c); if (lng2(perp) < EPS) /* parallel */ perp = cross(b-a,cross(b-a,c-a)); if (lng2(perp) < EPS) return 0; /* coincident */ return fabs(dot(a-c,perp))/lng(perp); }
int sphere_iline_isect(Point c, double r, Point a, Point b, Point *p, Point *q) { Point vec, mid = closest_pt_iline(a,b,c); if (lng2(c-mid) > r*r) return 0; vec = (a-b)*sqrt((r*r - lng2(c-mid))/lng2(a-b)); *p = mid + vec; *q = mid - vec; return 1; }
int bounce(Point ori, Point dir, Point a, Point b, Point *np, Point *ndir) { Point tmp; int res; res = intersect_iline(ori, ori+dir, a, b, &tmp); if (res == -1) return -1; if (res != 1 || dot(tmp-ori,dir) < 0 || fabs(lng(a-tmp) + lng(b-tmp) - lng(a-b)) > EPS) return 0; *np = tmp; if (lng2(a-tmp) < EPS || lng2(b-tmp) < EPS) return -2; *ndir = reflect(a,b,tmp+dir) - tmp; return 1; }
Point closest_pt_plane(Point a, Point b, Point c, Point p) { Point norm; norm = cross(b-a,c-a); assert(lng2(norm) > EPS); // collinearity return closest_pt_plane(norm,a,p); }
/* this is the same as line_line_dist, but it also returns the points of closest approach */ double closest_approach(Point a, Point b, Point c, Point d, Point *p, Point *q) { double s = dot(d-c,b-a), t = dot(a-c,d-c); double num, den, tmp; den = lng2(b-a)*lng2(d-c) - s*s; num = t*s - dot(a-c,b-a)*lng2(d-c); if (fabs(den) < EPS) { /* parallel */ *p = a; *q = (d-c)*t/lng2(d-c) + c; if (fabs(s) < EPS) *q = a; /* coincident */ } else { /* skew */ tmp = num/den; *p = a + (b-a)*tmp; *q = c + (d-c)*(t + s*tmp)/lng2(d-c); } return lng(*p-*q); }
Point to_plane(Point a, Point b, Point c, Point p) { Point norm, ydir, xdir, res; norm = cross(b-a,c-a); assert(lng2(norm) > EPS); // collinearity xdir = (b-a)/lng(b-a); // create orthonormal vectors ydir = cross(norm,xdir); ydir = ydir/lng(ydir); res.x = dot(p-a,xdir); res.y = dot(p-a,ydir); res.z = 0; return res; }
void main() { FCPartitionDesc dbl("dbl","dbl"); FCPartitionDesc lng("lng","lng"); FCPartitionDesc charp("charp","charp"); FCPartitionDesc date("date","date"); FCPartitionDesc dblx("dblx","dblx"); FCPartitionDesc lngx("lngx","lngx"); FCPartitionDesc charpx("charpx","charpx"); FCPartitionDesc datex("datex","datex"); PDFriend::MakeADouble(dbl); PDFriend::MakeACharPtr(charp); PDFriend::MakeALong(lng); PDFriend::MakeAColDate(date); // test copy constructor.. FCPartitionDesc dbl2(dbl); FCPartitionDesc lng2(lng); FCPartitionDesc charp2(charp); FCPartitionDesc date2(date); dblx = dbl; lngx = lng; charpx = charp; datex = date; cout << "dbl----" << endl << dbl ; cout << "lng----" << endl << lng ; cout << "charp--" << endl << charp ; cout << "date---" << endl << date << endl; cout << "dbl2----" << endl << dbl2 ; cout << "lng2----" << endl << lng2 ; cout << "charp2--" << endl << charp2 ; cout << "date2---" << endl << date2 << endl; cout << "dblx----" << endl << dblx ; cout << "lngx----" << endl << lngx ; cout << "charpx--" << endl << charpx ; cout << "date2x--" << endl << datex << endl; cout << dbl.GetDouble() << endl; cout << charp.GetCharPtr() << endl; cout << lng.GetLong() << endl; cout << date.GetColDate().nMonth << "/" << date.GetColDate().nDay << "/" << date.GetColDate().nYear << endl; }
/* Given a plane and a line ab, determine if the two intersect, and if so, find the single point of intersection */ int plane_iline_isect(Point norm, Point ori, Point a, Point b, Point *p) { double along, den = dot(norm,b-a); if (fabs(den) < EPS) { /* parallel */ if (lng2(cross(ori-a,b-a)) < EPS) return -1; /* coincident */ return 0; /* non-intersecting */ } along = dot(norm,ori-a)/den; /* if you want to intersect a plane with a finite segment, check that (along <= 1 && along => 0) */ *p = a + along*(b-a); return 1; }
Point closest_pt_iline(Point a, Point b, Point p) { double along = dot(b-a,p-a)/lng2(b-a); return (b-a)*along + a; }
/* is the point p on the infinite line ab? */ int on_iline(Point a, Point b, Point p) { return (lng2(p-closest_pt_iline(a,b,p)) < EPS); }
Point closest_pt_plane(Point norm, Point a, Point p) { Point res = cross(cross(norm,p-a),norm); if (lng2(res) < EPS) return a; return res*dot(res,p-a)/lng2(res); }