Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using SegmentsAlgorythm;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Linq;
- using System.Threading.Tasks;
- namespace OutlineAlgorithm
- {
- public class NewOutlineProcessor
- {
- private List<Outline> outlines = new List<Outline>();
- private List<Segment> prioritySet = new List<Segment>();
- private EventComparator eventComparator = new EventComparator();
- private ByStartComparator byStartComparator = new ByStartComparator();
- public async Task addElement(Segment segment)
- {
- prioritySet.Add(segment);
- //перераспределяем отрезки на числовой прямой
- //p.s.Встроенные алгоритмы отлично оптимизированы - почти отсортированный массив пересортируется очень быстро
- //p.p.s.как ни велик соблазн положить сортировку в отдельный поток, без синхронизации нельзя
- prioritySet.Sort(byStartComparator);
- await FindOutline();
- Console.WriteLine("---Priority Set---");
- foreach (Segment seg in prioritySet)
- {
- Console.WriteLine(seg);
- }
- Console.WriteLine("---Result Set---");
- foreach (Outline outline in outlines)
- {
- Console.WriteLine(outline);
- }
- }
- private Task FindOutline()
- {
- return Task.Run(() =>
- {
- List<SweepLineEvent> activeSet = new List<SweepLineEvent>();
- //обыскивать активный набор
- foreach (Segment segment in prioritySet)
- {
- //добавление события - хороший момент для анализа, как и удаление
- SweepLineEvent segmentStartEvent;
- segmentStartEvent.POI = segment.start;
- segmentStartEvent.parent = segment;
- segmentStartEvent.TYPE = SweepLineEvent.START;
- SweepLineEvent segmentEndEvent;
- segmentEndEvent.POI = segment.end;
- segmentEndEvent.parent = segment;
- segmentEndEvent.TYPE = SweepLineEvent.END;
- activeSet.Add(segmentEndEvent);
- activeSet.Add(segmentStartEvent);
- activeSet.Sort(eventComparator);
- Console.WriteLine("---Active Set---");
- foreach (SweepLineEvent seg in activeSet)
- {
- Console.WriteLine(seg);
- }
- Console.WriteLine("---Sweep line cycle---");
- for (int i = 0; i < activeSet.Count; i++)
- {
- for (int j = 0; j < activeSet.Count; j++)
- {
- Console.WriteLine("Count = "+ activeSet.Count);
- Console.WriteLine("Точка интереса " + activeSet[i].POI + " рассматривается..");
- if (Math.Abs(activeSet[i].POI.X - activeSet[j].POI.X) < 0.001f && i>1)
- {
- //если равен х, то равен и у
- if (activeSet[i].POI.Y == activeSet[j].POI.Y)
- {
- AddOutline(activeSet[i].parent, activeSet[j].parent);
- Console.WriteLine("Новый контур обрабатывается..");
- }
- }
- //если это конец отрезка, значит, он ушёл из зоны видимости, ведь все события отсортированы
- //p.s. последний не считается - ситуация может изменится на следующей итерации
- bool isTheEnd = activeSet[i].TYPE == SweepLineEvent.END;
- if (isTheEnd && i!=activeSet.Count-1)
- {
- Console.WriteLine("Заметающая прямая больше не пересекает отрезок " + activeSet[i].parent);
- activeSet.RemoveAll(e => e.parent.Equals(activeSet[i].parent));
- }
- }
- }
- }
- });
- }
- private void AddOutline(Segment segment, Segment foundedSegment)
- {
- //исследование в уже существующем контуре
- Console.WriteLine("---исследование в уже существующем контуре---");
- Outline first = searchInOtherOutlines(segment);
- Outline second = searchInOtherOutlines(foundedSegment);
- //если отрезки состоят в одном и том же непустом контуре, значит, ничего делать не нужно
- if (first != null && first == second)
- {
- Console.WriteLine("Контур уже существует");
- return;
- }
- //первый есть..
- if (first != null)
- {
- Console.WriteLine("отрезок " + segment + " уже есть в контурах..");
- //..а второго нет(наиболее распространённая ситуация)
- if (second == null)
- {
- Console.WriteLine("а отрезка " + foundedSegment + " в контурах ещё нет, добавляем...");
- first.Add(foundedSegment);
- Console.WriteLine("итоговый контур: " + first);
- }
- else
- {
- //..или и второй есть
- Console.WriteLine("отрезок " + foundedSegment + " тоже..");
- Console.WriteLine("оба есть в контурах! ");
- Console.WriteLine("все проверки считаются проваленными...");
- }
- }
- //..или нет первого
- else
- {
- Console.WriteLine("отрезка " + segment + " нет в контурах..");
- //..но есть второй..
- if (second != null)
- {
- Console.WriteLine("но " + foundedSegment + " есть, добавим первый к нему..");
- second.Add(segment);
- Console.WriteLine("итоговый контур " + second);
- }
- //..или обоих нет
- else
- {
- Console.WriteLine("отрезка " + foundedSegment + " тоже");
- Outline newOutline = new Outline(segment, foundedSegment);
- outlines.Add(newOutline);
- Console.WriteLine("так как совпадение всё же обнаружено, создаётся новый контур: " + newOutline);
- }
- }
- }
- private Outline searchInOtherOutlines(Segment segment)
- {
- Outline found = null;
- foreach (Outline outline in outlines)
- {
- if (outline.Contains(segment)) found = outline;
- }
- return found;
- }
- private class ByStartComparator : IComparer<Segment>
- {
- public int Compare(Segment first, Segment second)
- {
- return first.start.X.CompareTo(second.start.X);
- }
- }
- private class EventComparator : IComparer<SweepLineEvent>
- {
- public int Compare(SweepLineEvent first, SweepLineEvent second)
- {
- return first.POI.X.CompareTo(second.POI.X);
- }
- }
- private struct SweepLineEvent
- {
- public string TYPE;
- public const string START = "START";
- public const string END = "END";
- public PointF POI; //point of interest
- public Segment parent;
- public override string ToString()
- {
- return "["+TYPE + " | " + POI + " | Parent:" + parent+"]";
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement