如果两个线段重叠或相交,则将它们合并在同一圆上 [英] Combine two segments on the same circle if they overlap or intersect
问题描述
如果两个部分重叠或相交,我会尝试合并.我的问题类似于此一个>.但是,我要结合两个部分.
I am try to combine two segments if they overlap or intersect.My question is similar to this and this. However, what I want is to combine two segments.
public class Segment
{
private readonly double _from;
private readonly double _to;
public Segment(double from, double to)
{
_from = Normalize(from); // 0 <= x < 360
_to = Normalize(to);
}
public bool Inside(double target)
{
if (_from < _to)
return _from <= target && target <= _to;
return _from <= target || target <= _to;
}
}
我正在尝试写一个TryCombine()
.
public bool TryCombine(Segment other, out Segment result)
{
// if not intersect
// return false
// else if overlap
// return true, out larger one
// else if intersect
// return true, out a new one with merged bound
}
预期结果
var seg1 = new Segment(0, 100);
var seg2 = new Segment(50, 150);
var seg3 = new Segment(110, -100);
var seg4 = new Segment(10, 50);
Segment result;
seg1.TryCombine(seg2, result); // True, result = Segment(0, 150)
seg1.TryCombine(seg3, result); // False
seg1.TryCombine(seg4, result); // True, result = Segment(0, 100)
seg2.TryCombine(seg3, result); // True, result = Segment(260, 150)
推荐答案
您可以在第二个链接中使用我的答案中所述的方法.
You can use approach described in my answer in you second link.
ma = (a2 + a1)/ 2
mb = (b2 + b1)/ 2
cda = Cos(da)
cdb = Cos(db)
要检查交叉点是否存在以及发生哪种类型的交叉点,请找到4个布尔值
To check whether intersection exists and what kind o intersection takes place, find 4 boolean values
BStartInsideA = (Cos(ma - b1) >= cda)
BEndInsideA = (Cos(ma - b2) >= cda)
AStartInsideB = (Cos(mb - a1) >= cdb)
AEndInsideB = (Cos(mb - a2) >= cdb)
这些组合可能形成16种可能的结果(并非所有结果都是可靠的).我将这些结果组合为4位值的位,并在case
语句中对其进行处理.
These combinations could form 16 possible results (not all are reliable). I'd combine these results as bits of 4-bit value and treat them in the case
statement.
例如,如果第一个和最后一个值均为true(值0b1001 = 9
),则您具有类似于seg1-seg2情况的简单交集-因此获得AStart ans起点,BEnd作为终点并将其标准化(添加360如果小于AStart,则返回BEnd).
For example, if the first and the last values are true (value 0b1001 = 9
), you have simple intersection like your seg1-seg2 case - so get AStart ans starting point, BEnd as ending point and normalize them (add 360 to BEnd if it is less than AStart).
预规范化步骤应提供BEnd> = BStart和AEnd> = AStart(例如,将(3,1)弧转换为具有中点182和半角179的(3,361)
Pre-normalization step should provide BEnd>=BStart and AEnd>=AStart (for example, transform (3,1) arc into (3, 361) with middle point 182 and semi-angle 179)
可能的结果(两个额外的案例,4个简单的最终组合,4个单端一致的案例):
Possible results (two extra cases, 4 simple end combinations, 4 one-end coinciding cases):
0000: no intersection
1111: full circle
0011: AStart-AEnd
1001: AStart-BEnd
0110: BStart-AEnd
1100: BStart-BEnd
0111: AStart-AEnd
1011: AStart-AEnd
1110: BStart-BEnd
1101: BStart-BEnd
一位组合和1010,0101看起来不可能
One-bit combinations and 1010, 0101 look impossible
使用通配符,如作者建议的那样:
with wildcards, as author proposed:
At first check for
0000: no intersection
1111: full circle
then
**11: AStart-AEnd
1001: AStart-BEnd
0110: BStart-AEnd
11**: BStart-BEnd
这篇关于如果两个线段重叠或相交,则将它们合并在同一圆上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!