private void AddGhostPoint()
        {
            for (int i = 0; i < this.Diviser.InnerPoints.Count; i++)
            {
                Point2D point = this.Diviser.InnerPoints[i];

                for (int j = 0; j < this.Diviser.Divisers.Count; j++)
                {
                    LineSegment2D lineSegment = this.Diviser.Divisers[j];

                    if (lineSegment.Contains(point))
                    {
                        int a = this.Diviser.Parent.GetPointIndex(lineSegment.FirstPoint);
                        int b = this.Diviser.Parent.GetPointIndex(lineSegment.LastPoint);

                        Debug.Assert(a != -1 && b != -1);

                        double t = lineSegment.GetPosition(point);

                        this.ghostPoint.Add(new GhostPoint2D(a, b, t));
                    }
                }
            }
        }
示例#2
0
        public void ContainsPoint_Test()
        {
            for (int x0 = -10; x0 < 10; x0++)
            {
                for (int y0 = -10; y0 < 10; y0++)
                {
                    var el = new Ellipse(new Vector2D(x0, y0), 10, 10);

                    for (int a = 0; a < 360; a++)
                    {
                        var p1 = el.GetPointByAngle(Utils.ToRadian(a));
                        var p2 = el.GetPointByAngle(Utils.ToRadian(a) + System.Math.PI);

                        var line = new LineSegment2D(p1, p2);

                        var dx = System.Math.Abs(p1.X - p2.X);
                        var dy = System.Math.Abs(p1.Y - p2.Y);

                        if (dx >= dy)
                        {
                            //проекция на ось Х больше проекции на ось Y
                            //Проверяем точки, перемещаясь по X

                            //A x + B y + C = 0
                            //y = k x + b

                            var k = -(line.A / line.B);
                            var b = -(line.C / line.B);

                            var delta = dx / 100;
                            var start = System.Math.Min(p1.X, p2.X);
                            var stop  = System.Math.Max(p1.X, p2.X);

                            for (double i = (start - delta * 10); i <= (stop + delta * 10); i += delta)
                            {
                                var x   = System.Math.Round(i, 5);
                                var y   = k * x + b;
                                var p   = new Vector2D(x, y);
                                var res = line.Contains(p);
                                if ((x >= start) && (x <= stop))
                                {
                                    Assert.IsTrue(res);
                                }
                                else
                                {
                                    Assert.IsFalse(res);
                                }
                            }
                        }
                        else
                        {
                            //проекция на ось Y больше проекции на ось X
                            //Проверяем точки, перемещаясь по Y

                            //A x + B y + C = 0
                            //x = k y + b

                            var k = -(line.B / line.A);
                            var b = -(line.C / line.A);

                            var delta = dy / 100;
                            var start = System.Math.Min(p1.Y, p2.Y);
                            var stop  = System.Math.Max(p1.Y, p2.Y);

                            for (double i = (start - delta * 10); i <= (stop + delta * 10); i += delta)
                            {
                                var y   = System.Math.Round(i, 5);
                                var x   = k * y + b;
                                var p   = new Vector2D(x, y);
                                var res = line.Contains(p);
                                if ((y >= start) && (y <= stop))
                                {
                                    Assert.IsTrue(res);
                                }
                                else
                                {
                                    Assert.IsFalse(res);
                                }
                            }
                        }
                    }
                }
            }
        }
        public LineSegmentIntersecResult Intersec(LineSegment2D line)
        {
            double x1 = Start.X;
            double y1 = Start.Y;
            double x2 = Stop.X;
            double y2 = Stop.Y;

            double x3 = line.Start.X;
            double y3 = line.Start.Y;
            double x4 = line.Stop.X;
            double y4 = line.Stop.Y;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            bool l1Vertical = (x1 == x2);
            // ReSharper disable once CompareOfFloatsByEqualityOperator
            bool l2Vertical = (x3 == x4);

            if (l1Vertical && l2Vertical)
            {
                // Если обе линии вертикальны и имеют общую точку, то они
                // накладываются друг на друга
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                if (x1 == x3)
                {
                    // Если отрезки по Y накладываются, то и линии накладываются
                    if (((System.Math.Min(y1, y2) <= y3) && (y3 <= System.Math.Max(y1, y2))) ||
                        ((System.Math.Min(y1, y2) <= y4) && (y3 <= System.Math.Max(y1, y2))))
                    {
                        return(new LineSegmentIntersecResult(
                                   LineSegmentIntersecResult.IntersecResult.Overlaps, null));
                    }
                    // иначе линии не пересекаются
                    return(new LineSegmentIntersecResult(
                               LineSegmentIntersecResult.IntersecResult.DontIntersecs, null));
                }
                // Если обе линии вертикальны и не имеют общей точкк, то они не
                // пересекаются
                else
                {
                    return(new LineSegmentIntersecResult(
                               LineSegmentIntersecResult.IntersecResult.DontIntersecs, null));
                }
            }

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            bool l1Horizontal = (y1 == y2);
            // ReSharper disable once CompareOfFloatsByEqualityOperator
            bool l2Horizontal = (y3 == y4);

            if (l1Horizontal && l2Horizontal)
            {
                // Если обе линии горизонтальны и имеют общую точку, то они
                // накладываются друг на друга
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                if (y1 == y3)
                {
                    // Если отрезки по X накладываются, то и линии накладываются
                    if (((System.Math.Min(x1, x2) <= x3) && (x3 <= System.Math.Max(x1, x2))) ||
                        ((System.Math.Min(x1, x2) <= x4) && (x3 <= System.Math.Max(x1, x2))))
                    {
                        return(new LineSegmentIntersecResult(
                                   LineSegmentIntersecResult.IntersecResult.Overlaps, null));
                    }
                    // иначе линии не пересекаются
                    return(new LineSegmentIntersecResult(
                               LineSegmentIntersecResult.IntersecResult.DontIntersecs, null));
                }

                // Если обе линии горизонтальны и не имеют общей точку, то они не
                // пересекаются
                else
                {
                    return(new LineSegmentIntersecResult(
                               LineSegmentIntersecResult.IntersecResult.DontIntersecs, null));
                }
            }

            // Считаем коэффицианты
            double h1 = y2 - y1;
            double w1 = x2 - x1;
            double h2 = y4 - y3;
            double w2 = x4 - x3;

            double a1 = h1 / w1;
            double b1 = y1 - x1 * a1;
            double a2 = h2 / w2;
            double b2 = y3 - x2 * a2;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (a1 == a2)
            {
                // Линии параллельны и накладываются друг на друга
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                if (b1 == b2)
                {
                    // имеют тот же сдвиг по Y и при этом имеют накладывающиеся
                    // отрезки по X, то линии накладываются
                    if (((System.Math.Min(x1, x2) <= x3) && (x3 <= System.Math.Max(x1, x2))) ||
                        ((System.Math.Min(x1, x2) <= x4) && (x3 <= System.Math.Max(x1, x2))))
                    {
                        return(new LineSegmentIntersecResult(
                                   LineSegmentIntersecResult.IntersecResult.Overlaps, null));
                    }
                    // иначе линии не пересекаются
                    return(new LineSegmentIntersecResult(
                               LineSegmentIntersecResult.IntersecResult.DontIntersecs, null));
                }
                // Линии параллельны и не пересекаются
                return(new LineSegmentIntersecResult(
                           LineSegmentIntersecResult.IntersecResult.DontIntersecs, null));
            }

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (h1 * w2 + h2 * w1 == 0)
            {
                // линии не пересекаются
                return(new LineSegmentIntersecResult(
                           LineSegmentIntersecResult.IntersecResult.DontIntersecs, null));
            }

            // Считаем координату Х
            double x = (w1 * w2 * (y3 - y1) - x3 * h2 * w1 + x1 * h1 * w2)
                       / (h1 * w2 - h2 * w1);

            // теперь по координате Х считаем Y
            // ReSharper disable once RedundantAssignment
            double y = 0;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (w1 != 0)
            {
                y = x * h1 / w1 + y1 - x1 * h1 / w1;
            }
            else
            {
                y = x * h2 / w2 + y3 - x3 * h2 / w2;
            }

            Vector2D intersecPoint = new Vector2D(x, y);

            // Если точка пересечения принадлежит обоим отрезкам, то они
            // пересекаются
            if (Contains(intersecPoint) && line.Contains(intersecPoint))
            {
                return(new LineSegmentIntersecResult(
                           LineSegmentIntersecResult.IntersecResult.Intersecs, intersecPoint));
            }

            // Отрезки не пересекаются
            return(new LineSegmentIntersecResult(
                       LineSegmentIntersecResult.IntersecResult.DontIntersecs, null));
        }