diff --git a/Intersection.cs b/Intersection.cs new file mode 100644 index 0000000..b054ad9 --- /dev/null +++ b/Intersection.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; + +namespace RiverTrace +{ + class Intersection + { + private static bool LinesIntersect(Vector a, Vector b, Vector c, Vector d) + { + // Source: + // http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect#comment19165734_565282 + + Vector CmP = new Vector(c.X - a.X, c.Y - a.Y); + Vector r = new Vector(b.X - a.X, b.Y - a.Y); + Vector s = new Vector(d.X - c.X, d.Y - c.Y); + + double CmPxr = CmP.X * r.Y - CmP.Y * r.X; + double CmPxs = CmP.X * s.Y - CmP.Y * s.X; + double rxs = r.X * s.Y - r.Y * s.X; + + if (CmPxr == 0.0) + { + return ((c.X - a.X < 0.0) != (c.X - b.X < 0.0)) || + ((c.Y - a.Y < 0.0) != (c.Y - b.Y < 0.0)); + } + + if (rxs == 0.0) + return false; + + double rxsr = 1.0 / rxs; + double t = CmPxs * rxsr; + double u = CmPxr * rxsr; + + return (t >= 0.0) && (t <= 1.0) && (u >= 0.0) && (u <= 1.0); + } + + public static bool Check(List way, Vector point) + { + if (way.Count < 3) + return true; + Vector lastPoint = way[way.Count - 1]; + for (int i = 0; i < way.Count - 2; i++) + if (LinesIntersect(way[i], way[i + 1], lastPoint, point)) + return false; + return true; + } + } +} diff --git a/RiverTrace.csproj b/RiverTrace.csproj index c3bec33..4220a1e 100644 --- a/RiverTrace.csproj +++ b/RiverTrace.csproj @@ -57,6 +57,7 @@ + diff --git a/Tracer.cs b/Tracer.cs index a60e9c2..14099a3 100644 --- a/Tracer.cs +++ b/Tracer.cs @@ -95,14 +95,11 @@ public Tracer() tileMap = new TileMap(Config.Data.zoom); - var way = new List(); - Vector p1 = new Vector(); Vector p2 = new Vector(); Projection.DegToPix(Config.Data.lat1, Config.Data.lon1, Config.Data.zoom, out p1.X, out p1.Y); Projection.DegToPix(Config.Data.lat2, Config.Data.lon2, Config.Data.zoom, out p2.X, out p2.Y); - way.Add(p1); Vector lastDirection = p2 - p1; lastDirection.Normalize(); @@ -110,6 +107,9 @@ public Tracer() int pixelRange = (int)(scanRadius * 2) + 1; + var way = new List(); + way.Add(p1); + List samples = new List(); Vector lastPoint = p1; @@ -182,16 +182,20 @@ public Tracer() Config.Data.angleStep - Config.Data.angleRange); lastDirection = lastDirection.Rotated(bestAngle); lastPoint += lastDirection * scanRadius * Config.Data.advanceRate; + + if (!Intersection.Check(way, lastPoint)) + break; + way.Add(lastPoint); } - sw.Stop(); - - way.Reverse(); if (Config.Data.simplificationStrength > 0.0) { way = Simplify.DouglasPeuckerReduction(way, riverWidthPx * Config.Data.simplificationStrength); } + way.Reverse(); + sw.Stop(); + WriteOsm(way); for (int i = 0; i < 25; i++)