private void DrawIntersections(LineD[] lines) { const double radius = 4.0; // generate new random line set if desired if (lines == null) { Size scale = new Size(OutputBox.Width - 4 * radius, OutputBox.Height - 4 * radius); int count = MersenneTwister.Default.Next(3, 20); lines = new LineD[count]; for (int i = 0; i < lines.Length; i++) { lines[i] = GeoAlgorithms.RandomLine( 2 * radius, 2 * radius, scale.Width, scale.Height); } } _lines = lines; double epsilon = (double)ToleranceUpDown.Value; _crossings = (epsilon > 0.0 ? MultiLineIntersection.FindSimple(lines, epsilon) : MultiLineIntersection.FindSimple(lines)); LinesLabel.Content = String.Format("{0}/{1}", lines.Length, _crossings.Length); OutputBox.Children.Clear(); // draw line set foreach (LineD line in lines) { var shape = new Line() { X1 = line.Start.X, Y1 = line.Start.Y, X2 = line.End.X, Y2 = line.End.Y, Stroke = Brushes.Black }; OutputBox.Children.Add(shape); } // draw intersections as hollow circles foreach (var crossing in _crossings) { var circle = new Ellipse() { Width = 2 * radius, Height = 2 * radius, Stroke = Brushes.Red }; Canvas.SetLeft(circle, crossing.Shared.X - radius); Canvas.SetTop(circle, crossing.Shared.Y - radius); OutputBox.Children.Add(circle); } }
public void Random() { LineD[] lines = new LineD[100]; for (int i = 0; i < lines.Length; i++) { lines[i] = GeoAlgorithms.RandomLine(0, 0, 1000000, 1000000); } FindBoth(lines); }
/// <summary> /// Creates a random <see cref="Subdivision"/> with the specified number of full edges and /// comparison epsilon.</summary> /// <param name="size"> /// The number of full edges, i.e. half the number of <see cref="Subdivision.Edges"/>, in /// the returned <see cref="Subdivision"/>.</param> /// <param name="epsilon"> /// The maximum absolute difference at which two coordinates should be considered equal. /// </param> /// <returns> /// A new random <see cref="Subdivision"/> with the specified <paramref name="size"/> and /// <paramref name="epsilon"/>.</returns> private static Subdivision CreateSubdivision(int size, double epsilon) { LineD[] lines = new LineD[size]; for (int i = 0; i < size; i++) { lines[i] = GeoAlgorithms.RandomLine(0, 0, 1000, 1000); } // split random set into non-intersecting line segments var crossings = MultiLineIntersection.FindSimple(lines, epsilon); var splitLines = MultiLineIntersection.Split(lines, crossings); Array.Copy(splitLines, lines, size); // re-randomize lines to eliminate split ordering CollectionsUtility.Randomize(lines); Subdivision division = Subdivision.FromLines(lines); division.Validate(); return(division); }
private void GeometryBasicTest() { Stopwatch timer = new Stopwatch(); long polyTicks = 0, polyEpsilonTicks = 0, lineTicks = 0, lineEpsilonTicks = 0; const double epsilon = 1e-10; const int outerLoop = 10000, innerLoop = 1000; const int iterations = outerLoop * innerLoop; for (int i = 0; i < outerLoop; i++) { PointD[] polygon = GeoAlgorithms.RandomPolygon(0, 0, 1000, 1000); LineD line = GeoAlgorithms.RandomLine(0, 0, 1000, 1000); LineD line2 = GeoAlgorithms.RandomLine(0, 0, 1000, 1000); PointD q = GeoAlgorithms.RandomPoint(0, 0, 1000, 1000); // trigger JIT compilation if (i == 0) { GeoAlgorithms.PointInPolygon(q, polygon); GeoAlgorithms.PointInPolygon(q, polygon, epsilon); line.Intersect(line2); line.Intersect(line2, epsilon); } timer.Restart(); for (int j = 0; j < innerLoop; j++) { line.Intersect(line2); } timer.Stop(); lineTicks += timer.ElapsedTicks; timer.Restart(); for (int j = 0; j < innerLoop; j++) { line.Intersect(line2, epsilon); } timer.Stop(); lineEpsilonTicks += timer.ElapsedTicks; timer.Restart(); for (int j = 0; j < innerLoop; j++) { GeoAlgorithms.PointInPolygon(q, polygon); } timer.Stop(); polyTicks += timer.ElapsedTicks; timer.Restart(); for (int j = 0; j < innerLoop; j++) { GeoAlgorithms.PointInPolygon(q, polygon, epsilon); } timer.Stop(); polyEpsilonTicks += timer.ElapsedTicks; } Output(" "); Output(String.Format("{0,12}", "Exact")); Output(String.Format("{0,12}", "Epsilon")); Output("\nLine Intersection "); Output(String.Format("{0,12:N2}", 1000 * AverageMicrosecs(lineTicks, iterations))); Output(String.Format("{0,12:N2}", 1000 * AverageMicrosecs(lineEpsilonTicks, iterations))); Output("\nPoint in Polygon "); Output(String.Format("{0,12:N2}", 1000 * AverageMicrosecs(polyTicks, iterations))); Output(String.Format("{0,12:N2}", 1000 * AverageMicrosecs(polyEpsilonTicks, iterations))); Output("\nTimes are nsec averages for exact and epsilon comparisons.\n"); Output("Point in Polygon uses random polygons with 3-60 vertices.\n"); }