Math 比较两个角度
给定平面上的四个点,Math 比较两个角度,math,vector,geometry,Math,Vector,Geometry,给定平面上的四个点,A、B、X、Y,我想确定以下两个角度中哪一个更小∢ABX或∢ABY 角度∢ABX定义为BX的角度,当AB转换为位于开放段(-∞,0]。说∢ABX我是指在访问顶点B后左转时得到的角度 我宁愿不使用cos或sqrt,以保持准确性并最小化性能(代码将在嵌入式系统上运行) 在A=(-1,0),B=(0,0)的情况下,我可以比较两个角度∢ABX和∢ABY,通过计算向量的点积X,Y,并观察其符号 在这种情况下,我能做的是: 确定ABX是否向右或向左转弯 如果ABX左转,检查Y和A是否在线
A、B、X、Y
,我想确定以下两个角度中哪一个更小∢ABX
或∢ABY
角度∢ABX
定义为BX
的角度,当AB
转换为位于开放段(-∞,0]
。说∢ABX
我是指在访问顶点B
后左转时得到的角度
我宁愿不使用cos
或sqrt
,以保持准确性并最小化性能(代码将在嵌入式系统上运行)
在A=(-1,0),B=(0,0)
的情况下,我可以比较两个角度∢ABX
和∢ABY
,通过计算向量的点积X,Y
,并观察其符号
在这种情况下,我能做的是:
ABX
是否向右或向左转弯ABX
左转,检查Y
和A
是否在线段BX
的同一侧。如果是-∢ABX
是一个小于ABY的值ABX
右转,则Y
和A
在BX
的同一侧,表示∢ABX
大于∢ABY
你需要注意的是“更小”的含义。这个概念并不像前面所说的那样精确。例如,如果一个点A位于象限4(x分量>0,y分量<0),而另一个点B位于象限1(x分量>0,y分量>0),那么“更小”是什么意思平均值?向量从原点到A的角度在0到π/2之间;向量从原点到B的角度在3π/4到2π之间。哪个更小?使用余弦定律:
A**2+B**2-2*A*B*cos(φ)=c**2
式中,a=| ax |,b=| bx |(| by |),c=| ab |(| ay |),φ是角度ABX(ABY)通过执行以下操作将原点置于b的中心
X = X - B
Y = Y - B
A = A - B
编辑:还需要对3个向量进行归一化
A = A / |A|
X = X / |X|
Y = Y / |Y|
通过这样做找到两个角度
acos(A dot X)
acos(A dot Y)
===
我不明白精度损失的原因。你只是在比较,而不是以任何方式修改点的坐标…这里有一些伪代码。当两个角度相同时,不会检测到这种情况。也不会处理角度方向,例如,假设所有角度都为0) if(dot2<0) //ABX更小 if(dot1*dot1/dot(v1,v1)>dot2*dot2/dot(v2,v2)) //ABX更小 //ABY更小 如果(dot2>0) //ABY更小 if(dot1*dot1/dot(v1,v1)>dot2*dot2/dot(v2,v2)) //ABY更小 //ABX更小
请注意,如果你允许取两个平方根,这种痛苦的大部分就会消失。我不确定你是否可以不使用sqrt而逃脱。 简单:
AB=A-B/| A-B|
XB=X-B/| X-B|
YB=Y-B/| Y-B|
if(点(XB,AB)>点(YB,AB)){
// 你可能想看看。距离和角度的概念被四边形和扩展所取代,它们不涉及sqrt
和cos
。查看网页底部,了解如何计算两条线之间的扩展。主题有自己的网站,甚至有a。你假设a和X的大小是1(或彼此的倒数)。A和Y也是如此。没有sqrt,你如何获得这些距离?必须放弃“无平方根”的想法。你不需要sqrt。你可以比较cos(phi1)和cos(phi2)。两者中的较大者就是较大的角度。真的吗?对于x=0时的不连续性,你会怎么做?你需要sqrt来计算2*a*b
项(你需要这样做来求解cos(phi)
)。另外,cos(phi1)
,cos(phi2)中的较大者
将对应于较小的角度。请注意,只有当您的位置已经准确知道时(例如,表示为整数或有理数),才有意义保持准确性。但避免平方根还有其他合理的原因,即性能。我在问题中描述了一种不使用平方根的方法。我将很高兴听到为什么我的方法不起作用。这是一个很好的观点。角度∢ABX
定义为当AB
转换为位于开放段上时BX
的角度(-∞,0]。直观地说,我指的是在访问顶点B
后左转时的角度ABX
。Cos是一个近似值,因此,是的,除了这些操作的高成本外,还损失了一些精度。此外,他只需要单调函数,而不需要值本身。
v0 = A-B
v1 = X-B
v2 = Y-B
dot1 = dot(v0, v1)
dot2 = dot(v0, v2)
if(dot1 > 0)
if(dot2 < 0)
// ABX is smaller
if(dot1 * dot1 / dot(v1,v1) > dot2 * dot2 / dot(v2, v2) )
// ABX is smaller
// ABY is smaller
if(dot2 > 0)
// ABY is smaller
if(dot1 * dot1 / dot(v1,v1) > dot2 * dot2 / dot(v2,v2) )
// ABY is smaller
// ABX is smaller
AB = A-B/|A-B|
XB = X-B/|X-B|
YB = Y-B/|Y-B|
if(dot(XB,AB) > dot (YB,AB)){
//<ABY is grater
}
else
{
...
}