int intersec(const line& l1, const line& l2, point& res){ assert(!(l1.v == point())); assert(!(l2.v == point())); if (vp(l1.v,l2.v) == point()){ if (vp(l1.v, l1.p - l2.p) == point()) return 2; // same return 0; // parallel } point n = vp(l1.v,l2.v); point p = l2.p - l1.p; if (sgn(sp(n,p))) return 0; // skew ld t; if (sgn(n.x)) t = (p.y * l2.v.z - p.z * l2.v.y) / n.x; else if (sgn(n.y)) t = (p.z * l2.v.x - p.x * l2.v.z) / n.y; else if (sgn(n.z)) t = (p.x * l2.v.y - p.y * l2.v.x) / n.z; else assert(false); res = l1.p + l1.v * t; assert(l1.on(res)); assert(l2.on(res)); return 1; // intersects }
void closest(const line& l1,const line& l2, point& p1,point& p2){ if (vp(l1.v,l2.v) == point()){ p1 = l1.p; p2 = l2.p - l1.v * /*BOXNEXT*/ (sp(l1.v,l2.p - l1.p) / l1.v.dist2()); return; } point p = l2.p - l1.p; ld t1 = ( sp(l1.v,p) * l2.v.dist2() - sp(l1.v,l2.v) * sp(l2.v,p) ) / vp(l1.v,l2.v).dist2(); ld t2 = ( sp(l2.v,l1.v) * sp(l1.v,p) - sp(l2.v,p) * l1.v.dist2() ) / vp(l2.v,l1.v).dist2(); p1 = l1.p + l1.v * t1; p2 = l2.p + l2.v * t2; assert(l1.on(p1)); assert(l2.on(p2)); }
bool cross( line L ) { return on( intersect( L ) ) && L.on( intersect( L ) ); }