两条线之间的内角
我有两条线路:Line1 和 Line2。每条线由两个点 (P1L1(x1, y1), P2L1(x2, y2)
和 P1L1(x1, y1), P2L3(x2, y3))
定义。我想知道这两条线定义的内角。
为此,我计算每条线与横坐标的角度:
double theta1 = atan(m1) * (180.0 / PI);
double theta2 = atan(m2) * (180.0 / PI);
在知道角度后,我计算以下内容:
double angle = abs(theta2 - theta1);
我遇到的问题或疑问是:有时我得到正确的角度,但有时我得到互补的角度(对于我来说,外部)。我怎么知道什么时候减去180°
才能知道内角?有没有更好的算法可以做到这一点?因为我尝试了一些方法:点积, 以下公式:
result = (m1 - m2) / (1.0 + (m1 * m2));
但我总是遇到同样的问题;我从来不知道我什么时候有外角或内角!
I have two lines: Line1 and Line2. Each line is defined by two points (P1L1(x1, y1), P2L1(x2, y2)
and P1L1(x1, y1), P2L3(x2, y3))
. I want to know the inner angle defined by these two lines.
For do it I calculate the angle of each line with the abscissa:
double theta1 = atan(m1) * (180.0 / PI);
double theta2 = atan(m2) * (180.0 / PI);
After to know the angle I calculate the following:
double angle = abs(theta2 - theta1);
The problem or doubt that I have is: sometimes I get the correct angle but sometimes I get the complementary angle (for me outer). How can I know when subtract 180º
to know the inner angle? There is any algorithm better to do that? Because I tried some methods: dot product,
following formula:
result = (m1 - m2) / (1.0 + (m1 * m2));
But always I have the same problem; I never known when I have the outer angle or the inner angle!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我认为您正在寻找的是 内部产品 (您可能还想查看两个角度的点积条目)。在你的情况下,这是由以下给出的:
答案以弧度为单位。
编辑:这是一个完整的实现。将有问题的值替换到 p1、p2 和 p3 中,然后让我知道您得到的结果。根据您对两条线的定义,点 p1 是两条线相交的顶点。
上面的代码产生:
I think what you're looking for is the inner product (you may also want to look over the dot product entry) of the two angles. In your case, that's given by:
Answer is in radians.
EDIT: Here's a complete implementation. Substitute the problematic values in p1, p2, and p3 and let me know what you get. The point p1 is the vertex where the two lines intersect, in accordance with your definition of the two lines.
The code above yields:
这样它就永远是内角。得到结果后添加即可。
That way it will always be the inner angle. Just add it after you get result.
如果您想要介于 0 度到 360 度之间的角度,请使用以下代码;其经过全面测试且功能齐全:
}
注意: 旋转将为顺时针方向;
If you want in between angle in 0 degree to 360 degree then use following code; Its fully tested and functional:
}
Note: Rotation will be clockwise;
整点比给出的答案容易得多:
当您使用 atan(slope) 时,您会丢失(字面意思)一点信息,即在范围 (0. .2*PI),它为函数 tan() 提供相同的值。
只需使用 atan2(deltax, deltay) 即可获得正确的角度。例如
然后减去,取绝对值,如果大于PI则从2*PI中减去。
The whole point is much easier than the given answers:
When you use atan(slope) you lose (literally) one bit of information, that is there are exactly two angles (theta) and (theta+PI) in the range (0..2*PI), which give the same value for the function tan().
Just use atan2(deltax, deltay) and you get the right angle. For instance
Then subtract, take absolute value, and if greater than PI subtract from 2*PI.
2 个向量之间的内角 (v1, v2) = arc cos ( 内积 (v1,v2) / (module(v1) * module(v2)) )。
其中内积(v1,v2) = xv1*xv2 + yv1*yv2
module(v) = sqrt(pow(xv,2) + pow(yv,2))
因此,您的问题的答案是在以下示例中实现的:
Inner angle between 2 vectors (v1, v2) = arc cos ( inner product(v1,v2) / (module(v1) * module(v2)) ).
Where inner product(v1,v2) = xv1*xv2 + yv1*yv2
module(v) = sqrt(pow(xv,2) + pow(yv,2))
So, the answer of your question is implemented on the following example:
如果您使用绝对值,您将始终得到锐角。即切线 theta = m1-m2 在 (1 +m1 * m2) 上的绝对值。如果您采用反正切,则无论计算器如何设置,您的答案都将以弧度或度为单位。抱歉,这不是编程术语,我是数学老师,不是程序员......
If you use abolute value you will always get the acute angle. That is tangent theta = abs value of m1-m2 over (1 +m1 * m2). If you take inverse tangent your answer will be in radians or degrees however the calculator is set. Sorry this isnt programming lingo, I am a math teacher, not a programmer...
获得外角与内角完全取决于减法的顺序(想一想)。您需要从较大的 theta 中减去较小的 theta,以便始终可靠地获得内角。由于您期望的数据类型,您可能还想使用
atan2
函数。Getting the outer angle vs the inner angle is determined entirely by the order of your subtractions (think about it). You need to subtract the smaller theta from the larger in order to reliably always get the inner angle. You also probably want to use the
atan2
function because of the type of data you're expecting.我希望我正确理解你的问题,因为想要两条线相交的锐角而不是钝角。我说得对吗?
相交的锐角和钝角互为 180 度余角。即
http://www.mathworks.com/access/helpdesk /help/techdoc/ref/atan.html
证明 atan 在 +/- pi/2 处渐近。
因此,atan 的两个结果之间的最大差异是 pi 或 180 度,无论您使用梯度的
+/-
表示法还是正的0 到 pi
表示法。考虑以下伪代码:
函数
acuteAngle
从数学角度说明了您需要执行的操作。然而,它不能用于 PI/2 邻域中的角度值,因为无论表示钝角还是锐角,角度与该邻域中结果的二元比较都是有问题的。
因此,我们必须比较两条线的点的坐标。
我们找出由
[(x2,y2)(x3,y3)]
组成的第三条线是否比假设的斜边短、等于或长。凭借毕达哥拉斯定理,
如果角度恰好为 PI/2 或 90 度,则会形成斜边。我们把他假设的斜边线称为 L3Hypo。
通过头脑中的几何可视化,
L3Hypo,钝角。
因此,
因此,下面的伪代码,
假设你已经有了这个功能
getGradient(Point P, Q):
我可能在伪代码中犯了一些拼写错误(希望没有),但我演示了这个概念的要点。如果是这样,有人可能会很友善地编辑掉拼写错误。
进一步
然而,经过深思熟虑,我发现由于指令的原因,精确度的斗争集中在其最薄弱的环节
,所以,我们不妨省去所有麻烦,简单地这样做:
I hope I understand your question correctly as wanting the acute angle rather than the obtuse angle of the intersection of two lines. Am I correct?
Acute and obtuse angles of an intersection are 180 deg complements of each other. i.e.
http://www.mathworks.com/access/helpdesk/help/techdoc/ref/atan.html
exhibits that an atan is asymptotic at +/- pi/2.
Therefore, the max difference between two results of atan is pi or 180 deg, whether you use the
+/-
notation or positive0 to pi
notation of a gradient.Consider the following pseudocode:
The function
acuteAngle
illustrates what you need to do, mathematically.However, it cannot be used for values of angles in the neighbourhood of PI/2 because binary comparisons of angles with results in that neighbourhood is questionable whether an obtuse or acute angle is represented.
Therefore, we have to compare the coordinates of the points of the two lines.
We find out whether the 3rd line formed from
[(x2,y2)(x3,y3)]
is shorter, equal or longer than the hypothetical hypotenuse.By virtue of Pythagoras' theorem,
A hypotenuse is formed if the angle is exactly PI/2 or 90 deg. Let's call his hypothetical hypotenuse line L3Hypo.
By geometrical visualisation in your mind,
L3Hypo, the angle is obtuse.
Therefore,
Therefore, the following pseudo-code,
Presuming you already have the function
getGradient(Point P, Q):
I may have committed some typo mistakes in the pseudo-code (hopefully not) but I demonstrated the gist of the concept. If so, someone could be so kind to edit away the typos.
Further
However, after mulling over it, I find that the struggle for precision pivots on its weakest link due to the directive
So, we might as well save all the trouble and simply do this: