一个简单的三点共线判断问题

寻开心 2005-01-14 05:17:03
已知三个顶点p1, p2, 和p3的坐标, 请就下面两种情形,分别给出解答方案:
1) 2d下如何判断
2) 3d下如何判断
备注: 这个问题重点解决判断过程当中的运算量大小以及浮点误差问题
...全文
1905 42 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
quanchong 2005-03-13
  • 打赏
  • 举报
回复
说实话楼主确实有点寻开心了。你给个精度范围,我开个10000位的数组给你用高精度算,这总行了吧?要是开数组用高精度算都不行,那你的要求也太高了。

cbc 2005-03-13
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/3846/3846757.xml?temp=.7295038
konriuen 2005-03-13
  • 打赏
  • 举报
回复
Hough变换
zengwujun 2005-03-08
  • 打赏
  • 举报
回复
mark
laozi 2005-03-08
  • 打赏
  • 举报
回复
说实话,在工程中用浮点数本身就有些问题

其实可以构造一个函数库,用分数来替代浮点数

对于现在面向对象的高级语言来说,单个浮点数和二维坐标没有本质的区别

超大整数的处理用数组也是众所周知的

考虑到浮点数的产生时代的局限性,我一直搞不懂为什么没有出现这种基于分数的函数库

rickone 2005-02-20
  • 打赏
  • 举报
回复
p1,p2,p3是要判断的三点,三维的(多维的同样可以)
v1:=p1-p2 各维坐标分别相减
v2:=p2-p3
然后做比较,比较是有顺序的,v1对v2作比较,是拿c(某个数)乘v2.x看是否等于v1.x,再乘v2.y看是否等于v1.y,,,一直乘到最后一维:如果某一次不相等(相等要近似相等了,作差取绝对值,看是否足够小)则返回false或者某次乘法溢出同样返回false,一直到最后一维比较都相等,则v1,v2线性相关,即共线返回true。
但是c如何确定?到底拿谁跟谁比较?
从v1的分量中找一个特殊的分量,比如v1.y,这个分量满足两个条件:
1、v1.y<>0
2、v2.y<>0
[如果这样的分量不存在,再看它们中有没有零向量(这个过程可以在前面的扫描中同时标记一下完成),如果有零向量则返回true,否则返回false]
然后拿v1.y乘以一个较小的数(如0.0001),看结果是否大于v2.y,如果大于则c:=v2.y/v1.y,拿v2对v1作比较;如果小于则c:=v1.y/v2.y,拿v1对v2作比较。[开始乘一个较小的数的判断是防止求c的时候用到一次除法可能溢出]
cuixiping 2005-02-19
  • 打赏
  • 举报
回复
把三个点的坐标放大成整数,再用整数来处理。
寻开心 2005-02-16
  • 打赏
  • 举报
回复
关于浮点数的比较的问题,可以参看

http://blog.csdn.net/happy__888/
minlingtianxia 2005-02-10
  • 打赏
  • 举报
回复
不知道(先转化为乘法,再用高精度来做,用几个长一点的数组)可不可以?
xuzuning 2005-02-05
  • 打赏
  • 举报
回复
其实你的问题是如何确定误差的问题。
这个问题在理论上我说不清楚,但实际编程中却比较容易解决。
“所有的点坐标都用float类型来表示的”
而folat在机器中用4个字节存储,前3个字节为底数(二进制)后一个字节为指数(二进制),他们的最前面的1位为符号位。也就是说,无论存储多大多小的数据都最多只是23位二进制数的“有效数”
因此可以通过“联合”取出folat的指数进行比较,其大者作为RelError的指数而令底数为1或再大些即可
寻开心 2005-02-04
  • 打赏
  • 举报
回复
原来虽然考虑到了 a==b 使用绝对误差判断是否相同,但是实际上在浮点数范围变化比较大的时候,这个绝对误差判断方法失效了

再放几天,节后揭帖

同时再看看,有无完整的代码给出
就目前的回答状况, 不好给分 :)
寻开心 2005-02-04
  • 打赏
  • 举报
回复
经过几天的测试和思考,总于想明白了
其实核心的问题不在如何计算的算法上,实际上是在浮点数的相等的比较上

对于整数 A==B简单
对于浮点数 A==B 99%会失败的

总结浮点数比较方法如下:
1 浮点数表达本身就是不精确的,比如0.5, 0.25, 0.125这种数字在二进制浮点表达方法当中是可以准确表达的,而0.2, 0.3这样的是无法准确表达的,这就造成了误差
2 为了解决这个误差可以使用 fabs(a-b)<FloatError 这样的办法解决
但是这个办法也不完善,因为FloatError的数值不好确定
这里有两个原因
A) FloatError没有考虑到A和B的大小,对于很小的数来说,FloatError还是很大的,对于特别大的数的时候FloatError又太小了。
B) 对于很大的浮点数,存在一个现象,比如10000这么大的数,你无法用浮点数精确表达9999。9999999这样的数据,只能表达到9999,9998左右,这个时候FloatError小于0.002的时候更本就等价于A=B这样的判断
上述各个问题产生的原因实际上是因为我们使用了绝对误差,
为了解决这个问题,应该引入相对误差判断才是

3 相对误差判断方法
if ( fabs((A-B)/B)< RelError ) ....
这样其实还是不好,为了更精确应该改造为
if fabs(A)> fabs(b)
if ( fabs((A-B)/A)< RelError ) ....
else
if ( fabs((A-B)/A)< RelError ) ....
这样相对才完备一些。

但是在有的时候,仅仅使用相对误差也不合理, 还需要和绝对误差结合使用

4 相对误差和绝对误差的合并判断
同时进行相对误差和绝对误差判断,满足其中一个就认为相等,这样才安全

根据这个东西改造出了共线判断的实用算法
实际上就是 A/B = C/D 转换为a*d == b*c 的浮点相等判断而已
mathe 2005-01-31
  • 打赏
  • 举报
回复
比如p2在p1,p3之间,我们可以计算p3到直线p1p2的垂足q,然后看p3是否是最接近q的整数点:)
寻开心 2005-01-31
  • 打赏
  • 举报
回复
终于看到有点价值的答复了 :)
维埃里的说法: 精度是没有绝对,放大镜下查看在不在线的问题

理论上判定三点是否共线的方法非常很多,但是要放到工程当中是否适用是另外 一回事。
因为这个问题比较特殊就在于是任意三点(也许有重复点),而且有意隐藏了共线的精度应该是多大的问题。
希望能够看到具体的算法
AdenPlus 2005-01-30
  • 打赏
  • 举报
回复
我感觉3个点只能组成一个平面。所以我认为3D和2D的计算方法和计算量应该是一样的,因为你的2D下三点共线就是在一个假设的平面中完成的。

共线我认为判断两个矢量的叉积为0应该是可以的,精度问题我觉得只要多试几个不同的实际情况,把精度控制在只要是小数点后6位或8位直接忽略后等于0就行了。

还有我觉得绝对的精度是没有的,因为我们大部分人是搞工程的,不是搞理论科学的,所以我觉得就是一个效率和精度的平衡问题了,实际情况下就算肉眼看是共线,放大镜下看还是不共线,你能说这三个点就是不共线吗?
timgreen 2005-01-29
  • 打赏
  • 举报
回复
jlfuhappy(石头) 的加一点
只看(p3.x-p1.x ) * (p2.y-p1.y) - (p3.y-p1.y)*(p2.x-p1.x) == 0还只能说明在一个面上 (或者说一个方向的投影为共线)
再看看(p3.x-p1.x ) * (p2.z-p1.z) - (p3.z-p1.z)*(p2.x-p1.x) == 0就好
yliang 2005-01-29
  • 打赏
  • 举报
回复
注意两点:
1、不管用什么方法,但就是不能直接使用斜率,因为斜率可能很大;
2、如果理论计算结果是0,计算结果一般不会直接与0比较,通常是计算结果的绝对值与一个绝对值较小的数(如著名的AutoCAD很多时候的取值是:1e-6)比较。
yliang 2005-01-29
  • 打赏
  • 举报
回复
对我上面提供的算法,实际编程时,首先应该判断是否有重复点,如果没重复点时应该将V1,V2单位化
(归一化,标准化)后再算叉积分量
yliang 2005-01-29
  • 打赏
  • 举报
回复
设三维中的三点为P1,P2,P3;
P1到P2的向量为:V1=P2-P1;
P1到P3的向量为:V2=P3-P1;
如果P1,P2,P3在同一直线,则V1与V2的夹角为0或PI,所以
V1与V2的叉积的模为:|V1xV2|=0;
即有:
V1.Y*V2.Z-V1.Z*V2.Y=0,
V1.Z*V2.X-V1.X*V2.Z=0,
V1.X*V2.Y-V1.Y*V2.X=0.
jlfuhappy 2005-01-28
  • 打赏
  • 举报
回复
其实2D和3D是一样的 问题,根本不用区分2D和3D1!!
(p3.x-p1.x ) * (p2.y-p1.y) - (p3.y-p1.y)*(p2.x-p1.x) 判断是否等于0 即可!!
加载更多回复(22)

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧