コード例 #1
0
        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);
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        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");
        }