|
From: <pat...@us...> - 2011-03-27 18:11:06
|
Revision: 1272
http://ggt.svn.sourceforge.net/ggt/?rev=1272&view=rev
Author: patrickh
Date: 2011-03-27 18:11:00 +0000 (Sun, 27 Mar 2011)
Log Message:
-----------
Added an overload of gmtl::findClosestPt() for use with gmtl::Tri<T> and
gmtl::Point<T, 3>.
Submitted by: Sebastian Messerschmidt
Modified Paths:
--------------
trunk/ChangeLog
trunk/gmtl/TriOps.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2011-03-27 17:31:11 UTC (rev 1271)
+++ trunk/ChangeLog 2011-03-27 18:11:00 UTC (rev 1272)
@@ -1,5 +1,8 @@
DATE AUTHOR CHANGE
---------- ------------ -------------------------------------------------------
+2011-03-27 patrickh Added an overload of gmtl::findClosestPt() for use with
+ gmtl::Tri<T> and gmtl::Point<T, 3>.
+ Submitted by Sebastian Messerschmidt
2011-03-27 patrickh Added an overload of gmtl::intersectDoubleSided() for
Tri/LineSeg intersection that ignores the triangle
winding.
Modified: trunk/gmtl/TriOps.h
===================================================================
--- trunk/gmtl/TriOps.h 2011-03-27 17:31:11 UTC (rev 1271)
+++ trunk/gmtl/TriOps.h 2011-03-27 18:11:00 UTC (rev 1272)
@@ -18,6 +18,83 @@
*/
/**
+ * Finds the closest point on the triangle to a given point.
+ *
+ * @param tri The triangle to test.
+ * @param pt The point which to test against triangle.
+ *
+ * @return the point on the line segment closest to pt.
+ *
+ * @since 0.7.0
+ */
+template< class DATA_TYPE >
+Point<DATA_TYPE, 3> findNearestPt(const Tri<DATA_TYPE>& tri,
+ const Point<DATA_TYPE, 3>& pt)
+{
+ // inspired by Real Time Collision Detection 1st Edition p. 144 ff
+ Vec<DATA_TYPE, 3> ab = tri.edge(0,1);
+ Vec<DATA_TYPE, 3> ac = tri.edge(0,2);
+ Vec<DATA_TYPE, 3> ap = pt - tri.mVerts[0]; // p - a
+
+ // check if P in vertex region outside a
+ DATA_TYPE d1 = dot(ab, ap);
+ DATA_TYPE d2 = dot(ac, ap);
+ if (d1 <= 0.0 && d2 <= 0.0)
+ {
+ return tri.mVerts[0];
+ }
+
+// check if P in vertex region outside b
+ Vec<DATA_TYPE, 3> bp = pt - tri.mVerts[1]; // p -b
+ DATA_TYPE d3 = dot(ab, bp);
+ DATA_TYPE d4 = dot(ac, bp);
+
+ if (d3 >= 0 && d4 <= d3)
+ {
+ return tri.mVerts[1];
+ }
+
+ // check if p in edge region of AB, if true return projection of P onto AB
+ DATA_TYPE vc = d1*d4 - d3*d2;
+ if (vc <= 0.0 && d1 >= 0.0 && d3 <= 0.0)
+ {
+ DATA_TYPE v = d1 / (d1 - d3);
+ return tri.mVerts[0] + v * ab;
+ }
+
+ // check if P in vertex region outside c
+ Vec<DATA_TYPE, 3> cp = pt - tri.mVerts[2]; // p - c
+ DATA_TYPE d5 = dot(ab, cp);
+ DATA_TYPE d6 = dot(ac, cp);
+ if (d6 >= 0.0 && d5 <= d6)
+ {
+ return tri.mVerts[2];
+ }
+
+ // check if p in edge region of AC, if true return projection of P onto AC
+ DATA_TYPE vb = (d5 * d2) - (d1 * d6);
+ if (vb <= 0.0 && d2 >= 0.0 && d6 <= 0.0)
+ {
+ DATA_TYPE w = d2 / (d2 - d6);
+ return tri.mVerts[0] + w * ac;
+ }
+
+ // check if p in edge region of BC, if true return projection of P onto BC
+ DATA_TYPE va = (d3 * d6) - (d5 * d4);
+ if (va <= 0.0 && (d4 -d3) >= 0.0 && (d5 - d6) >= 0.0)
+ {
+ DATA_TYPE w = (d4 -d3) / ((d4 - d3) + (d5 -d6));
+ return tri.mVerts[1] + w * (tri.edge(1,2));
+ }
+
+ // P inside face region Compute Q trough barycentric coordinates
+ DATA_TYPE denom = 1.0 / (va + vb + vc);
+ DATA_TYPE v = vb * denom;
+ DATA_TYPE w = vc * denom;
+ return (tri.mVerts[0] + (ab * v) + (ac * w));
+}
+
+/**
* Computes the point at the center of the given triangle.
*
* @param tri the triangle to find the center of
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|