Revision: 53775
http://brlcad.svn.sourceforge.net/brlcad/?rev=53775&view=rev
Author: r_weiss
Date: 2012-11-19 23:18:06 +0000 (Mon, 19 Nov 2012)
Log Message:
-----------
Added two new functions to libbn in file "plane.c". Added
"bn_distsq_pt3_lseg3_v2" which a test version of "bn_distsq_pt3_lseg3" and
"bn_are_equal" which is a support function for this new test function. At some
point this test function and the original will be consolidated.
Modified Paths:
--------------
brlcad/trunk/src/libbn/plane.c
Modified: brlcad/trunk/src/libbn/plane.c
===================================================================
--- brlcad/trunk/src/libbn/plane.c 2012-11-19 22:05:36 UTC (rev 53774)
+++ brlcad/trunk/src/libbn/plane.c 2012-11-19 23:18:06 UTC (rev 53775)
@@ -2322,6 +2322,205 @@
/**
+ * B N _ A R E _ E Q U A L
+ *
+ * This is a support function for the test function "bn_distsq_pt3_lseg3_v2".
+ *
+ */
+int
+bn_are_equal(fastf_t a, fastf_t b, fastf_t t)
+{
+ fastf_t ai, af, bi, bf;
+ int ret = 0;
+
+ af = modf(a, &ai);
+ bf = modf(b, &bi);
+
+ if ((long)ai == (long)bi && t < 1.0) {
+ if (NEAR_EQUAL(af, bf, t)) {
+ ret = 1;
+ }
+ } else {
+ if (NEAR_EQUAL(a, b, t)) {
+ ret = 1;
+ }
+ }
+ return ret;
+}
+
+
+/**
+ * B N _ D I S T S Q _ P T 3 _ L S E G 3 _ v 2
+ *
+ * Find the square of the distance from a point P to a line segment described
+ * by the two endpoints A and B.
+ *
+ * P
+ * *
+ * /.
+ * / .
+ * / .
+ * / . (dist)
+ * / .
+ * / .
+ * *------*--------*
+ * A PCA B
+ *
+ * There are six distinct cases, with these return codes -
+ * 0 P is within tolerance of lseg AB. *dist = 0.
+ * 1 P is within tolerance of point A. *dist = 0.
+ * 2 P is within tolerance of point B. *dist = 0.
+ * 3 PCA is within tolerance of A. *dist = |P-A|**2.
+ * 4 PCA is within tolerance of B. *dist = |P-B|**2.
+ * 5 P is "above/below" lseg AB. *dist=|PCA-P|**2.
+ *
+ * This function is a test version of "bn_distsq_pt3_lseg3".
+ *
+ */
+int
+bn_distsq_pt3_lseg3_v2(fastf_t *distsq, const fastf_t *a, const fastf_t *b,
const fastf_t *p, const struct bn_tol *tol)
+{
+ vect_t AtoB, AtoP, BtoP;
+ fastf_t AtoB_mag, AtoP_mag, AtoPCA_mag, PtoPCA_mag, BtoP_mag;
+ fastf_t dot, dt, dist;
+ int ret;
+
+ dt = tol->dist;
+ VSUB2(AtoB, b, a);
+ AtoB_mag = MAGNITUDE(AtoB);
+ VSUB2(AtoP, p, a);
+ AtoP_mag = MAGNITUDE(AtoP);
+ if (AtoB_mag < dt) {
+ /* (A=B) */
+ if (AtoP_mag < dt) {
+ /* ambiguous case: (A=B) (A=P) (B=P) */
+ /* return could be 0 thru 4 */
+ /* P is within tolerance of point A */
+ dist = 0.0;
+ ret = 1;
+ } else {
+ /* ambiguous case: (A=B) (A!=P) */
+ /* return could be 3 thru 5 */
+ /* P is "above/below" lseg AB */
+ dist = AtoP_mag;
+ ret = 5;
+ }
+ } else {
+ /* (A!=B) */
+ if (AtoP_mag < dt) {
+ /* ambiguous case: (A!=B) (A=P) */
+ /* return could be 0,1,3 */
+ dist = 0.0;
+ ret = 1; /* P is within tolerance of point A */
+ } else {
+ /* (A!=B) (A!=P) */
+ if (bn_lseg3_lseg3_parallel(a, b, a, p, tol)) {
+ /* AtoB and AtoP are collinear */
+ dot = VDOT(AtoB, AtoP);
+ if (dot > SMALL_FASTF) {
+ /* AtoB and AtoP pointing in the same direction */
+ if (bn_are_equal(AtoB_mag, AtoP_mag, dt) ||
bn_pt3_pt3_equal(b, p, tol)) {
+ /* AtoB and AtoP pointing in the same direction */
+ /* (B=P) */
+ /* ambiguous case: (A!=B) (A!=P) (B=P) */
+ /* return could be 0, 2, 4 */
+ dist = 0.0;
+ ret = 2;
+ } else if (AtoP_mag > AtoB_mag) {
+ /* AtoB and AtoP pointing in the same direction */
+ /* (A!=B) (A!=P) (B!=P), lsegs AtoB and AtoP are
collinear.
+ * P is to the right of B, not above/below lseg AtoB.
+ */
+ /* both P and PCA and not within tolerance of lseg AtoB
*/
+ dist = AtoP_mag - AtoB_mag;
+ ret = 4;
+ } else {
+ /* AtoB and AtoP pointing in the same direction */
+ /* (A!=B) (A!=P) (B!=P), lsegs AtoB and AtoP are
collinear */
+ /* AtoP_mag < AtoB_mag */
+ /* P is on lseg AtoB */
+ dist = 0.0;
+ ret = 0;
+ }
+ } else {
+ /* AtoB and AtoP are collinear */
+ /* AtoB and AtoP pointing in opposite directions */
+ /* P is to the left of A, not above/below lseg AtoB. */
+ /* both P and PCA and not within tolerance of lseg AtoB */
+ dist = AtoP_mag;
+ ret = 3;
+ }
+ } else {
+ /* (A!=B) (A!=P) */
+ /* AtoB and AtoP are not collinear */
+ dot = VDOT(AtoP, AtoB);
+ if ZERO(dot) {
+ /* (A=PCA), lsegs AtoB and AtoP are perpendicular */
+ dist = AtoP_mag;
+ ret = 3;
+ } else if (dot > SMALL_FASTF) {
+ AtoPCA_mag = dot / AtoB_mag;
+ if (NEAR_ZERO(AtoPCA_mag, dt)) {
+ /* (A=PCA), lsegs AtoB and AtoP are perpendicular */
+ dist = AtoP_mag;
+ ret = 3;
+ } else if (bn_are_equal(AtoPCA_mag, AtoB_mag, dt) ||
EQUAL(AtoPCA_mag, AtoB_mag)) {
+ /* (B=PCA) */
+ VSUB2(BtoP, p, b);
+ BtoP_mag = MAGNITUDE(BtoP);
+ if (BtoP_mag < dt) {
+ /* ambiguous case: (B=PCA) (B=P) */
+ /* return could be 2 or 4 */
+ dist = 0.0;
+ ret = 2;
+ } else {
+ /* (B=PCA) (B!=P) */
+ dist = BtoP_mag;
+ ret = 4;
+ }
+ } else if (AtoPCA_mag < AtoB_mag) {
+ /* PCA is on lseg AtoB */
+ PtoPCA_mag = sqrt((AtoP_mag * AtoP_mag) + (AtoPCA_mag *
AtoPCA_mag));
+ if (PtoPCA_mag < dt) {
+ /* P is within tolerance of lseg AtoB */
+ dist = 0.0;
+ ret = 0;
+ } else {
+ dist = PtoPCA_mag;
+ ret = 5;
+ }
+ } else {
+ /* AtoPCA_mag > AtoB_mag */
+ /* P is to the right of B, above/below lseg AtoB. */
+ /* both P and PCA and not within tolerance of lseg AtoB
*/
+ VSUB2(BtoP, p, b);
+ BtoP_mag = MAGNITUDE(BtoP);
+ dist = BtoP_mag;
+ ret = 4;
+ }
+ } else {
+ /* dot is neg */
+ AtoPCA_mag = dot / AtoB_mag;
+ if (NEAR_ZERO(AtoPCA_mag, dt)) {
+ /* (PCA=A), lsegs AtoB and AtoP are perpendicular */
+ dist = AtoP_mag;
+ ret = 3;
+ } else {
+ /* (PCA!=A), PCA is not on lseg AtoB */
+ /* both P and PCA and not within tolerance of lseg AtoB
*/
+ dist = AtoP_mag;
+ ret = 3;
+ }
+ }
+ }
+ }
+ }
+ *distsq = dist * dist;
+ return ret;
+}
+
+
+/**
* B N _ D I S T _ P T 3 _ L S E G 3
*@brief
* Find the distance from a point P to a line segment described by the
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits