我正试图找到一种计算两个弧之间交点的方法。 我需要使用它来确定一个圆的右半部分有多少圆弧,左边多少。 我虽然关于创建右半部分的弧线,并将其与实际弧线相交。 但是我花了很多时间来解决这个问题,所以我想在这里问 - 有人必须在此之前做过。
编辑: 对不起前面的插图是在我的头部在嘎吱嘎吱的角度后太沉重的情况下提供的。我会再试一次解释一下:
在this link中你可以看到我将弧线中间切成两半,弧的右边部分包含135度,左边部分有90度。
此Arc从-180开始并以45结束。(或者从180开始,如果标准化则结束于405)。
我设法创建此代码以计算右侧部分和左侧部分中包含的弧度数量:
f1 = (angle2>270.0f?270.0f:angle2) - (angle1<90.0f?90.0f:angle1);
if (f1 < 0.0f) f1 = 0.0f;
f2 = (angle2>640.0f?640.0f:angle2) - (angle1<450.0f?450.0f:angle1);
if (f2 < 0.0f) f2 = 0.0f;
f3 = (angle2>90.0f?90.0f:angle2) - angle1;
if (f3<0.0f) f3=0.0f;
f4 = (angle2>450.0f?450.0f:angle2) - (angle1<270.0f?270.0f:angle1);
if (f4<0.0f) f4=0.0f;
将角度标准化为非负值后效果很好,但当然低于360度。 然后f1 + f2给出了左半部分的总和,f3 + f4给出了右半部分的总和。 它也没有考虑将弧定义为360以上的情况,这可能是一个“错误”的情况。
但是,这似乎更像是一种“解决方法”,而不是一种正确的数学解决方案。 我正在寻找一个更优雅的解决方案,它应该基于两个弧之间的“交叉点”(因为数学没有“侧面”,它不是视觉“;
谢谢!
答案 0 :(得分:2)
我认为这有效,但我没有彻底测试过。你有2个弧,每个弧有一个起始角和一个停止角。我会按照从北方顺时针方向测量的度数来完成这项工作,但是就像数学家那样从东方逆时针方向测量的弧度也很容易。
首先'标准化'你的弧线,也就是说,将它们中的所有角度减少到[0,360)
,所以取出360度的倍数并使所有角度+ ve。确保每个弧的停止角度位于起始角度的顺时针方向。
接下来,选择其中一个弧的起始角度,无关紧要。将您拥有的所有角度(其中4个)按数字顺序排序。如果任何角度在数值上小于您选择的起始角度,则向它们添加360度。
将角度重新排序为增加的数字顺序。您选择的起始角度将是新列表中的第一个元素。从您已选择的起始角度开始,列表中的下一个角度是什么?
1)如果是同一弧的停止角,那么要么没有重叠,要么这个弧完全包含在另一个弧内。做一个笔记,找到下一个角度。如果下一个角度是另一个弧的起始角度,则没有重叠,您可以停止;如果它是另一个弧的停止角,则重叠包含整个第一弧。停止
2)如果是另一个弧的起始角,则重叠从该角开始。记下这个角度。扫描遇到的下一个角度必须是一个停止角度,重叠在那里结束。停止。
3)如果是另一个圆弧的停止角,则重叠包括第一个圆弧的起始角度与该角度之间的角度。停止。
这不是特别优雅,并且依赖于ifs而不是我喜欢的但它应该工作并且相对容易翻译成您喜欢的编程语言。
看,根本没有三角学!
修改强>
这是一种更“数学”的方法,因为你似乎觉得有必要。
对于(-pi,pi]
中的双角正弦函数(通常称为sinh
)中的角度θ,将角度映射到区间(大约)(-11.5,11.5]
中实线上的区间。与arcsin
和arccos
不同,此函数的反函数在同一区间也是单值的。请按照以下步骤操作:
1)如果一个弧包含0,则将其分为2个弧,(start,0)
和(0,stop)
。你现在在实线上有2个,3个或4个区间。
2)计算这些间隔的交集并从线性测量转换回角度测量。你现在有两个弧的交集。
答案 1 :(得分:1)
可以使用单线测试恢复此测试。即使已经发布了一个好的答案,让我介绍一下。
假设第一个弧是A:(a0,a1)
,第二个弧是B:(b0,b1)
。我假设角度值是唯一的,即在[0°,360°[
,[0,2*pi[
或]-pi,pi]
范围内(范围本身并不重要,我们将看到原因)。我将范围]-pi,pi]
作为所有角度的范围。
为了详细解释这种方法,我首先在 R 中设计区间交叉的测试。因此,我们在这里a1>=a0
和b1>=b0
。对于实际间隔使用相同的符号,我计算以下数量:
S = (b0-a1)*(b1-a0)
如果S>0
,则两个段不重叠,否则它们的交集不为空。确实很容易理解为什么这个公式有效。如果S>0
,我们有两种情况:
b0>a1
表示b1>a0
,因此没有交集:a0=<a1<b0=<b1
。
b1<a0
表示b0<b1
,因此没有交集:b0=<b1<a0=<a1
。
所以我们有一个数学表达式,在 R 中表现良好。
现在我在圆形域]-pi,pi]
上展开它。假设a0<a1
和b0<b1
不再适用:例如,弧可以从pi/2
转到-pi/2
,它是左半圆。
所以我计算了以下数量:
S = (b0-a1)*(b1-a0)*H(a1-a0)*H(b1-b0)
其中H是由H(x)=-1 if x<0 else H(x)=1
同样,如果S>0
,弧A和B之间没有交叉。有16个案例要探索,我不会在这里做到这一点......但很容易在一张纸上做出来:)
备注:S的值并不重要,只是条款的标志。这个公式的美妙之处在于它与您所采用的范围无关。此外,您可以将其重写为逻辑测试:
T := (b0>a1)^(b1>a0)^(a1>=a0)^(b1>=b0)
其中^
是逻辑XOR
修改强>
唉,这个公式中有一个明显的失败案例...所以我在这里纠正它。我意识到htere是两个弧的交点可以是两个弧的情况,例如-pi<a0<b1<b0<a1<pi
时。
解决这个问题的方法是引入第二个测试:如果角度之和高于2*pi
,则弧线肯定会相交。
所以公式结果是:
T := (a1+b1-a0-b0+2*pi*((b1<b0)+(a1<a0))<2*pi) | ((b0>a1)^(b1>a0)^(a1>=a0)^(b1>=b0))
好吧,它不像前一个那么优雅,但它现在是正确的。