确定:在线段上的点 [英] determinate: is point on line segment
问题描述
我正在尝试编写Java方法,如果point(x,y)位于线段上,则返回boolean真,否则返回false.
I am trying to code an java methods wich returns an boolean true if a point(x,y) is on a line segment and false if not.
我尝试过:
public static boolean OnDistance(MyLocation a, MyLocation b, MyLocation queryPoint) {
double value = java.lang.Math.signum((a.mLongitude - b.mLongitude) * (queryPoint.mLatitude - a.mLatitude)
- (b.mLatitude - a.mLatitude) * (queryPoint.mLongitude - a.mLongitude));
double compare = 1;
if (value == compare) {
return true;
}
return false;
}
但是它不起作用. 帮助和建议,不胜感激.谢谢!
but it doesnt work. help and advice is greatly appreciated. Thank you!
推荐答案
我不是 JAVA 编码器,所以我坚持数学运算...对于初学者,请假设您在飞机上(而不是球面) )
I am not JAVA coder so I stick to math behind ... For starters let assume you are on plane (not sphere surface)
-
我会使用向量数学,所以让:
a,b
-是行端点
q
-查询点
c=q-a
-查询的行方向向量
d=b-a
-线方向矢量
a,b
- be the line endpoints
q
- queried point
c=q-a
- queried line direction vector
d=b-a
- line direction vector
使用点积进行参数提取
t=dot(c,d)/(|c|*|d|)
t
是行参数<0,1>
,如果超出范围q
不在行内
|c|=sqrt(c.x*c.x+c.y*c.y)
向量的大小
dot(c,d)=c.x*d.x+c.y*d.y
标量向量相乘
t
is line parameter <0,1>
if out of range q
is not inside line
|c|=sqrt(c.x*c.x+c.y*c.y)
size of vector
dot(c,d)=c.x*d.x+c.y*d.y
scalar vector multiply
现在计算线上的对应点
e=a+(t*d)
e
是ab
计算q
和ab
compute perpendicular distance of q
and ab
l=|q-e|;
如果(l>treshold)
,则q
不在行ab
上,否则在ab
行上.阈值是您仍在接受为线内线的最大距离.不需要l
sqrt-ed阈值常数可以用2来代替速度.
if (l>treshold)
then q
is not on line ab
else it is on the line ab
. The threshold is the max distance from line you are still accepting as inside line. No need to have l
sqrt-ed the threshold constant can be powered by 2 instead for speed.
如果将所有这些都添加到单个方程式中
然后某些事情会自我简化(希望不会犯一些愚蠢的数学错误)
then some things will simplify itself (hope did not make some silly math mistake)
l=|(q-a)-(b-a)*(dot(q-a,b-a)/|b-a|^2)|;
return (l<=treshold);
或
l=|c-(d*dot(c,d)/|d|^2)|;
return (l<=treshold);
如您所见,我们甚至不需要sqrt
:)
As you can see we do not even need sqrt
for this :)
[注释]
如果需要球形或椭圆形表面,则需要指定更近的半轴.这条线变为弧线/曲线,需要进行一些校正,具体取决于表面的形状.
If you need spherical or ellipsoidal surface instead then you need to specify it closer which it is what are the semi axises. The line become arc/curve and need some corrections which depends on the shape of surface see
,但也可以通过近似来完成,也可以通过对点e
的二进制搜索来实现,请参见:
but can be done also by approximation and may be also by binary search of point e
see:
使用的矢量数学可以在最后找到:
The vector math used can be found here at the end:
此处3D C ++实现(具有不同的名称):
double distance_point_axis(double *p,double *p0,double *dp)
{
int i;
double l,d,q[3];
for (i=0;i<3;i++) q[i]=p[i]-p0[i]; // q = p-p0
for (l=0.0,i=0;i<3;i++) l+=dp[i]*dp[i]; // l = |dp|^2
for (d=0.0,i=0;i<3;i++) d+=q[i]*dp[i]; // d = dot(q,dp)
if (l<1e-10) d=0.0; else d/=l; // d = dot(q,dp)/|dp|^2
for (i=0;i<3;i++) q[i]-=dp[i]*d; // q=q-dp*dot(q,dp)/|dp|^2
for (l=0.0,i=0;i<3;i++) l+=q[i]*q[i]; l=sqrt(l); // l = |q|
return l;
}
其中p0[3]
是轴上的任何点,而dp[3]
是轴的方向向量. p[3]
是您想要到轴的距离的查询点.
Where p0[3]
is any point on axis and dp[3]
is direction vector of axis. The p[3]
is the queried point you want the distance to axis for.
这篇关于确定:在线段上的点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!