Freitag, 17. August 2012

ActionScript: Distance between line and a point

/**
 * Computes the difference vector between two vectors.
 * @param p1 First vector (from (0,0).
 * @param p2 Second vector (from (0,0).
 * @return  The difference vector between p1 and p2.
 */
public static function differenceVector(p1 : Point, p2 : Point) : Point {
 return new Point(p2.x - p1.x, p2.y - p1.y);
}
  
/**
 * Projects a point onto a line. Returns the projected point or null if
 * the projection does not fall within the segment. 
 * 
 * @param lineStart First point of the line.
 * @param lineEnd Second point of the line.
 * @param p Point that should be projected onto the line given by 
 *              lineStart and lineEnd.
 * @return      The projected point on the line or null if the projection line
 *              falls not between lineStart and lineEnd.
 */
public static function projectPointOntoLine(lineStart : Point, 
                                            lineEnd : Point, 
                                            p : Point) : Point {
 // Difference vector is the line.
 var l : Point = differenceVector(lineEnd, lineStart);
   
 // Determine determinant and divide it by the length of the line.
 var u : Number = (((p.x - lineStart.x) * (lineEnd.x - lineStart.x)) + 
                          ((p.y - lineStart.y) * (lineEnd.y - lineStart.y))) / 
                         (l.length * l.length);
   
 // Check whether the projection lies between lineStart and lineEnd.
 if ((u < 0) || (u > 1)) {
  return null;
 }
   
 // Compute projection point.
 var pp : Point = new Point(lineStart.x + u * (lineEnd.x - lineStart.x),
                                   lineStart.y + u * (lineEnd.y - lineStart.y));
   
 return pp;
}
  
/**
 * Computes the shortest distance between a line and a point. If the 
 * point cannot be projected onto the line segment specified by
 * lineStart and lineEnd, the function will return -1.
 * 
 * @param lineStart First point of the line.
 * @param lineEnd Second point of the line.
 * @param p Point that should be projected onto the line given by
 *              lineStart and lineEnd.
 * @return      The distance between p and the line or -1 if p cannot be
 *              projected onto the line.
 */
public static function distanceLinePoint(lineStart : Point, 
                                         lineEnd : Point, 
                                         p : Point) : Number {
 var projection : Point = projectPointOntoLine(lineStart, lineEnd, p);
 if (projection != null) {
  return differenceVector(p, projection).length;
 } else {
  return -1;
 }
}

Keine Kommentare:

Kommentar veröffentlichen