removing template arguments to swap, it hurts msvc

This commit is contained in:
T.Alderighi 2021-12-13 10:08:54 +01:00
parent fcc4a3bcb5
commit a85534cc46
1 changed files with 386 additions and 386 deletions

View File

@ -1,386 +1,386 @@
/**************************************************************************** /****************************************************************************
* VCGLib o o * * VCGLib o o *
* Visual and Computer Graphics Library o o * * Visual and Computer Graphics Library o o *
* _ O _ * * _ O _ *
* Copyright(C) 2004-2016 \/)\/ * * Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| * * Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | * * ISTI - Italian National Research Council | *
* \ * * \ *
* All rights reserved. * * All rights reserved. *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. * * for more details. *
* * * *
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.6 2007/05/08 12:11:58 pietroni Revision 1.6 2007/05/08 12:11:58 pietroni
added circle-line intersection added circle-line intersection
****************************************************************************/ ****************************************************************************/
#ifndef __VCGLIB_INTERSECTION_2 #ifndef __VCGLIB_INTERSECTION_2
#define __VCGLIB_INTERSECTION_2 #define __VCGLIB_INTERSECTION_2
#include <vcg/space/line2.h> #include <vcg/space/line2.h>
#include <vcg/space/ray2.h> #include <vcg/space/ray2.h>
#include <vcg/space/segment2.h> #include <vcg/space/segment2.h>
#include <vcg/space/point2.h> #include <vcg/space/point2.h>
#include <vcg/space/triangle2.h> #include <vcg/space/triangle2.h>
#include <vcg/space/box2.h> #include <vcg/space/box2.h>
#include <vector> #include <vector>
namespace vcg { namespace vcg {
/** \addtogroup space */ /** \addtogroup space */
/*@{*/ /*@{*/
/** /**
Function computing the intersection between couple of geometric primitives in Function computing the intersection between couple of geometric primitives in
2 dimension 2 dimension
*/ */
/// return true if the algle is convex (right rotation) /// return true if the algle is convex (right rotation)
template<class SCALAR_TYPE> template<class SCALAR_TYPE>
inline bool Convex(const Point2<SCALAR_TYPE> & p0,const Point2<SCALAR_TYPE> & p1,const Point2<SCALAR_TYPE> & p2) inline bool Convex(const Point2<SCALAR_TYPE> & p0,const Point2<SCALAR_TYPE> & p1,const Point2<SCALAR_TYPE> & p2)
{ {
const SCALAR_TYPE EPS= SCALAR_TYPE(1e-8); const SCALAR_TYPE EPS= SCALAR_TYPE(1e-8);
return (((p0-p1)^(p2-p1))<=EPS); return (((p0-p1)^(p2-p1))<=EPS);
} }
///return if exist the intersection point ///return if exist the intersection point
///between 2 lines in a 2d plane ///between 2 lines in a 2d plane
template<class SCALAR_TYPE> template<class SCALAR_TYPE>
inline bool LineLineIntersection(const vcg::Line2<SCALAR_TYPE> & l0, inline bool LineLineIntersection(const vcg::Line2<SCALAR_TYPE> & l0,
const vcg::Line2<SCALAR_TYPE> & l1, const vcg::Line2<SCALAR_TYPE> & l1,
Point2<SCALAR_TYPE> &p) Point2<SCALAR_TYPE> &p)
{ {
const SCALAR_TYPE Eps= SCALAR_TYPE(1e-8); const SCALAR_TYPE Eps= SCALAR_TYPE(1e-8);
///first line ///first line
SCALAR_TYPE x1=l0.Origin().X(); SCALAR_TYPE x1=l0.Origin().X();
SCALAR_TYPE y1=l0.Origin().Y(); SCALAR_TYPE y1=l0.Origin().Y();
SCALAR_TYPE x2=x1+l0.Direction().X(); SCALAR_TYPE x2=x1+l0.Direction().X();
SCALAR_TYPE y2=y1+l0.Direction().Y(); SCALAR_TYPE y2=y1+l0.Direction().Y();
///second line ///second line
SCALAR_TYPE x3=l1.Origin().X(); SCALAR_TYPE x3=l1.Origin().X();
SCALAR_TYPE y3=l1.Origin().Y(); SCALAR_TYPE y3=l1.Origin().Y();
SCALAR_TYPE x4=x3+l1.Direction().X(); SCALAR_TYPE x4=x3+l1.Direction().X();
SCALAR_TYPE y4=y3+l1.Direction().Y(); SCALAR_TYPE y4=y3+l1.Direction().Y();
///then find intersection ///then find intersection
///denominator ///denominator
SCALAR_TYPE den=((x1-x2)*(y3-y4))-((y1-y2)*(x3-x4)); SCALAR_TYPE den=((x1-x2)*(y3-y4))-((y1-y2)*(x3-x4));
if (fabs(den)<Eps) if (fabs(den)<Eps)
return false; return false;
SCALAR_TYPE d0=(x1*y2)-(y1*x2); SCALAR_TYPE d0=(x1*y2)-(y1*x2);
SCALAR_TYPE d1=(x3*y4)-(y3*x4); SCALAR_TYPE d1=(x3*y4)-(y3*x4);
SCALAR_TYPE numx=(d0*(x3-x4))-(d1*(x1-x2)); SCALAR_TYPE numx=(d0*(x3-x4))-(d1*(x1-x2));
SCALAR_TYPE numy=(d0*(y3-y4))-(d1*(y1-y2)); SCALAR_TYPE numy=(d0*(y3-y4))-(d1*(y1-y2));
p.X()=numx/den; p.X()=numx/den;
p.Y()=numy/den; p.Y()=numy/den;
return true; return true;
} }
///return if exist the intersection point ///return if exist the intersection point
///between 2 lines in a 2d plane ///between 2 lines in a 2d plane
template<class SCALAR_TYPE> template<class SCALAR_TYPE>
inline bool RayLineIntersection(const vcg::Line2<SCALAR_TYPE> & l, inline bool RayLineIntersection(const vcg::Line2<SCALAR_TYPE> & l,
const vcg::Ray2<SCALAR_TYPE> & r, const vcg::Ray2<SCALAR_TYPE> & r,
Point2<SCALAR_TYPE> &p) Point2<SCALAR_TYPE> &p)
{ {
///construct line from ray ///construct line from ray
vcg::Line2<SCALAR_TYPE> l_test; vcg::Line2<SCALAR_TYPE> l_test;
l_test.Set(r.Origin(),r.Direction()); l_test.Set(r.Origin(),r.Direction());
if (!LineLineIntersection(l,l_test,p)) if (!LineLineIntersection(l,l_test,p))
return false; return false;
Point2<SCALAR_TYPE> dir=p-r.Origin(); Point2<SCALAR_TYPE> dir=p-r.Origin();
dir.Normalize(); dir.Normalize();
return (dir*r.Direction()>0); return (dir*r.Direction()>0);
} }
/// interseciton between point and triangle /// interseciton between point and triangle
template<class SCALAR_TYPE> template<class SCALAR_TYPE>
inline bool RaySegmentIntersection(const vcg::Ray2<SCALAR_TYPE> & r, inline bool RaySegmentIntersection(const vcg::Ray2<SCALAR_TYPE> & r,
const vcg::Segment2<SCALAR_TYPE> &seg, const vcg::Segment2<SCALAR_TYPE> &seg,
Point2<SCALAR_TYPE> &p_inters) Point2<SCALAR_TYPE> &p_inters)
{ {
///first compute intersection between lines ///first compute intersection between lines
vcg::Line2<SCALAR_TYPE> line2; vcg::Line2<SCALAR_TYPE> line2;
line2.SetOrigin(seg.P0()); line2.SetOrigin(seg.P0());
vcg::Point2<SCALAR_TYPE> dir=seg.P1()-seg.P0(); vcg::Point2<SCALAR_TYPE> dir=seg.P1()-seg.P0();
dir.Normalize(); dir.Normalize();
line2.SetDirection(dir); line2.SetDirection(dir);
if(!RayLineIntersection<SCALAR_TYPE>(line2,r,p_inters)) if(!RayLineIntersection<SCALAR_TYPE>(line2,r,p_inters))
return false; return false;
///then test if intersection point is nearest ///then test if intersection point is nearest
///to both extremes then length of the segment ///to both extremes then length of the segment
SCALAR_TYPE d0=(seg.P1()-p_inters).Norm(); SCALAR_TYPE d0=(seg.P1()-p_inters).Norm();
SCALAR_TYPE d1=(seg.P0()-p_inters).Norm(); SCALAR_TYPE d1=(seg.P0()-p_inters).Norm();
SCALAR_TYPE length=(seg.P0()-seg.P1()).Norm(); SCALAR_TYPE length=(seg.P0()-seg.P1()).Norm();
return ((d0<length)&&(d1<length)); return ((d0<length)&&(d1<length));
} }
/// interseciton between point and triangle /// interseciton between point and triangle
template<class SCALAR_TYPE> template<class SCALAR_TYPE>
inline bool RayBoxIntersection(const vcg::Ray2<SCALAR_TYPE> & r, inline bool RayBoxIntersection(const vcg::Ray2<SCALAR_TYPE> & r,
const vcg::Box2<SCALAR_TYPE> &bbox, const vcg::Box2<SCALAR_TYPE> &bbox,
Point2<SCALAR_TYPE> &p_inters) Point2<SCALAR_TYPE> &p_inters)
{ {
///first create the 4 segments ///first create the 4 segments
vcg::Segment2<SCALAR_TYPE> S[4]; vcg::Segment2<SCALAR_TYPE> S[4];
for (int i=0;i<4;i++) for (int i=0;i<4;i++)
S[i]=vcg::Segment2<SCALAR_TYPE>(bbox.P(i),bbox.P((i+1)%4)); S[i]=vcg::Segment2<SCALAR_TYPE>(bbox.P(i),bbox.P((i+1)%4));
SCALAR_TYPE mind=std::numeric_limits<SCALAR_TYPE>::max(); SCALAR_TYPE mind=std::numeric_limits<SCALAR_TYPE>::max();
bool found=false; bool found=false;
for (int i=0;i<4;i++) for (int i=0;i<4;i++)
{ {
Point2<SCALAR_TYPE> p_inters_test; Point2<SCALAR_TYPE> p_inters_test;
if (!RaySegmentIntersection(r,S[i],p_inters_test))continue; if (!RaySegmentIntersection(r,S[i],p_inters_test))continue;
SCALAR_TYPE Norm=(p_inters_test-r.Origin()).Norm(); SCALAR_TYPE Norm=(p_inters_test-r.Origin()).Norm();
if (Norm<mind) if (Norm<mind)
{ {
mind=Norm; mind=Norm;
p_inters=p_inters_test; p_inters=p_inters_test;
found=true; found=true;
} }
} }
return found; return found;
} }
/// interseciton between point and triangle /// interseciton between point and triangle
template<class SCALAR_TYPE> template<class SCALAR_TYPE>
inline bool LineSegmentIntersection(const vcg::Line2<SCALAR_TYPE> & line, inline bool LineSegmentIntersection(const vcg::Line2<SCALAR_TYPE> & line,
const vcg::Segment2<SCALAR_TYPE> &seg, const vcg::Segment2<SCALAR_TYPE> &seg,
Point2<SCALAR_TYPE> &p_inters) Point2<SCALAR_TYPE> &p_inters)
{ {
///first compute intersection between lines ///first compute intersection between lines
vcg::Line2<SCALAR_TYPE> line2; vcg::Line2<SCALAR_TYPE> line2;
line2.SetOrigin(seg.P0()); line2.SetOrigin(seg.P0());
vcg::Point2<SCALAR_TYPE> dir=seg.P1()-seg.P0(); vcg::Point2<SCALAR_TYPE> dir=seg.P1()-seg.P0();
dir.Normalize(); dir.Normalize();
line2.SetDirection(dir); line2.SetDirection(dir);
if(!LineLineIntersection(line,line2,p_inters)) if(!LineLineIntersection(line,line2,p_inters))
return false; return false;
///then test if intersection point is nearest ///then test if intersection point is nearest
///to both extremes then length of the segment ///to both extremes then length of the segment
SCALAR_TYPE d0=(seg.P1()-p_inters).Norm(); SCALAR_TYPE d0=(seg.P1()-p_inters).Norm();
SCALAR_TYPE d1=(seg.P0()-p_inters).Norm(); SCALAR_TYPE d1=(seg.P0()-p_inters).Norm();
SCALAR_TYPE length=(seg.P0()-seg.P1()).Norm(); SCALAR_TYPE length=(seg.P0()-seg.P1()).Norm();
return ((d0<length)&&(d1<length)); return ((d0<length)&&(d1<length));
} }
/// interseciton between two segments /// interseciton between two segments
template<class SCALAR_TYPE> template<class SCALAR_TYPE>
inline bool SegmentSegmentIntersection(const vcg::Segment2<SCALAR_TYPE> &seg0, inline bool SegmentSegmentIntersection(const vcg::Segment2<SCALAR_TYPE> &seg0,
const vcg::Segment2<SCALAR_TYPE> &seg1, const vcg::Segment2<SCALAR_TYPE> &seg1,
Point2<SCALAR_TYPE> &p_inters) Point2<SCALAR_TYPE> &p_inters)
{ {
const SCALAR_TYPE Eps= SCALAR_TYPE(1e-8); const SCALAR_TYPE Eps= SCALAR_TYPE(1e-8);
SCALAR_TYPE lambda0,lambda1; SCALAR_TYPE lambda0,lambda1;
const Point2<SCALAR_TYPE> & p0 = seg0.P0(); const Point2<SCALAR_TYPE> & p0 = seg0.P0();
const Point2<SCALAR_TYPE> & p1 = seg0.P1(); const Point2<SCALAR_TYPE> & p1 = seg0.P1();
const Point2<SCALAR_TYPE> & p2 = seg1.P0(); const Point2<SCALAR_TYPE> & p2 = seg1.P0();
const Point2<SCALAR_TYPE> & p3 = seg1.P1(); const Point2<SCALAR_TYPE> & p3 = seg1.P1();
SCALAR_TYPE a = (p1-p0)[0]; SCALAR_TYPE a = (p1-p0)[0];
SCALAR_TYPE b = (p2-p3)[0]; SCALAR_TYPE b = (p2-p3)[0];
SCALAR_TYPE c = (p1-p0)[1]; SCALAR_TYPE c = (p1-p0)[1];
SCALAR_TYPE d = (p2-p3)[1]; SCALAR_TYPE d = (p2-p3)[1];
SCALAR_TYPE e = (p2-p0)[0]; SCALAR_TYPE e = (p2-p0)[0];
SCALAR_TYPE f = (p2-p0)[1]; SCALAR_TYPE f = (p2-p0)[1];
SCALAR_TYPE det = a*d-b*c; SCALAR_TYPE det = a*d-b*c;
lambda0 = (d*e-b*f)/det; lambda0 = (d*e-b*f)/det;
lambda1 = (-c*e+a*f)/det; lambda1 = (-c*e+a*f)/det;
if (fabs(det)<Eps) if (fabs(det)<Eps)
return false;// they are parallell return false;// they are parallell
if (!(lambda0 >= 0.0 && lambda0 <= 1.0 && lambda1 >= 0.0 && lambda1 <= 1.0)) if (!(lambda0 >= 0.0 && lambda0 <= 1.0 && lambda1 >= 0.0 && lambda1 <= 1.0))
return false; return false;
p_inters = p0*(1-lambda0)+p1*lambda0; p_inters = p0*(1-lambda0)+p1*lambda0;
return true; return true;
} }
/// interseciton between point and triangle /// interseciton between point and triangle
template<class SCALAR_TYPE> template<class SCALAR_TYPE>
inline bool IsInsideTrianglePoint( const Triangle2<SCALAR_TYPE> & t,const Point2<SCALAR_TYPE> & p) inline bool IsInsideTrianglePoint( const Triangle2<SCALAR_TYPE> & t,const Point2<SCALAR_TYPE> & p)
{ {
Point2<SCALAR_TYPE> p0=t.P0(0); Point2<SCALAR_TYPE> p0=t.P0(0);
Point2<SCALAR_TYPE> p1=t.P0(1); Point2<SCALAR_TYPE> p1=t.P0(1);
Point2<SCALAR_TYPE> p2=t.P0(2); Point2<SCALAR_TYPE> p2=t.P0(2);
///first test with bounding box ///first test with bounding box
vcg::Box2<SCALAR_TYPE> b2d; vcg::Box2<SCALAR_TYPE> b2d;
b2d.Add(p0); b2d.Add(p0);
b2d.Add(p1); b2d.Add(p1);
b2d.Add(p2); b2d.Add(p2);
if (!b2d.IsIn(p)) if (!b2d.IsIn(p))
return false; return false;
///then text convex ///then text convex
if (!Convex(p0,p1,p2)) if (!Convex(p0,p1,p2))
std::swap<Point2<SCALAR_TYPE> >(p1,p2); std::swap(p1,p2);
return((Convex(p,p0,p1))&&(Convex(p,p1,p2))&&(Convex(p,p2,p0))); return((Convex(p,p0,p1))&&(Convex(p,p1,p2))&&(Convex(p,p2,p0)));
//return((Convex(p,p0,p1))&&(Convex(p,p1,p2))&&(Convex(p,p2,p0))); //return((Convex(p,p0,p1))&&(Convex(p,p1,p2))&&(Convex(p,p2,p0)));
} }
template<class ScalarType> template<class ScalarType>
bool TriangleTriangleIntersect2D(const vcg::Triangle2<ScalarType> &tr0, bool TriangleTriangleIntersect2D(const vcg::Triangle2<ScalarType> &tr0,
const vcg::Triangle2<ScalarType> &tr1) const vcg::Triangle2<ScalarType> &tr1)
{ {
///test BBox Intersection ///test BBox Intersection
vcg::Box2<ScalarType> bbtr0; vcg::Box2<ScalarType> bbtr0;
bbtr0.Add(tr0.P(0)); bbtr0.Add(tr0.P(0));
bbtr0.Add(tr0.P(1)); bbtr0.Add(tr0.P(1));
bbtr0.Add(tr0.P(2)); bbtr0.Add(tr0.P(2));
vcg::Box2<ScalarType> bbtr1; vcg::Box2<ScalarType> bbtr1;
bbtr1.Add(tr1.P(0)); bbtr1.Add(tr1.P(0));
bbtr1.Add(tr1.P(1)); bbtr1.Add(tr1.P(1));
bbtr1.Add(tr1.P(2)); bbtr1.Add(tr1.P(2));
if (!bbtr0.Collide(bbtr1)) return false; if (!bbtr0.Collide(bbtr1)) return false;
///test vertex in face ///test vertex in face
for (int i=0;i<3;i++) for (int i=0;i<3;i++)
{ {
bool inside0=vcg::IsInsideTrianglePoint(tr0,tr1.P(i)); bool inside0=vcg::IsInsideTrianglePoint(tr0,tr1.P(i));
bool inside1=vcg::IsInsideTrianglePoint(tr1,tr0.P(i)); bool inside1=vcg::IsInsideTrianglePoint(tr1,tr0.P(i));
if (inside0 || inside1) return true; if (inside0 || inside1) return true;
} }
///test segment ///test segment
///to segment intersection ///to segment intersection
for (int i=0;i<3;i++) for (int i=0;i<3;i++)
{ {
for (int j=0;j<3;j++) for (int j=0;j<3;j++)
{ {
if (i>j) continue; if (i>j) continue;
vcg::Segment2<ScalarType> seg0=vcg::Segment2<ScalarType>(tr0.P(i),tr0.P((i+1)%3)); vcg::Segment2<ScalarType> seg0=vcg::Segment2<ScalarType>(tr0.P(i),tr0.P((i+1)%3));
vcg::Segment2<ScalarType> seg1=vcg::Segment2<ScalarType>(tr1.P(j),tr1.P((j+1)%3)); vcg::Segment2<ScalarType> seg1=vcg::Segment2<ScalarType>(tr1.P(j),tr1.P((j+1)%3));
vcg::Point2<ScalarType> p_inters; vcg::Point2<ScalarType> p_inters;
bool intersect=SegmentSegmentIntersection(seg0,seg1,p_inters); bool intersect=SegmentSegmentIntersection(seg0,seg1,p_inters);
if (intersect) return true; if (intersect) return true;
} }
} }
return false; return false;
} }
template <class ScalarType> template <class ScalarType>
bool PointInsidePolygon(vcg::Point2<ScalarType> p, bool PointInsidePolygon(vcg::Point2<ScalarType> p,
const std::vector<vcg::Segment2<ScalarType> > &polygon) const std::vector<vcg::Segment2<ScalarType> > &polygon)
{ {
int n=polygon.size(); int n=polygon.size();
vcg::Box2<ScalarType> BB; vcg::Box2<ScalarType> BB;
for (int i=0;i<n;i++) for (int i=0;i<n;i++)
{ {
BB.Add(polygon[i].P0()); BB.Add(polygon[i].P0());
BB.Add(polygon[i].P1()); BB.Add(polygon[i].P1());
} }
if (!BB.IsIn(p))return false; if (!BB.IsIn(p))return false;
//take 4 directions //take 4 directions
int inside_test=0; int inside_test=0;
for (int dir=0;dir<4;dir++) for (int dir=0;dir<4;dir++)
{ {
int intersection=0; int intersection=0;
vcg::Ray2<ScalarType> r; vcg::Ray2<ScalarType> r;
vcg::Point2<ScalarType> direct=vcg::Point2<ScalarType>(0,0); vcg::Point2<ScalarType> direct=vcg::Point2<ScalarType>(0,0);
switch (dir) switch (dir)
{ {
case 0 : direct.X()=1;break; case 0 : direct.X()=1;break;
case 1 : direct.Y()=1;break; case 1 : direct.Y()=1;break;
case 2 : direct.X()=-1; break; case 2 : direct.X()=-1; break;
default :direct.Y()=-1; default :direct.Y()=-1;
} }
r.SetOrigin(p); r.SetOrigin(p);
r.SetDirection(direct); r.SetDirection(direct);
for (int i=0;i<n;i++) for (int i=0;i<n;i++)
{ {
Point2<ScalarType> p_inters; Point2<ScalarType> p_inters;
if (vcg::RaySegmentIntersection(r,polygon[i],p_inters))intersection++; if (vcg::RaySegmentIntersection(r,polygon[i],p_inters))intersection++;
} }
if ((intersection%2)==1) if ((intersection%2)==1)
inside_test++; inside_test++;
} }
return(inside_test>2); return(inside_test>2);
} }
//intersection between a circle and a line //intersection between a circle and a line
template<class ScalarType> template<class ScalarType>
inline bool CircleLineIntersection(const vcg::Line2<ScalarType> & line, inline bool CircleLineIntersection(const vcg::Line2<ScalarType> & line,
const vcg::Point2<ScalarType> &center, const vcg::Point2<ScalarType> &center,
const ScalarType &radius, const ScalarType &radius,
vcg::Point2<ScalarType> &p0, vcg::Point2<ScalarType> &p0,
vcg::Point2<ScalarType> &p1) vcg::Point2<ScalarType> &p1)
{ {
///translate with origin on the center ///translate with origin on the center
ScalarType x1,x2,y1,y2; ScalarType x1,x2,y1,y2;
x1=line.Origin().X()-center.X(); x1=line.Origin().X()-center.X();
y1=line.Origin().Y()-center.Y(); y1=line.Origin().Y()-center.Y();
x2=x1+line.Direction().X(); x2=x1+line.Direction().X();
y2=y1+line.Direction().Y(); y2=y1+line.Direction().Y();
ScalarType dx,dy,dr,D,delta,sign; ScalarType dx,dy,dr,D,delta,sign;
dx=x2-x1; dx=x2-x1;
dy=y2-y1; dy=y2-y1;
dr=sqrt(dx*dx+dy*dy); dr=sqrt(dx*dx+dy*dy);
D=x1*y2-x2*y1; D=x1*y2-x2*y1;
delta=radius*radius*dr*dr-D*D; delta=radius*radius*dr*dr-D*D;
if (dy>=0) if (dy>=0)
sign=1; sign=1;
else else
sign=-1; sign=-1;
if (delta<0.000001) if (delta<0.000001)
return false;///no intersection return false;///no intersection
else else
{ {
p0.X()=(D*dy+sign*dx*sqrt(delta))/dr*dr; p0.X()=(D*dy+sign*dx*sqrt(delta))/dr*dr;
p0.Y()=(-D*dx+fabs(dy)*sqrt(delta))/dr*dr; p0.Y()=(-D*dx+fabs(dy)*sqrt(delta))/dr*dr;
p1.X()=(D*dy-sign*dx*sqrt(delta))/dr*dr; p1.X()=(D*dy-sign*dx*sqrt(delta))/dr*dr;
p1.Y()=(-D*dx-fabs(dy)*sqrt(delta))/dr*dr; p1.Y()=(-D*dx-fabs(dy)*sqrt(delta))/dr*dr;
p0+=center; p0+=center;
p1+=center; p1+=center;
return true; return true;
} }
} }
// Ray-Segment Functor // Ray-Segment Functor
class RaySegmentIntersectionFunctor { class RaySegmentIntersectionFunctor {
public: public:
template <class SEGMENTTYPE, class SCALARTYPE> template <class SEGMENTTYPE, class SCALARTYPE>
inline bool operator () (const SEGMENTTYPE & S, inline bool operator () (const SEGMENTTYPE & S,
const Ray2<SCALARTYPE> & ray, const Ray2<SCALARTYPE> & ray,
SCALARTYPE & t) SCALARTYPE & t)
{ {
typedef SCALARTYPE ScalarType; typedef SCALARTYPE ScalarType;
typedef vcg::Point2<ScalarType> CoordType; typedef vcg::Point2<ScalarType> CoordType;
CoordType inters_test; CoordType inters_test;
bool bret = RaySegmentIntersection(ray,S, inters_test); bool bret = RaySegmentIntersection(ray,S, inters_test);
if (bret) if (bret)
t=(inters_test-ray.Origin()).Norm(); t=(inters_test-ray.Origin()).Norm();
return (bret); return (bret);
} }
}; };
/*@}*/ /*@}*/
} // end namespace } // end namespace
#endif #endif