逆时针从V1到V2时,如何判断V3是否介于V1和V2之间?

时间:2009-03-28 23:52:24

标签: matlab vector geometry angle

我有三个向量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。

5 个答案:

答案 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是红鲱鱼。你只是想让自己混淆一下三个角度。

  1. 顺时针旋转所有内容(V1)
  2. 将剩余的两个角度归一化为[0,360]
  3. 现在问题只是比较规范(角度(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)

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

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

  2. V3形成的三角形,原点和V2。这个三角形也必须是逆时针方向。

  3. 为了测试三角形的缠绕,足以检查顶点的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");
      }
    }