Added IntersectionSphereTriangle
This commit is contained in:
parent
6f6da43f69
commit
9105a551cd
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.32 2007/05/29 14:33:29 fiorin
|
||||||
|
Added IntersectionSegmentSphere
|
||||||
|
|
||||||
Revision 1.31 2007/04/16 09:08:15 cignoni
|
Revision 1.31 2007/04/16 09:08:15 cignoni
|
||||||
commented out non compiling intersectionSpherePlane
|
commented out non compiling intersectionSpherePlane
|
||||||
|
|
||||||
|
|
@ -134,6 +137,7 @@ Initial Commit
|
||||||
#ifndef __VCGLIB_INTERSECTION_3
|
#ifndef __VCGLIB_INTERSECTION_3
|
||||||
#define __VCGLIB_INTERSECTION_3
|
#define __VCGLIB_INTERSECTION_3
|
||||||
|
|
||||||
|
#include <vcg/math/base.h>
|
||||||
#include <vcg/space/point3.h>
|
#include <vcg/space/point3.h>
|
||||||
#include <vcg/space/line3.h>
|
#include <vcg/space/line3.h>
|
||||||
#include <vcg/space/ray3.h>
|
#include <vcg/space/ray3.h>
|
||||||
|
|
@ -230,7 +234,102 @@ namespace vcg {
|
||||||
solution_count++;
|
solution_count++;
|
||||||
}
|
}
|
||||||
return solution_count;
|
return solution_count;
|
||||||
|
}; // end of IntersectionSegmentSphere
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Compute the intersection between a sphere and a triangle.
|
||||||
|
* \param[in] sphere the input sphere
|
||||||
|
* \param[in] triangle the input triangle
|
||||||
|
* \param[out] witness if intersection is detected, it is the point on the triangle nearest to the center of the sphere
|
||||||
|
* \param[out] res if not null, in the first item is stored the minimum distance between the triangle and the sphere,
|
||||||
|
* while in the second item is stored the penetration depth
|
||||||
|
* \return true iff there is an intersection between the sphere and the triangle
|
||||||
|
*/
|
||||||
|
template < class SCALAR_TYPE >
|
||||||
|
bool IntersectionSphereTriangle(const vcg::Sphere3 < SCALAR_TYPE > & sphere ,
|
||||||
|
const vcg::Triangle3< SCALAR_TYPE > & triangle,
|
||||||
|
vcg::Point3 < SCALAR_TYPE > & witness ,
|
||||||
|
std::pair< SCALAR_TYPE, SCALAR_TYPE > * res=NULL)
|
||||||
|
{
|
||||||
|
typedef SCALAR_TYPE ScalarType;
|
||||||
|
typedef typename vcg::Point3< ScalarType > Point3t;
|
||||||
|
typedef typename vcg::Triangle3< ScalarType > Triangle3t;
|
||||||
|
|
||||||
|
bool penetration_detected = false;
|
||||||
|
|
||||||
|
ScalarType radius = sphere.Radius();
|
||||||
|
Point3t center = sphere.Center();
|
||||||
|
Point3t p0 = triangle.P(0)-center;
|
||||||
|
Point3t p1 = triangle.P(1)-center;
|
||||||
|
Point3t p2 = triangle.P(2)-center;
|
||||||
|
|
||||||
|
Point3t p10 = p1-p0;
|
||||||
|
Point3t p21 = p2-p1;
|
||||||
|
Point3t p20 = p2-p0;
|
||||||
|
|
||||||
|
ScalarType delta0_p01 = p10*p1;
|
||||||
|
ScalarType delta1_p01 = -p10*p0;
|
||||||
|
ScalarType delta0_p02 = p20*p2;
|
||||||
|
ScalarType delta2_p02 = -p20*p0;
|
||||||
|
ScalarType delta1_p12 = p21*p2;
|
||||||
|
ScalarType delta2_p12 = -p21*p1;
|
||||||
|
|
||||||
|
// the closest point can be one of the vertices of the triangle
|
||||||
|
if (delta1_p01<=ScalarType(0.0) && delta2_p02<=ScalarType(0.0)) { witness = p0; }
|
||||||
|
else if (delta0_p01<=ScalarType(0.0) && delta2_p12<=ScalarType(0.0)) { witness = p1; }
|
||||||
|
else if (delta0_p02<=ScalarType(0.0) && delta1_p12<=ScalarType(0.0)) { witness = p2; }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScalarType temp = p10*p2;
|
||||||
|
ScalarType delta0_p012 = delta0_p01*delta1_p12 + delta2_p12*temp;
|
||||||
|
ScalarType delta1_p012 = delta1_p01*delta0_p02 - delta2_p02*temp;
|
||||||
|
ScalarType delta2_p012 = delta2_p02*delta0_p01 - delta1_p01*(p20*p1);
|
||||||
|
|
||||||
|
// otherwise, can be a point lying on same edge of the triangle
|
||||||
|
if (delta0_p012<=ScalarType(0.0))
|
||||||
|
{
|
||||||
|
ScalarType denominator = delta1_p12+delta2_p12;
|
||||||
|
ScalarType mu1 = delta1_p12/denominator;
|
||||||
|
ScalarType mu2 = delta2_p12/denominator;
|
||||||
|
witness = (p1*mu1 + p2*mu2);
|
||||||
}
|
}
|
||||||
|
else if (delta1_p012<=ScalarType(0.0))
|
||||||
|
{
|
||||||
|
ScalarType denominator = delta0_p02+delta2_p02;
|
||||||
|
ScalarType mu0 = delta0_p02/denominator;
|
||||||
|
ScalarType mu2 = delta2_p02/denominator;
|
||||||
|
witness = (p0*mu0 + p2*mu2);
|
||||||
|
}
|
||||||
|
else if (delta2_p012<=ScalarType(0.0))
|
||||||
|
{
|
||||||
|
ScalarType denominator = delta0_p01+delta1_p01;
|
||||||
|
ScalarType mu0 = delta0_p01/denominator;
|
||||||
|
ScalarType mu1 = delta1_p01/denominator;
|
||||||
|
witness = (p0*mu0 + p1*mu1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// or else can be an point internal to the triangle
|
||||||
|
ScalarType denominator = delta0_p012 + delta1_p012 + delta2_p012;
|
||||||
|
ScalarType lambda0 = delta0_p012/denominator;
|
||||||
|
ScalarType lambda1 = delta1_p012/denominator;
|
||||||
|
ScalarType lambda2 = delta2_p012/denominator;
|
||||||
|
witness = p0*lambda0 + p1*lambda1 + p2*lambda2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res!=NULL)
|
||||||
|
{
|
||||||
|
ScalarType witness_norm = witness.Norm();
|
||||||
|
res->first = vcg::math::Max< ScalarType >( witness_norm-radius, ScalarType(0.0) );
|
||||||
|
res->second = vcg::math::Max< ScalarType >( radius-witness_norm, ScalarType(0.0) );
|
||||||
|
}
|
||||||
|
penetration_detected = (witness.SquaredNorm() <= (radius*radius));
|
||||||
|
witness += center;
|
||||||
|
return penetration_detected;
|
||||||
|
}; //end of IntersectionSphereTriangle
|
||||||
|
|
||||||
|
|
||||||
/// intersection between line and plane
|
/// intersection between line and plane
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue