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);
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 )
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