/
docNemo
/
clothes-graph
Обзор
Документация
Войти
/
docNemo
/
clothes-graph
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
src/ClothesGraph.Model/Drafting/CurveIntersection.cs
73 строки
3 KB
docNemo
Фундамент продукта: параметрическое построение выкроек, печать, установщик
08 авг 2026, 22:17
08 авг 2026, 22:17
cd47cce
Код
Авторство
О чём код?
using System; using ClothesGraph.Geometry; namespace ClothesGraph.Model.Drafting; /// <summary> /// Поиск точки пересечения двух линий. /// </summary> /// <remarks> /// Для пары отрезков решается аналитически. В остальных случаях линии /// разбиваются на хорды и ищется пересечение хорд: этого достаточно для /// построений чертежа, где кривые пересекаются под ощутимым углом. /// </remarks> internal static class CurveIntersection { private const int Samples = 96; public static Point2? Solve(ICurve first, ICurve second) { if (first is LineCurve a && second is LineCurve b) return SolveSegments(a.Start, a.End, b.Start, b.End); var previousFirst = first.Start; for (var i = 1; i <= Samples; i++) { var currentFirst = first.PointAt(i / (double)Samples); var previousSecond = second.Start; for (var j = 1; j <= Samples; j++) { var currentSecond = second.PointAt(j / (double)Samples); var hit = SolveSegments(previousFirst, currentFirst, previousSecond, currentSecond); if (hit is not null) return hit; previousSecond = currentSecond; } previousFirst = currentFirst; } return null; } private static Point2? SolveSegments(Point2 a1, Point2 a2, Point2 b1, Point2 b2) { double ax = a2.X.Units - a1.X.Units, ay = a2.Y.Units - a1.Y.Units; double bx = b2.X.Units - b1.X.Units, by = b2.Y.Units - b1.Y.Units; var denominator = ax * by - ay * bx; // Параллельные линии пересечения не дают. Совпадающие тоже не дают // единственной точки, поэтому и они считаются неразрешимыми. if (Math.Abs(denominator) < 1e-9) return null; double dx = b1.X.Units - a1.X.Units, dy = b1.Y.Units - a1.Y.Units; var t = (dx * by - dy * bx) / denominator; var u = (dx * ay - dy * ax) / denominator; const double tolerance = 1e-9; if (t < -tolerance || t > 1 + tolerance || u < -tolerance || u > 1 + tolerance) return null; return new Point2( Length.FromUnits((long)Math.Round(a1.X.Units + ax * t, MidpointRounding.AwayFromZero)), Length.FromUnits((long)Math.Round(a1.Y.Units + ay * t, MidpointRounding.AwayFromZero))); } }