我有三个向量V1,V2和V3。他们的起源点在轴的起源上。当我从V1逆时针移动到V2时,如何确定V3是否介于V1和V2之间?
alt text http://www.freeimagehosting.net/uploads/1448ea8896.jpg
无法通过获取角度和评估这些条件(伪代码)来完成:
if angle(V3) > angle(V1) && angle(V3) < angle(V2)
printf("V3 is between V1 and V2")
else
printf("out of the interval")
要查看其缺陷,假设angle
函数给出了[-pi pi]范围内的角度。因此,如果角度(V1)= 120(度),角度(V2)= -130,角度(V3)= 150,那么答案(根据上面的代码)是“超出间隔”,但如果你四处走动逆时针从V1到V2,它们介于它们之间。
您可能会建议将2 * pi添加到角度(V2)或类似的东西,但我已尝试过这样的东西而且它不起作用。
我在MATLAB中编程。
编辑1:它是2D。
答案 0 :(得分:8)
由于您是在MATLAB中执行此操作,因此这是一个应该有效的解决方案:
crossProds = [V1(1)*V2(2)-V1(2)*V2(1) ...
V1(1)*V3(2)-V1(2)*V3(1) ...
V3(1)*V2(2)-V3(2)*V2(1)];
if (all(crossProds >= 0) || ...
(crossProds(1) < 0) && ~all(crossProds(2:3) < 0)),
disp("V3 is between V1 and V2");
else
disp("out of the interval");
end
<强>说明强>
二维矢量 V1 和 V2 之间的叉积存储在 crossProds 的第一个元素中。如果 V1 和 V2 之间的逆时针角度介于0和180度之间(包括0和180度),则此值将大于或等于零。在这种情况下,当 V3 在 V1 和 V2 之间逆时针方向时,则交叉积(V1,V3) 和(V3,V2)也大于或等于零。这解释了第一次逻辑检查:
all(crossProds >= 0)
如果 V1 和 V2 之间的逆时针角度大于180度,则这两个矢量的叉积将小于零。在这种情况下,当 V3 在顺时针方向上 V1 和 V2 之间时,交叉产品 (V1,V3)和(V3,V2)也小于零。因此,如果这些交叉产品不都小于零,则 V3 必须介于 V1 和 V2 之间逆时针方向。这解释了接下来的两个逻辑检查:
(crossProds(1) < 0) && ~all(crossProds(2:3) < 0)
上述逻辑检查应涵盖所有可能的情况。运营商||和&amp;&amp;在MATLAB中是short circuit operators:如果没有必要,他们将跳过第二个语句。例如,如果OR中的第一个语句为true,则没有理由检查第二个语句,因为OR中只有一个参数必须为true才能使结果为真。
答案 1 :(得分:3)
计算角度(V1),角度(V2)和角度(v3)(a1,a2,a3)。
修改a2和a3(如果需要,添加2 * pi)以便
a1 <= a2 < a1 + 2*pi
a1 <= a3 < a1 + 2*pi
现在你只需要比较a2和a3。 V3在V1和V2之间,导致a3低于a2。
答案 2 :(得分:2)
V1是红鲱鱼。你只是想让自己混淆一下三个角度。
现在问题只是比较规范(角度(V2) - 角度(V1))和规范(角度(V3) - 角度(V1))。
答案 3 :(得分:0)
对于大多数其他编程语言来说,这是一种更简单的方法。
如果给出V1,V2和V3矢量,我们需要确定天气V3在V1和V2之间,Ri = atan2(Vi)(从-pi到pi返回弧度的角度):
<强>顺时针强>:
R1 -= R3;
R2 -= R3;
if (R1 < 0) R1 += 2 * PI;
if (R2 <= 0) R2 += 2 * PI;
return (r1 < r2);
对于逆时针,只需交换R1和R2。
答案 4 :(得分:-2)
要测试这种情况,你必须计算两个三角形的缠绕:
由V1,原点和V3组成的三角形。这个三角形必须是逆时针方向。
V3形成的三角形,原点和V2。这个三角形也必须是逆时针方向。
为了测试三角形的缠绕,足以检查顶点的2D交叉积的符号。
测试看起来像这样(对不起 - C代码):
int IsBetween (vector v1, vector v2, vector v3)
{
float winding1 = (v1.x * v3.y - v1.y * v3.x);
float winding2 = (v3.x * v2.y - v3.y * v2.x);
// this test could be exactly the wrong way around. This depends
// on how you define your coordinate system (e.g. is Y going up or down?)
if ((winding1 <0) && (winding2 < 0))
{
printf ("V3 is between them\n");
}
else
{
printf ("it's not\n");
}
}