Я готовлюсь создать программу для обнаружения дуг и отрезков из набора точек (x, y), которые следуют друг за другом и обычно создают замкнутый многоугольник. Я просто не знаю, с чего начать. Может быть, кто-то знает "готовую" библиотеку (можно платную), которая, думаю, для меня такая? Или, может быть, какие-то предложения алгоритмов, которые относительно легко реализовать? Жду любых советов.
Обнаружение дуг и сегментов линий по набору точек
Ответы (1)
Если ваши точки не точно попадают на дуги и сегменты, но вы пытаетесь найти наиболее близкое соответствие, см.: 'https://en.wikipedia.org/wiki/Curve_fitting'.
Если ваши точки точно следуют дугам или сегментам линии, возможно, это закрытое решение может вам подойти. Предполагается, что дуги состоят как минимум из 4 точек. Вы можете создать дугу с любыми тремя точками, поэтому невозможно определить, должны ли они быть дугой или сегментом линии (если только вы не используете пороговое значение угла). С 4 точками вы можете сравнить, являются ли точки (0,1,2) и (0,1,3) частью одной и той же дуги.
При создании дуговых объектов из 3 точек внутренне он вычисляет радиус и центр, чтобы можно было их сравнить. Чтобы найти круг из 3 точек: https://math.stackexchange.com/questions/213658/get-the-equation-of-a-circle-when-given-3-points
PolyCurve ArcsAndLines(List<Point3d> points)
{
var curve = new PolyCurve();
Arc current = Arc.Unset;
for (int i = 0; i < points.Count - 1; i++)
{
var areEqual = false;
if (i + 3 < points.Count)
{
var arcA = new Arc(points[i], points[i + 1], points[i + 2]);
var arcB = new Arc(points[i], points[i + 1], points[i + 3]);
areEqual = AreEqual(arcA, arcB);
}
if (areEqual)
{
var start = current == Arc.Unset ? points[i] : current.StartPoint;
current = new Arc(start, points[i + 1], points[i + 3]);
}
else
{
if (current != Arc.Unset)
{
curve.Append(current);
current = Arc.Unset;
i++;
}
else
{
curve.Append(new Line(points[i], points[i + 1]));
}
}
}
return curve;
}
bool AreEqual(Arc a, Arc b)
{
const double tol = 0.001;
bool sameRadius = Math.Abs(a.Radius - b.Radius) < tol;
if (!sameRadius) return false;
bool sameCenter = a.Center.DistanceTo(b.Center) < tol;
return sameCenter;
}
«кривая» — это список, содержащий сегменты линий и дуг.
Он должен работать с открытыми полилиниями и полигонами (с конечной точкой, совпадающей с начальной). Если начало многоугольника находится в середине дуги, он будет разделен на две дуги. Правильный многоугольник (в результате которого получается круг) не будет работать должным образом, поскольку вы будете определять дугу с одинаковыми начальной и конечной точками.