diff --git a/vcg/complex/intersection.h b/vcg/complex/intersection.h index c344684b..4c2ce3f0 100644 --- a/vcg/complex/intersection.h +++ b/vcg/complex/intersection.h @@ -99,7 +99,7 @@ bool Intersect( GridType & grid,Plane3 plane, std::vector - inline bool IntersectionSegmentPlane( const Plane3 & pl, const Segment3 & s, Point3 & p0){ + inline bool IntersectionPlaneSegment( const Plane3 & pl, const Segment3 & s, Point3 & p0){ T p1_proj = s.P1()*pl.Direction()-pl.Offset(); T p0_proj = s.P0()*pl.Direction()-pl.Offset(); if ( (p1_proj>0)-(p0_proj<0)) return false; @@ -358,13 +358,13 @@ namespace vcg { } /// intersection between segment and plane - template - inline bool Intersection( const Plane3 & pl, - const SEGMENTTYPE & sg, - Point3 & po){ - typedef typename SEGMENTTYPE::ScalarType T; - const T epsilon = T(1e-8); + template + inline bool IntersectionPlaneSegmentEpsilon(const Plane3 & pl, + const Segment3 & sg, + Point3 & po, + const ScalarType epsilon = ScalarType(1e-8)){ + typedef ScalarType T; T k = pl.Direction().dot((sg.P1()-sg.P0())); if( (k > -epsilon) && (k < epsilon)) return false; @@ -380,36 +380,38 @@ namespace vcg { template inline bool IntersectionPlaneTriangle( const Plane3 & pl, const TRIANGLETYPE & tr, - Segment3 & sg){ - typedef typename TRIANGLETYPE::ScalarType T; - if(Intersection(pl,Segment3(tr.P(0),tr.P(1)),sg.P0())){ - if(Intersection(pl,Segment3(tr.P(0),tr.P(2)),sg.P1())) - return true; - else - { - Intersection(pl,Segment3(tr.P(1),tr.P(2)),sg.P1()); - return true; - } - }else - { - if(Intersection(pl,Segment3(tr.P(1),tr.P(2)),sg.P0())) - { - Intersection(pl,Segment3(tr.P(0),tr.P(2)),sg.P1()); - return true; - } + Segment3 & sg) + { + typedef typename TRIANGLETYPE::ScalarType T; + if(IntersectionPlaneSegment(pl,Segment3(tr.P(0),tr.P(1)),sg.P0())){ + if(IntersectionPlaneSegment(pl,Segment3(tr.P(0),tr.P(2)),sg.P1())) + return true; + else + { + IntersectionPlaneSegment(pl,Segment3(tr.P(1),tr.P(2)),sg.P1()); + return true; + } } - return false; - } + else + { + if(IntersectionPlaneSegment(pl,Segment3(tr.P(1),tr.P(2)),sg.P0())) + { + IntersectionPlaneSegment(pl,Segment3(tr.P(0),tr.P(2)),sg.P1()); + return true; + } + } + return false; + } /// intersection between two triangles template - inline bool Intersection(const TRIANGLETYPE & t0,const TRIANGLETYPE & t1){ + inline bool IntersectionTriangleTriangle(const TRIANGLETYPE & t0,const TRIANGLETYPE & t1){ return NoDivTriTriIsect(t0.P0(0),t0.P0(1),t0.P0(2), t1.P0(0),t1.P0(1),t1.P0(2)); } template - inline bool Intersection(Point3 V0,Point3 V1,Point3 V2, + inline bool IntersectionTriangleTriangle(Point3 V0,Point3 V1,Point3 V2, Point3 U0,Point3 U1,Point3 U2){ return NoDivTriTriIsect(V0,V1,V2,U0,U1,U2); } @@ -525,7 +527,7 @@ bool IntersectionRayTriangle( const Ray3 & ray, const Point3 & vert0, // line-box template -bool Intersection_Line_Box( const Box3 & box, const Line3 & r, Point3 & coord ) +bool IntersectionLineBox( const Box3 & box, const Line3 & r, Point3 & coord ) { const int NUMDIM = 3; const int RIGHT = 0; @@ -599,17 +601,17 @@ bool Intersection_Line_Box( const Box3 & box, const Line3 & r, Point3 & // ray-box template -bool Intersection_Ray_Box( const Box3 & box, const Ray3 & r, Point3 & coord ) +bool IntersectionRayBox( const Box3 & box, const Ray3 & r, Point3 & coord ) { Line3 l; l.SetOrigin(r.Origin()); l.SetDirection(r.Direction()); - return(Intersection_Line_Box(box,l,coord)); + return(IntersectionLineBox(box,l,coord)); } // segment-box return fist intersection found from p0 to p1 template -bool Intersection_Segment_Box( const Box3 & box, +bool IntersectionSegmentBox( const Box3 & box, const Segment3 & s, Point3 & coord ) { @@ -626,7 +628,7 @@ bool Intersection_Segment_Box( const Box3 & box, dir.Normalize(); l.SetOrigin(s.P0()); l.SetDirection(dir); - if(Intersection_Line_Box(box,l,coord)) + if(IntersectionLineBox(box,l,coord)) return (test.IsIn(coord)); return false; } @@ -634,29 +636,37 @@ bool Intersection_Segment_Box( const Box3 & box, // segment-box intersection , return number of intersections and intersection points template -int Intersection_Segment_Box( const Box3 & box, +int IntersectionSegmentBox( const Box3 & box, const Segment3 & s, Point3 & coord0, Point3 & coord1 ) { int num=0; Segment3 test= s; - if (Intersection_Segment_Box(box,test,coord0 )) + if (IntersectionSegmentBox(box,test,coord0 )) { num++; Point3 swap=test.P0(); test.P0()=test.P1(); test.P1()=swap; - if (Intersection_Segment_Box(box,test,coord1 )) + if (IntersectionSegmentBox(box,test,coord1 )) num++; } return num; } - -// segment-triangle intersection +/** +* Compute the intersection between a segment and a triangle. +* It relies on the lineTriangle Intersection +* @param[in] segment +* @param[in] triangle vertices +* @param[out]=(t,u,v) the intersection point, meaningful only if the line of segment intersects the triangle +* t is the baricentric coord of the point on the segment +* (u,v) are the baricentric coords of the intersection point in the segment +* +*/ template -bool Intersection_Segment_Triangle( const vcg::Segment3 & seg, +bool IntersectionSegmentTriangle( const vcg::Segment3 & seg, const Point3 & vert0, const Point3 & vert1, const Point3 & vert2, @@ -672,29 +682,35 @@ bool Intersection_Segment_Triangle( const vcg::Segment3 & seg, Point3 inter; if (!bb0.Collide(bb1)) return false; - if (!vcg::Intersection_Segment_Box(bb1,seg,inter)) + if (!vcg::IntersectionSegmentBox(bb1,seg,inter)) return false; //first set both directions of ray - vcg::Ray3 ray; + vcg::Line3 line; vcg::Point3 dir; dir=(seg.P1()-seg.P0()); dir.Normalize(); - ray.Set(seg.P0(),dir); - - //then control for each direction the intersection with triangle - if ((IntersectionRayTriangle(ray,vert0,vert1,vert2,dist,a,b)) - ||(IntersectionRayTriangle(ray,vert1,vert0,vert2,dist,b,a))) - return (dist<(seg.P1()-seg.P0()).Norm()); - else - return(false); + line.Set(seg.P0(),dir); + if(IntersectionLineTriangle(line,vert0,vert1,vert2,dist,a,b)) + return (dist>=0 && dist<=1.0); + return false; +} +/** +* Compute the intersection between a segment and a triangle. +* Wrapper of the above function +*/ +template +bool IntersectionSegmentTriangle( const vcg::Segment3 & seg, + const TriangleType &t, + typename TriangleType::ScalarType & a ,typename TriangleType::ScalarType & b, typename TriangleType::ScalarType & dist) +{ + return IntersectionSegmentTriangle(seg,t.P(0),t.P(1),t.P(2),a,b,dist); } -template -bool Intersection_Plane_Box(const vcg::Plane3 &pl, +template +bool IntersectionPlaneBox(const vcg::Plane3 &pl, vcg::Box3 &bbox) { - typedef typename vcg::Segment3 SegmentType; typedef typename vcg::Point3 CoordType; SegmentType diag[4]; @@ -708,7 +724,7 @@ bool Intersection_Plane_Box(const vcg::Plane3 &pl, ScalarType a,b,dist; for (int i=0;i<3;i++) //call intersection of segment and plane - if (vcg::Intersection(pl,diag[i],intersection)) + if (vcg::IntersectionPlaneSegment(pl,diag[i],intersection)) return true; return false; } @@ -717,7 +733,7 @@ bool Intersection_Plane_Box(const vcg::Plane3 &pl, ///that is the intersectionk between the sphere and //the plane template -bool Intersection_Plane_Sphere(const Plane3 &pl, +bool IntersectionPlaneSphere(const Plane3 &pl, const Sphere3 &sphere, Point3 ¢er, ScalarType &radius) @@ -756,7 +772,7 @@ bool Intersection_Plane_Sphere(const Plane3 &pl, template -bool Intersection_Triangle_Box(const vcg::Box3 &bbox, +bool IntersectionTriangleBox(const vcg::Box3 &bbox, const vcg::Point3 &p0, const vcg::Point3 &p1, const vcg::Point3 &p2) @@ -779,13 +795,13 @@ bool Intersection_Triangle_Box(const vcg::Box3 &bbox, /////control plane of the triangle with bbox //vcg::Plane3 plTri=vcg::Plane3(); //plTri.Init(p0,p1,p2); - //if (!Intersection_Plane_Box(plTri,bbox)) + //if (!IntersectionPlaneBox(plTri,bbox)) // return false; ///then control intersection of segments with box - if (Intersection_Segment_Box(bbox,vcg::Segment3(p0,p1),intersection)|| - Intersection_Segment_Box(bbox,vcg::Segment3(p1,p2),intersection)|| - Intersection_Segment_Box(bbox,vcg::Segment3(p2,p0),intersection)) + if (IntersectionSegmentBox(bbox,vcg::Segment3(p0,p1),intersection)|| + IntersectionSegmentBox(bbox,vcg::Segment3(p1,p2),intersection)|| + IntersectionSegmentBox(bbox,vcg::Segment3(p2,p0),intersection)) return true; ///control intersection of diagonal of the cube with triangle @@ -797,14 +813,14 @@ bool Intersection_Triangle_Box(const vcg::Box3 &bbox, diag[3]=Segment3(bbox.P(3),bbox.P(4)); ScalarType a,b,dist; for (int i=0;i<3;i++) - if (Intersection_Segment_Triangle(diag[i],p0,p1,p2,a,b,dist)) + if (IntersectionSegmentTriangle(diag[i],p0,p1,p2,a,b,dist)) return true; return false; } template -bool Intersection_Sphere_Sphere( const SphereType & s0,const SphereType & s1){ +bool IntersectionSphereSphere( const SphereType & s0,const SphereType & s1){ return (s0.Center()-s1.Center()).SquaredNorm() < (s0.Radius()+s1.Radius())*(s0.Radius()+s1.Radius()); } diff --git a/vcg/space/triangle3.h b/vcg/space/triangle3.h index b0604bec..d8e14504 100644 --- a/vcg/space/triangle3.h +++ b/vcg/space/triangle3.h @@ -460,6 +460,15 @@ Point3 Circumcenter(const TriangleType &t) return c; } +/** + * @brief Computes the distance between a triangle and a point. + * + * @param t reference to the triangle + * @param q point location + * @param dist distance from p to t + * @param closest perpendicular projection of p onto t + */ + template void TrianglePointDistance(const TriangleType &t, const typename TriangleType::CoordType & q,