6

我有三个向量 V1、V2 和 V3。它们的原点位于轴的原点上。当我从 V1 逆时针移动到 V2 时,如何确定 V3 是否在 V1 和 V2 之间?

替代文字 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] 的范围内。因此,如果 angle(V1) = 120 (in degree), angle(V2) = -130 and angle(V3) = 150 那么答案(根据上面的代码)是“超出区间”,尽管如果你四处走动从 V1 到 V2 逆时针,它在它们之间。

您可能会建议将 2*pi 添加到 angle(V2) 或类似的东西,但我已经尝试过这样的事情并且它不起作用。

我正在用 MATLAB 编程。

编辑 1:它是 2D 的。

4

5 回答 5

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

解释:

二维向量V1V2之间的叉积存储在crossProds的第一个元素中。如果V1V2之间的逆时针角度在 0 到 180 度之间(包括 0 到 180 度),则该值将大于或等于 0。在这种情况下,当V3在逆时针方向上位于V1V2之间时,叉积(V1,V3)(V3,V2)也大于或等于零。这解释了第一个逻辑检查:

all(crossProds >= 0)

如果V1V2之间的逆时针角度大于 180 度,则这两个向量的叉积将小于零。在这种情况下,当V3顺时针方向上位于V1V2之间时,叉积(V1,V3)(V3,V2)也小于零。因此,如果这些叉积小于零,则V3必须在逆时针方向上位于V1V2之间。这解释了接下来的两个逻辑检查:

(crossProds(1) < 0) && ~all(crossProds(2:3) < 0)

上述逻辑检查应涵盖所有可能的情况。运营商 || 和 && 是MATLAB 中的短路运算符:如果不需要,它们将跳过第二个语句。例如,如果 OR 中的第一个语句为真,则没有理由检查第二个语句,因为 OR 中只需要一个参数为真,结果为真。

于 2009-03-29T01:51:26.190 回答
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。

于 2009-03-29T00:01:27.780 回答
2

V1 是一个红鲱鱼。你只会让自己同时考虑 3 个角度而感到困惑。

  1. 将所有内容顺时针旋转角度(V1)
  2. 将剩余的两个角度归一化为 [0,360)

现在的问题只是比较范数(角度(V2)-角度(V1))和范数(角度(V3)-角度(V1))。

于 2009-03-29T02:59:21.097 回答
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。

于 2014-12-06T13:47:21.210 回答
-2

要测试这种情况,您必须计算两个三角形的绕组:

  1. 由 V1、原点和 V3 组成的三角形。这个三角形必须是逆时针的。

  2. 由 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");
  }
}
于 2009-03-29T00:55:22.703 回答