public void Epsilon()
        {
            LineD[] lines   = new LineD[] { new LineD(0, 2, 5, 2), new LineD(3, 2.1, 5, 4) };
            var     results = FindBoth(lines);

            Assert.AreEqual(0, results.Length);
            results = MultiLineIntersection.FindSimple(lines, 1.0);
            Assert.AreEqual(1, results.Length);

            var result = results[0];

            Assert.IsTrue(PointD.Equals(new PointD(3, 2), result.Shared, 1.0));
            Assert.AreEqual(2, result.Lines.Length);
            Assert.AreEqual(0, result.Lines[0]);
            Assert.AreEqual(LineLocation.Between, result.Locations[0]);
            Assert.AreEqual(1, result.Lines[1]);
            Assert.AreEqual(LineLocation.Start, result.Locations[1]);

            lines   = new LineD[] { new LineD(3, 1, 1, 1), new LineD(1, 1.1, 3, 3), new LineD(1, 0.9, 3, -2) };
            results = FindBoth(lines);
            Assert.AreEqual(0, results.Length);
            results = MultiLineIntersection.FindSimple(lines, 1.0);
            Assert.AreEqual(1, results.Length);

            result = results[0];
            Assert.IsTrue(PointD.Equals(new PointD(1, 1), result.Shared, 1.0));
            Assert.AreEqual(3, result.Lines.Length);
            Assert.AreEqual(0, result.Lines[0]);
            Assert.AreEqual(LineLocation.End, result.Locations[0]);
            Assert.AreEqual(1, result.Lines[1]);
            Assert.AreEqual(LineLocation.Start, result.Locations[1]);
            Assert.AreEqual(2, result.Lines[2]);
            Assert.AreEqual(LineLocation.Start, result.Locations[1]);
        }
        private MultiLinePoint[] FindBoth(LineD[] lines)
        {
            var brute = MultiLineIntersection.FindSimple(lines);
            var sweep = MultiLineIntersection.Find(lines);

            CompareResults(brute, sweep);
            return(brute);
        }
Пример #3
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);
            }
        }
Пример #4
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);
        }