我得到一个具有两个端点的线段:(x1,y1) (x2,y2) 和一个随机点:(x3,y3)。
如果我将线段转换为极坐标,我需要能够以编程方式找出线段上最接近点 (x3,y3) 的点。
编辑:我在我的问题中犯了一个错误。问题不在于试图找到三者之间的最近点。问题是...给定一条带有起点和终点的 AB 线...在直线上找到最接近点 (x3,y3) 的任何点。
我得到一个具有两个端点的线段:(x1,y1) (x2,y2) 和一个随机点:(x3,y3)。
如果我将线段转换为极坐标,我需要能够以编程方式找出线段上最接近点 (x3,y3) 的点。
编辑:我在我的问题中犯了一个错误。问题不在于试图找到三者之间的最近点。问题是...给定一条带有起点和终点的 AB 线...在直线上找到最接近点 (x3,y3) 的任何点。
我想这为时已晚,以防万一有人需要,我只是转换回笛卡尔坐标,因此公式更易于查看:
public static double distance(double r1,double t1,double r2,double t2,double r3,double t3)
{
double x1 = (r1*Math.cos(t1));
double x2 = (r1*Math.cos(t2));
double x3 = (r1*Math.cos(t3));
double y1 = (r1*Math.sin(t1));
double y2 = (r1*Math.sin(t2));
double y3 = (r1*Math.sin(t3));
return Math.abs((x2-x1)*(y1-y3)-(x1-x3)*(y2-y1))/Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
public static Location closest(double x1, double y1, double x2, double y2, double x3, double y3){
Location a = new Location("provider");
Location b = new Location("provider");
Location c = new Location("provider");
//I can't remember which one goes where, you may need to swap all the x/ys around
//Do conversion or something here.
a.setLongitude(x1);
a.setLatitude(y1);
b.setLongitude(x2);
b.setLatitude(y2);
c.setLongitude(x3);
c.setLongitude(y3);
return closest(a, b, c);
}
public static Location closest(Location a, Location b, Location c){
return a.distanceTo(c) < b.distanceTo(c) ? a : b;
}
本题涉及小学代数:最近点只有3个选项:
使用毕达哥拉斯很容易找到 (x3,y3) 到两点之间的距离:
d1 = d(<x1,y1>,<x3,y3>) = sqrt( (x1-x3)^2 + (y1-y3)^2)
和
d2 = d(<x2,y2>,<x3,y3>) = sqrt( (x2-x3)^2 + (y2-y3)^2)
现在对于“更复杂”的部分:如果段上有另一个点更接近 (x3,y3) - 如果我们连接这些点 - 我们将有一个与原始段对角线的新段 - 我们必须将它与一阶方程(对于一条线)一起使用来找到第三个点,看看它是在线段上还是在外面(如果它在线段之外,那么我们将取 (x3,y3) 之间的最小距离到另外两点。
直线方程(请原谅我的英语 - 我是用母语学习的,所以请耐心等待)是:
(I) y = mx + d
其中 m 很容易计算:
m = (y1-y2)/(x1-x2)
现在我们知道 的值m
为了找到d
我们将使用前两点之一的值,例如:
y1 = mx1 +d => d = y1 - mx1
对角线将具有m'
is -1/m
,如果我们使用 (x3,y3) 的值,我们会发现d'
. 所以现在我们知道 (I) 的值以及对角线的方程:
(II) y=m'x + d'
如果我们使用这两个方程,我们可以在原始线段通过的线上找到最接近 (x3,y3) 的点 - 如果该点位于线段上 - 我们就完成了,否则,就像前面提到的 - 我们将在 d1
和之间取最小值d2