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)); } } } }
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)); }