finished sweepline
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TMI_practicum
|
||||
{
|
||||
@@ -17,7 +18,33 @@ namespace TMI_practicum
|
||||
|
||||
public double Distance(Circle otherCircle)
|
||||
{
|
||||
return Math.Sqrt(Math.Pow(X - otherCircle.X, 2) + Math.Pow(Y - otherCircle.Y, 2));
|
||||
return Math.Round(Math.Sqrt(Math.Pow(X - otherCircle.X, 2) + Math.Pow(Y - otherCircle.Y, 2)), 15);
|
||||
}
|
||||
|
||||
public IList<Intersection> FindIntersections(Circle c1)
|
||||
{
|
||||
var intersections = new List<Intersection>();
|
||||
double d = Distance(c1);
|
||||
if (d > R + c1.R || d < Math.Abs(R - c1.R) || d == 0.0 && R - c1.R == 0.0) return null;
|
||||
|
||||
|
||||
double a = Math.Round((R * R - c1.R * c1.R + d * d) / (2.0*d), 15);
|
||||
double px = Math.Round(X + a * (c1.X - X) / d, 15);
|
||||
double py = Math.Round(Y + a * (c1.Y - Y) / d, 15);
|
||||
|
||||
double htemp = Math.Round(R * R - a * a, 15);
|
||||
if (htemp == 0)
|
||||
{
|
||||
intersections.Add(new Intersection(px, py));
|
||||
}
|
||||
else
|
||||
{
|
||||
double h = Math.Round(Math.Sqrt(htemp), 15);
|
||||
intersections.Add(new Intersection(px + h * (c1.Y - Y) / d, py - h * (c1.X - X) / d));
|
||||
intersections.Add(new Intersection(px - h * (c1.Y - Y) / d, py + h * (c1.X - X) / d));
|
||||
}
|
||||
|
||||
return intersections;
|
||||
}
|
||||
}
|
||||
}
|
@@ -35,7 +35,8 @@ namespace TMI_practicum
|
||||
solved = SimpleAlgorithm.Solve(parsed.Item3);
|
||||
break;
|
||||
case 2:
|
||||
throw new NotImplementedException();
|
||||
solved = SweepLineAlgorithm.Solve(parsed.Item3);
|
||||
break;
|
||||
case 3:
|
||||
throw new NotImplementedException();
|
||||
default:
|
||||
@@ -52,7 +53,7 @@ namespace TMI_practicum
|
||||
|
||||
byte algoritm = 0;
|
||||
int nbCircles = 0;
|
||||
var circles = new List<Circle>();
|
||||
Circle[] circles = null;
|
||||
|
||||
using (StreamReader file = new StreamReader(path))
|
||||
{
|
||||
@@ -60,12 +61,13 @@ namespace TMI_practicum
|
||||
{
|
||||
algoritm = byte.Parse(file.ReadLine());
|
||||
nbCircles = int.Parse(file.ReadLine());
|
||||
|
||||
circles = new Circle[nbCircles];
|
||||
string line;
|
||||
int i = 0;
|
||||
while ((line = file.ReadLine()) != null)
|
||||
{
|
||||
double[] parts = line.Split(' ').Select(double.Parse).ToArray();
|
||||
circles.Add(new Circle(parts[0], parts[1], parts[2]));
|
||||
circles[i++] = new Circle(parts[0], parts[1], parts[2]);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
|
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TMI_practicum
|
||||
@@ -7,7 +6,7 @@ namespace TMI_practicum
|
||||
{
|
||||
public static IEnumerable<Intersection> Solve(IList<Circle> circles)
|
||||
{
|
||||
var intersections = new Stack<Intersection>();
|
||||
var intersections = new List<Intersection>();
|
||||
|
||||
for (int i = 0; i < circles.Count - 1; i++)
|
||||
{
|
||||
@@ -15,35 +14,12 @@ namespace TMI_practicum
|
||||
{
|
||||
var c1 = circles[i];
|
||||
var c2 = circles[j];
|
||||
CalculateIntersection(intersections, c1, c2);
|
||||
var intersects = c1.FindIntersections(c2);
|
||||
if (intersects != null) intersections.AddRange(c1.FindIntersections(c2));
|
||||
}
|
||||
}
|
||||
|
||||
return intersections;
|
||||
}
|
||||
|
||||
private static void CalculateIntersection(Stack<Intersection> intersections, Circle c1, Circle c2)
|
||||
{
|
||||
double d = c1.Distance(c2);
|
||||
if (d > c1.R + c2.R || d < Math.Abs(c1.R - c2.R)) return;
|
||||
|
||||
if (d == 0.0 && c1.R - c2.R == 0.0) throw new ArgumentException("Circles may not be coincident!");
|
||||
|
||||
double a = (c1.R * c1.R - c2.R * c2.R + d * d) / (2.0*d);
|
||||
double px = c1.X + a * (c2.X - c1.X) / d;
|
||||
double py = c1.Y + a * (c2.Y - c1.Y) / d;
|
||||
|
||||
double htemp = c1.R * c1.R - a * a;
|
||||
if (htemp == 0)
|
||||
{
|
||||
intersections.Push(new Intersection(px, py));
|
||||
}
|
||||
else
|
||||
{
|
||||
double h = Math.Sqrt(htemp);
|
||||
intersections.Push(new Intersection(px + h * (c2.Y - c1.Y) / d, py - h * (c2.X - c1.X) / d));
|
||||
intersections.Push(new Intersection(px - h * (c2.Y - c1.Y) / d, py + h * (c2.X - c1.X) / d));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Priority_Queue;
|
||||
using Medallion.Collections;
|
||||
|
||||
namespace TMI_practicum
|
||||
{
|
||||
@@ -8,58 +8,73 @@ namespace TMI_practicum
|
||||
{
|
||||
public static IEnumerable<Intersection> Solve(IList<Circle> circles)
|
||||
{
|
||||
// fuck deze priority queue piece of shit.... >:(
|
||||
SimplePriorityQueue<Event, double> events = new SimplePriorityQueue<Event, double>();
|
||||
Stack<Intersection> intersections = new Stack<Intersection>();
|
||||
var segments = new List<Segment>();
|
||||
|
||||
|
||||
|
||||
var events = new PriorityQueue<Event>();
|
||||
var intersections = new List<Intersection>();
|
||||
var active = new List<Circle>();
|
||||
|
||||
foreach (var circle in circles)
|
||||
{
|
||||
events.Enqueue(new Event(Event.EventType.Start, circle.X - circle.R), circle.X - circle.R);
|
||||
events.Enqueue(new Event(Event.EventType.End, circle.X + circle.R), circle.X + circle.R);
|
||||
events.Enqueue(new Event(Event.EventType.Start, circle.X - circle.R, circle));
|
||||
events.Enqueue(new Event(Event.EventType.End, circle.X + circle.R, circle));
|
||||
}
|
||||
|
||||
return null;
|
||||
while (events.Count != 0)
|
||||
{
|
||||
Event e = events.Dequeue();
|
||||
|
||||
switch (e.Type)
|
||||
{
|
||||
case Event.EventType.Start:
|
||||
active.Add(e.Circle);
|
||||
CheckIntersections(active, e.Circle, intersections);
|
||||
break;
|
||||
case Event.EventType.End:
|
||||
active.Remove(e.Circle);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
return intersections;
|
||||
}
|
||||
|
||||
private static void CheckIntersections(IEnumerable<Circle> active, Circle circle, List<Intersection> intersections)
|
||||
{
|
||||
foreach (var otherCircle in active)
|
||||
{
|
||||
if (circle.Equals(otherCircle)) continue;
|
||||
|
||||
var intersects = circle.FindIntersections(otherCircle);
|
||||
if (intersects == null) continue;
|
||||
|
||||
intersections.AddRange(intersects);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private struct Event
|
||||
private struct Event : IComparable<Event>
|
||||
{
|
||||
public EventType Type { get; }
|
||||
public Circle Circle { get; }
|
||||
public double X { get; }
|
||||
|
||||
public enum EventType
|
||||
{
|
||||
Start,
|
||||
End,
|
||||
Intersect
|
||||
End
|
||||
}
|
||||
|
||||
public Event(EventType type, double xCoordinate)
|
||||
public Event(EventType type, double x, Circle circle)
|
||||
{
|
||||
Type = type;
|
||||
X = xCoordinate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private struct Segment
|
||||
{
|
||||
public SegmentType Type { get; }
|
||||
public Circle Circle { get; }
|
||||
public enum SegmentType
|
||||
{
|
||||
Top,
|
||||
Bottom
|
||||
}
|
||||
|
||||
public Segment(Circle circle, SegmentType type)
|
||||
{
|
||||
X = x;
|
||||
Circle = circle;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public int CompareTo(Event other)
|
||||
{
|
||||
return X.CompareTo(other.X);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -33,11 +33,11 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="Priority Queue, Version=4.2.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<HintPath>..\packages\OptimizedPriorityQueue.4.2.0\lib\net45\Priority Queue.dll</HintPath>
|
||||
<Reference Include="MedallionPriorityQueue, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<HintPath>..\packages\MedallionPriorityQueue.1.1.0\lib\net45\MedallionPriorityQueue.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="OptimizedPriorityQueue" version="4.2.0" targetFramework="net461" />
|
||||
<package id="MedallionPriorityQueue" version="1.1.0" targetFramework="net461" />
|
||||
</packages>
|
Reference in New Issue
Block a user