bool interLineSeg(const VEC3& A, const VEC3& AB, typename VEC3::DATA_TYPE AB2, const VEC3& P, const VEC3& Q, VEC3& inter) { #define EPSILON (1.0e-5) typedef typename VEC3::DATA_TYPE T ; T dist = Geom::distancePoint2TrianglePlane(AB-A,A,P,Q); // std::cout << "dist "<< dist << std::endl; if (dist>EPSILON) return false; VEC3 AP = P - A ; VEC3 PQ = Q - P ; T X = AB * PQ ; T beta = ( AB2 * (AP*PQ) - X * (AP*AB) ) / ( X*X - AB2 * PQ.norm2() ) ; // std::cout << "beta "<< beta << std::endl; if ((beta<0.0) || (beta>1.0)) return false; inter = beta*Q +(1.0-beta)*P; return true; #undef EPSILON }
Intersection intersectionLineTriangle(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter) { typedef typename VEC3::DATA_TYPE T ; VEC3 u = Tb - Ta ; VEC3 v = Tc - Ta ; VEC3 n = u ^ v ; VEC3 w0 = P - Ta ; T a = -(n * w0) ; T b = (n * Dir) ; #define PRECISION 1e-20 if(fabs(b) < PRECISION) //ray parallel to triangle return NO_INTERSECTION ; #undef PRECISION T r = a / b ; Inter = P + r * Dir ; // intersect point of ray and plane // is I inside T? T uu = u.norm2() ; T uv = u * v ; T vv = v.norm2() ; VEC3 w = Inter - Ta ; T wu = w * u ; T wv = w * v ; T D = (uv * uv) - (uu * vv) ; // get and test parametric coords T s = ((uv * wv) - (vv * wu)) / D ; if(s < T(0) || s > T(1)) return NO_INTERSECTION ; T t = ((uv * wu) - (uu * wv)) / D ; if(t < T(0) || (s + t) > T(1)) return NO_INTERSECTION ; if((s == T(0) || s == T(1))) if(t == T(0) || t == T(1)) return VERTEX_INTERSECTION ; else return EDGE_INTERSECTION ; else if(t == T(0) || t == T(1)) return EDGE_INTERSECTION ; return FACE_INTERSECTION ; }
bool intersectionSphereEdge(typename PFP::MAP& map, const typename PFP::VEC3& center, typename PFP::REAL radius, Edge e, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& position, typename PFP::REAL& alpha) { typedef typename PFP::VEC3 VEC3 ; typedef typename PFP::REAL REAL ; const VEC3& p1 = position[e.dart]; const VEC3& p2 = position[map.phi1(e.dart)]; if(Geom::isPointInSphere(p1, center, radius) && !Geom::isPointInSphere(p2, center, radius)) { VEC3 p = p1 - center; VEC3 qminusp = p2 - center - p; REAL s = p * qminusp; REAL n2 = qminusp.norm2(); alpha = (- s + sqrt(s*s + n2 * (radius*radius - p.norm2()))) / n2; return true ; } return false ; }
Intersection intersectionSegmentTriangle(const VEC3& PA, const VEC3& PB, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter) { typedef typename VEC3::DATA_TYPE T ; const T precision = 0.0001;//std::numeric_limits<T>::min(); VEC3 u = Tb - Ta ; VEC3 v = Tc - Ta ; VEC3 Dir = PB - PA ; VEC3 n = u ^ v ; VEC3 w0 = PA - Ta ; float a = -(n * w0) ; float b = (n * Dir) ; if(fabs(b) < precision) //ray parallel to triangle return NO_INTERSECTION ; //compute intersection T r = a / b ; if((r < -precision) || (r > (T(1) + precision))) return NO_INTERSECTION; Inter = PA + r * Dir; // intersect point of ray and plane // is I inside T? T uu = u.norm2() ; T uv = u * v ; T vv = v.norm2() ; VEC3 w = Inter - Ta ; T wu = w * u ; T wv = w * v ; T D = (uv * uv) - (uu * vv) ; // get and test parametric coords T s = ((uv * wv) - (vv * wu)) / D ; if(s <= precision) s = 0.0f; if(s < T(0) || s > T(1)) return NO_INTERSECTION ; T t = ((uv * wu) - (uu * wv)) / D ; if(t <= precision) t = 0.0f; if(t < T(0) || (s + t) > T(1)) return NO_INTERSECTION ; if((s == T(0) || s == T(1))) if(t == T(0) || t == T(1)) return VERTEX_INTERSECTION ; else return EDGE_INTERSECTION ; else if(t == T(0) || t == T(1)) return EDGE_INTERSECTION ; return FACE_INTERSECTION ; }