社区
图形处理/算法
帖子详情
◇◆◇点到线段的最短距离◇◆◇
GoldenEye
2002-11-22 03:55:50
有一个线段,已知两个端点的坐标,在线段以外或之中有一点,坐标也已知,但所有坐标方位、方向不定,求最简化(时间最短)“这一点到这段线段的最短距离”算法。写伪代码、示例、说明都可以,谢谢!
...全文
830
17
打赏
收藏
◇◆◇点到线段的最短距离◇◆◇
有一个线段,已知两个端点的坐标,在线段以外或之中有一点,坐标也已知,但所有坐标方位、方向不定,求最简化(时间最短)“这一点到这段线段的最短距离”算法。写伪代码、示例、说明都可以,谢谢!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
17 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
HuWenjin
2002-11-25
打赏
举报
回复
我写的代码不管是烦也好,简也好,完成楼主的问题是没有说的
多种情况全部考虚到,实际应用也没有问题,就是说不管点是什么值都返回正确的距离。
什么都不用再想,只要 COPY 到你的程序中,输入入口值就可以了
harry202
2002-11-25
打赏
举报
回复
BOOL CSCLine::IsSelLine(CPoint pt/*鼠标点击点*/,CPoint p1,CPoint p2/*直线的两个端点*/)
{
/////////////////////////////////////////////////
int x=pt.x,y=pt.y;
int x1=p1.x,y1=p1.y;
int x2=p2.x,y2=p2.y;
//如果点击不在区域中,则返回FALSE
if(!PtInRect(CRect((x1<=x2?x1:x2)-5,
(y1<=y2?y1:y2)-5,
(x1>x2?x1:x2)+5,
(y1>y2?y1:y2)+5),pt))
return FALSE;
//计算距离
double d;
double sq = sqrt(y1*y1+x1*x1);
if(sq==0)
{
d = sqrt(x*x+y*y);
}
else
d = fabs((y1-y2)*x+(x2-x1)*y+x1*y2-x2*y1)/sq;
if(d<5)
return TRUE;//误差值,也可以通过函数参数传进来。
else
return FALSE;
}
---------------------
我刚写的,测试通过
HuWenjin
2002-11-25
打赏
举报
回复
试一下吗 不试怎知呢?
WesleyWu
2002-11-25
打赏
举报
回复
但是效率和我的不是一个数量级的哦,毕竟acos和sin比起sqrt要慢许多啊。
icansaymyabc
2002-11-23
打赏
举报
回复
问这个问题的搂主,说明你没好好听数学课,不是好学生。
crazy_lazy_pig
2002-11-22
打赏
举报
回复
直线方程两点式(变形):(x1-x2)*(y-y1)=(x-x1)*(y1-y2)
整理成标准形式:A*x + B*y + C = 0
点(x0,y0)到直线的距离为:
abs(A*x0 + B*y0 + C)/sqrt(A^2 + B^2) (1)
两点间距离公式(略)。
若你认为公式(1)的结果不是你要的,则其结果与点(x0,y0)到线段两端点的距离中取最短的一个。
最后再强调一点,距离本来就是与坐标系位置、方向、角度无关的量,除非你把坐标系的单位长度改变。所以你在一个坐标下得到的结果等同于坐标平移、旋转后的结果
WesleyWu
2002-11-22
打赏
举报
回复
不好意思,我上面有个地方打错了
应该是:
计算出从原点出发到线段的垂足坐标(x3,y3),和它相应的t
判断垂足是否在线段上,如果是,结果就是|d|,否则,取线段两个端点到原点距离的最小值为结果。
result=min(x1*x1+y1*y1,x2*x2+y2*y2);
WesleyWu
2002-11-22
打赏
举报
回复
虽是一个平面,但不能直接用点到直线的距离阿。所以要加以判断线段内或线段外。
shenanigan
2002-11-22
打赏
举报
回复
一样学习
感觉是数学问题
一线中的两点 和线外或线内一点 ,不还是在一个平面里面的吗?
何必要这么麻烦?
RomanticProgrammer
2002-11-22
打赏
举报
回复
学习.
zyl910
2002-11-22
打赏
举报
回复
http://expert.csdn.net/Expert/topic/715/715509.xml?temp=.5165369
WesleyWu
2002-11-22
打赏
举报
回复
连acos都用上了,不用这么麻烦吧。
设线段(x1,y1)-(x2,y2),另一测试点为(x0,y0),result为本题要求的“这一点到这段线段的最短距离”的结果。
如果(x0,y0)不是原点,做相应的坐标变换,使得原坐标系中的(x0,y0)为新坐标系中的原点,x轴和y轴方向不变,单位长度不变。以下算法都认为测试点是原点。
首先,计算出从原点指向该线段所在直线的单位法向量n={nx,ny},以及线段所在直线到原点的有向距离d。
//////////////////////////////////////////////////
dx=x2-x1; dy=y2-y1;
if (dx!=0.0f)
{
ny=1.0f;
nx=-ny*dy/dx;
} else {
nx=1.0f;
ny=-nx*dx/dy;
}
l=1/sqrt(nx*nx+ny*ny);
nx*=l; ny*=l;
d=x1*nx+y1*ny;
//////////////////////////////////////////////////
把这个线段用参数形式表示,t为参数。
x=x1+t*(x2-x1)
y=y1+t*(y2-y1)
如果 0<=t<=1 则该点(x,y)在线段上,否则在线段外。
计算出从原点出发到线段的垂足坐标(x3,y3),和它相应的t
判断垂足是否在线段上,如果是,结果就是|d|,否则,取线段两个端点到原点距离的最大值为结果。
//////////////////////////////////////////////////
x3=d*nx; y3=d*ny;
t=(dx!=0.0f) ? (x3-x1)/dx : (y3-y1)/dy;
if (t>=0.0f && t<=1.0f)
{
result=fabs(d);
} else {
result=max(x1*x1+y1*y1,x2*x2+y2*y2);
result=sqrt(result);
}
//////////////////////////////////////////////////
给分吧 :)
HuWenjin
2002-11-22
打赏
举报
回复
要给分,要不再不回答了
//计算点 point 到线段 (lineX,lineY) 的距离,返回计算的距离值
float PointToLine(CPoint LineX,CPoint LineY,CPoint point)
{
float xx,yy,x1,y1,x2,y2;
xx = (float)point.x;
yy = (float)point.y;
x1 = (float)LineX.x;
y1 = (float)LineX.y;
x2 = (float)LineY.x;
y2 = (float)LineY.y;
float a,b,c,ang1,ang2,ang;
//计算三条边的距离
a=CalcTwoPointLong(LineX,point);if(a==0.0)return 0.0;
b=CalcTwoPointLong(LineY,point);if(b==0.0)return 0.0;
c=CalcTwoPointLong(LineX,LineY);
//如果(x1,y1)和(x2,y2)是一个点直接返回距离
if(c==0.0) return a;
if(a<b) //如果(xx,yy)的点(x1,y1)这条边较短
{
if(y1==y2)
{
if(x1<x2)
ang1=0;
else
ang1=(float)PAI;
}
else
{
ang1=(float)acos((x2-x1)/c);
if(y1>y2)ang1=(float)PAI*2-ang1; //直线(x1,y1)-(x2,y2)的弧度
}
ang2=(float)acos((xx-x1)/a);
if(y1>yy)ang2=(float)PAI*2-ang2; //直线(x1,y1)-(xx,yy)的弧度
ang=ang2-ang1;
if(ang<0)ang=-ang;
if(ang>PAI) ang=(float)PAI*2-ang; //交角的大小
if(ang>PAI/2) return a; //如果为钝角,直接返回距离
else
return (a*(float)sin(ang)); //否则返回计算得到的距离
}
else //如果(xx,yy)的点(x2,y2)这条边较短
{
if(y1==y2)
{
if(x1<x2)
ang1=(float)PAI;
else
ang1=0;
}
else
{
ang1=(float)acos((x1-x2)/c); //直线(x2,y2)-(x1,y1)的斜率的弧度
if(y2>y1)ang1=(float)PAI*2-ang1;
}
ang2=(float)acos((xx-x2)/b); //直线(x2,x1)-(xx,yy)的斜率的弧度
if(y2>yy)ang2=(float)PAI*2-ang2;
ang=ang2-ang1;
if(ang<0) ang=-ang;
if(ang>PAI) ang=(float)PAI*2-ang; //交角的大小 ?
if(ang>PAI/2) return b; //如果为钝角,直接返回距离
else
return(b*(float)sin(ang)); //否则返回计算得到的距离
}
}
#define PAI 3.1415926
GoldenEye
2002-11-22
打赏
举报
回复
在二维,应该这么说:
1、过这两点做与这个线段垂直的直线,形成一个“区域”,我们暂叫他“path”;
2、出现两种情况,一种就是这个点在path之外,这时所求必为线段两端点中的一个,另外一种就在path之内,利用普通的勾股定理就ok;
原理很简单,问题在于:线段方向是任意的,我们怎么知道这个点在path之内还是之外?
body
2002-11-22
打赏
举报
回复
1。过点做与线段所在直线垂直的平面。
2。求出平面与线段所在直线的交点。
3。如果交点位于线段上,交点为所求。
4。如果不是,所求必为线段两端点中的一个。
Aizz
2002-11-22
打赏
举报
回复
“但所有坐标方位、方向不定”--几维坐标系?
用勾股定理吧,是不是最简就不知道了。
rtdb
2002-11-22
打赏
举报
回复
只要在一个坐标系内, 此题与坐标方位、方向无关.
一种
点到
线段
的最
短距离
的方法
一种
点到
线段
的最
短距离
的方法 下面介绍
点到
线段
的最
短距离
的方法: 图 1-6
点到
线段
的最
短距离
图1-6描述了一种计算点D到
线段
AC的最
短距离
的计算方法。直线方程由经过两点A (x1,y1) 和 C (x2,y2)确定: B = A + u (C - A) (1-9) 其中u为0到1之间的值,
线段
AC上的点B (x,y)是最靠近D的点,并且满足下面关系: (D - B) ...
点到
线段
的最
短距离
点到
线段
最
短距离
的运算与
点到
直线的最
短距离
的运算二者之间存在一定的差别,即求
点到
线段
最
短距离
时需要考虑参考点在沿
线段
方向的投影点是否在
线段
上,若在
线段
上才可采用
点到
直线距离公式,如图1所示。 图1 (a)最
短距离
为点P与其在
线段
AB上投影C之间的
线段
PC (b)最
点到
线段
的最
短距离
——矢量法
最近在看recast&detour源码的时候有遇到许多数学上的算法问题,特此记录,以便以后查看。矢量法推导:求点P到
线段
AB的最
短距离
。分成以下三种情况(a),(b),(c)。所以可以先根据计算出r的值,进而对应计算A点 B点 C点 和 P点之间的距离即可。特殊情况:当P在
线段
AB上:计算出来r仍然是 1>r>0, P点即C点,PC的距离d = 0;当P在
线段
AB端点或其...
Matlab求
点到
线段
的最
短距离
点到
线段
的距离是计算机图形学和计算几何学中常见的问题,本文主要介绍如何使用 Matlab 计算一个
点到
一条
线段
的最
短距离
。本文介绍了如何使用 Matlab 计算一个
点到
一条
线段
的最
短距离
。需要注意处理点在
线段
延长线上的情况,此时需要判断投影点是否在
线段
内。,分别表示
线段
两端点和需要计算距离的点。这个叉积结果是一个向量,其模长即为
点到
直线的距离。两个点所在的直线的距离,取二者中的较小值。先考虑
点到
无限长直线的距离。是否在
线段
上,若不在,则计算。否则,
点到
线段
的最近距离为。内,则
点到
线段
的距离即为。
C++功能模块8:
点到
线段
的最
短距离
在二维平面上,给出三个点的坐标分别为A(ax,ay), B(bx,by), C(cx,cy),求点A到
线段
BC的最
短距离
。从点A向直线BC作垂线,垂足可能在
线段
BC的左侧,在
线段
BC上,或者在
线段
BC的右侧三种情况,下面分别讨论。最
短距离
是三角形ABC以边BC的高,可通过海伦公式先求出面积,再求出高得到答案。最
短距离
显然是AB。
图形处理/算法
19,468
社区成员
50,678
社区内容
发帖
与我相关
我的任务
图形处理/算法
VC/MFC 图形处理/算法
复制链接
扫一扫
分享
社区描述
VC/MFC 图形处理/算法
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章