Created
October 14, 2011 10:43
-
-
Save instcode/1286793 to your computer and use it in GitHub Desktop.
Test if a point is "near" a segment specified by 2 points
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See: www.exaflop.org/docs/cgafaq/cga1.html | |
// Let the point be C (Cx,Cy) and the line be AB (Ax,Ay) to (Bx,By). | |
// Let P be the point of perpendicular projection of C on AB. The parameter | |
// r, which indicates P's position along AB, is computed by the dot product | |
// of AC and AB divided by the square of the length of AB: | |
// AC dot AB | |
// r = --------- | |
// ||AB||^2 | |
// | |
// r has the following meaning: | |
// | |
// r=0 P = A | |
// r=1 P = B | |
// r<0 P is on the backward extension of AB | |
// r>1 P is on the forward extension of AB | |
// 0<r<1 P is interior to AB | |
// | |
// L = sqrt((Bx-Ax)^2 + (By-Ay)^2) | |
// | |
// (Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay) | |
// => r = -------------------------------- | |
// L^2 | |
// | |
// (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) | |
// Let s = ----------------------------- | |
// L^2 | |
// => d = |s * L| | |
public class RoadSegment { | |
private double Ax, Ay; | |
private double Bx, By; | |
private double ABx, ABy; | |
private double sqAB; | |
private double length; | |
private double width; | |
public RoadSegment(double lon1, double lat1, double lon2, double lat2, double roadWidth) { | |
Ax = lat1; Ay = lon1; | |
Bx = lat2; By = lon2; | |
ABx = Bx - Ax; | |
ABy = By - Ay; | |
sqAB = ABx * ABx + ABy * ABy; | |
length = Math.sqrt(sqAB); | |
width = roadWidth; | |
} | |
public boolean isNear(double lon, double lat) { | |
double Cx = lat, Cy = lon; | |
double ACx = Cx - Ax, ACy = Cy - Ay; | |
double r = (ACx * ABx + ACy * ABy) / sqAB; | |
if (r < 0 || r > 1) { | |
return false; | |
} | |
double d = Math.abs((-ACy * ABx + ACx * ABy) / length); | |
return (d < width); | |
} | |
public double getLength() { | |
return length; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment