两个矢量之间的角度反射? (C#)

时间:2016-03-13 15:07:15

标签: c# trigonometry angle triangulation triangular

我需要能够检查构成形状一部分的三个点(A,B和C)之间的角度是否是反射(> PI弧度),如下图所示(对不起油漆技巧不好) !):

Angle ABC

我的点应该始终是逆时针的,我总是想测量形状内部的角度

我目前正在使用以下代码执行此操作:

//triangle[] is an array of the three points I am testing, corresponding
// to [A, B, C] on the diagram above

//Vectors from B to A and C
PointF toA = PointFVectorTools.difference(triangle[0], triangle[1]);
PointF toC = PointFVectorTools.difference(triangle[2], triangle[1]);

double angle = Math.Atan2(toB.Y, toB.X) - Math.Atan2(toA.Y, toA.X);

//Put angle in range 0 to 2 PI
if (angle < 0) angle += 2 * Math.PI;
return angle > Math.PI;

这在我迄今为止尝试的所有案例中都有用,但是这些合作伙伴不起作用: enter image description here

(其中B =(2,3))

我回来的角度是〜-0.5,而我期望〜+ 0.5。任何想法为什么这是错误的?

更新

我试图实现Nico的解决方案,虽然理论上我理解它但是我正在努力实现它。这是迄今为止的代码:

//Vector A -> B
float dx = triangle[1].X - triangle[0].X;
float dy = triangle[1].Y - triangle[0].Y;

//Left normal = (y, -x)
PointF leftDir = new PointF(dy, -dx);

//Vector B -> C
dx = triangle[2].X - triangle[1].X;
dy = triangle[2].Y - triangle[1].Y;

//Dot product of B->C and Left normal
float dot = dx * leftDir.X + dy * leftDir.Y;
return dot < 0;

2 个答案:

答案 0 :(得分:1)

我不确定代码中的toB是如何定义的,而且我也不熟悉PointF

无论如何,你应该使用余弦规则c^2 = a^2 + b^2 - 2ab cos(C)(其中a,b,c是三角形边长,C是对向c的角度:< / p>

public bool IsReflex(... triangle)
{
    var a = GetVectorLength(triangle[0].x, triangle[0].y, triangle[1].x, triangle[1].y);
    var b = GetVectorLength(triangle[1].x, triangle[1].y, triangle[2].x, triangle[2].y);
    var c = GetVectorLength(triangle[2].x, triangle[2].y, triangle[0].x, triangle[0].y);

    var cosC = (c*c - a*a - b*b) / (2*a*b);
    var C = Math.Acos(cosC); // this returns a value between 0 and pi

    return Math.Abs(C) > (Math.PI/2);
}

private double GetVectorLength(double x0, double y0, double x1, double y1)
{
    // using Pythagoras
    var sideX = x0 - x1;
    var sideY = y0 - y1;
    return Math.Sqrt(sideX*sideX + sideY*sideY);
}

答案 1 :(得分:1)

在下文中,我假设x轴指向右侧,y轴指向上方。如果在您的方案中不是这种情况,您可能需要切换一些标志。

如果您有线段(x1, y1) - (x2, y2)并且点是逆时针排序的,则您知道线段的左侧是形状。指向线段左侧的正交方向矢量是:

leftDir = (y1 - y2, x2 - x1)

与线段一起,此方向定义半空间。如果以下角度是凸的,则第三个点必须位于该半空间中。如果不是这种情况,角度是凹的(你显然称之为反射):

您可以使用点积确定点是否位于相同的半空间中:

isConcave = dot(p3 - p2, leftDir) < 0

在代码中:

float dx = x3 - x2;
float dy = y3 - y2;
float dot = dx * leftDir.x + dy * leftDir.y
return dot < 0;