]> granicus.if.org Git - graphviz/commitdiff
Add point_to_lineseg_dist.
authorerg <devnull@localhost>
Mon, 27 Jul 2009 16:04:24 +0000 (16:04 +0000)
committererg <devnull@localhost>
Mon, 27 Jul 2009 16:04:24 +0000 (16:04 +0000)
lib/glcomp/glutils.c
lib/glcomp/glutils.h

index b84dd2d2e7e2c272ff83d9770b436a10c67a75e4..cb05562a3f2492ec2cefec9e85e1fcec1803cbfa 100644 (file)
@@ -312,6 +312,16 @@ static point3f scale (double d, point3f p)
     return p;
 }
 
+static point3f blend (point3f p, point3f q, float m)
+{
+    point3f r;
+
+    r.x = p.x + m * ( q.x - p.x );
+    r.y = p.y + m * ( q.y - p.y );
+    r.z = p.z + m * ( q.z - p.z );
+    return r;
+}
+
 static point3f normalize (point3f p)
 {
    double d = len (p);
@@ -350,44 +360,32 @@ double point_to_line_dist (point3f p, point3f a, point3f b) {
     return (dist (p, q));
 }
 
-#ifdef UNUSED
-
-static float Magnitude(point3f *Point1, point3f *Point2 )
-{
-    point3f Vector;
-
-    Vector.x = Point2->x - Point1->x;
-    Vector.y = Point2->y - Point1->y;
-    Vector.z = Point2->z - Point1->z;
-
-    return (float)sqrt( Vector.x * Vector.x + Vector.y * Vector.y + Vector.z * Vector.z );
-}
 
-int DistancePointLine(point3f *Point, point3f *LineStart, point3f *LineEnd, float *Distance )
+/*
+ * Given a line segment determined by two points a and b, and a 3rd point p,
+ * return the distance between the point and the segment.
+ * If the perpendicular from p to the line a-b is outside of the segment,
+ * return the distance to the closer of a or b.
+ */
+double point_to_lineseg_dist (point3f p, point3f a, point3f b)
 {
-    float LineMag;
     float U;
-    point3f Intersection;
-
-    LineMag = Magnitude( LineEnd, LineStart );
-
-    U = ( ( ( Point->x - LineStart->x ) * ( LineEnd->x - LineStart->x ) ) +
-    ( ( Point->y - LineStart->y ) * ( LineEnd->y - LineStart->y ) ) +
-    ( ( Point->z - LineStart->z ) * ( LineEnd->z - LineStart->z ) ) ) /
-    ( LineMag * LineMag );
+    point3f q;
+    point3f ba = sub (b, a);
+    point3f pa = sub (p, a);
 
-    if( U < 0.0f || U > 1.0f )
-        return 0;   // closest point does not fall within the line segment
+    U = dot (pa, ba)/dot (ba, ba);
 
-    Intersection.x = LineStart->x + U * ( LineEnd->x - LineStart->x );
-    Intersection.y = LineStart->y + U * ( LineEnd->y - LineStart->y );
-    Intersection.z = LineStart->z + U * ( LineEnd->z - LineStart->z );
+    if (U > 1)
+       q = b;
+    else if (U < 0)
+       q = a;
+    else 
+       q = blend (a, b, U);
 
-    *Distance = Magnitude( Point, &Intersection );
+    return dist(p, q);
 
-    return 1;
 }
-#endif
 
 #ifdef DEBUG
 void main( void )
index 642bb4d9c85bf692812b4230919bf53ac31c2536..dafa07a9c29cc2ff4f3fddca20ac5e9ffebd1d22 100644 (file)
@@ -33,5 +33,6 @@ int GetFixedOGLPoslocal(int x, int y, GLfloat * X, GLfloat * Y, GLfloat * Z);
 void to3D(int x, int y, GLfloat * X, GLfloat * Y,GLfloat * Z);
 void linear_interplotate (float,float,float,float,float,float*);
 double point_to_line_dist(point3f p, point3f u, point3f v);
+double point_to_lineseg_dist (point3f p, point3f a, point3f b);
 
 #endif