2016-11-14 2 views
0

Я пытаюсь объединить два сегмента, если они пересекаются или пересекаются. Мой вопрос аналогичен this и this. Однако я хочу объединить два сегмента.Объедините два сегмента на одном круге, если они перекрываются или пересекаются

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) 

ответ

1

Вы можете использовать подход, описанный в моем ответе на вас второй ссылке.

ma = (a2 + a1)/ 2 
mb = (b2 + b1)/ 2 
cda = Cos(da) 
cdb = Cos(db) 

Чтобы проверить, существует ли пересечение и какие о пересечение происходит, найти 4 булевы значения

BStartInsideA = (Cos(ma - b1) >= cda) 
BEndInsideA = (Cos(ma - b2) >= cda) 
AStartInsideB = (Cos(mb - a1) >= cdb) 
AEndInsideB = (Cos(mb - a2) >= cdb) 

Эти комбинации могут образовывать 16 возможных результатов (не все надежны). Я бы объединил эти результаты как биты 4-битного значения и обработал их в операторе case.

Например, если первое и последнее значения истинны (значение 0b1001 = 9), у вас есть простое пересечение, такое как ваш случай seg1-seg2 - так что получите AStart ans отправную точку, BEnd в качестве конечной точки и нормализуйте их (добавьте 360 в BEnd, если он меньше AStart).

Предварительно нормализации шаг должен обеспечить Bend> = BStart и AEnd> = Astart (например, преобразование (3,1) в дугу (3, 361) со средней точкой 182 и полуприцепа углом 179)

Возможные результаты (два дополнительные корпуса, 4 простых комбинаций конца, 4 один конец совпадающих случаев):

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 

One-битовые комбинации и 1010, 0101 взгляд невозможно

с групповыми символами, предложенный автор:

+0

Проблема BStart внутри A и BEnd внутри A не подразумевает A перекрытие B., если A (0, 5) и B есть (3, 1), тогда результат должен быть полным. – Joshua

+0

Эта ситуация должна быть «поймана» во время «нормализации» – MBo

+0

Что вы имеете в виду под контролем во время нормализации? Можно подсчитать угол по часовой стрелке (0, 15) или против часовой стрелки (15, 0), который представляет собой два разных интервала. – Joshua

Смежные вопросы