从点集合中检测圆弧和线段
Arcs and line segments detection from collection of points
我正准备创建一个程序来检测点 (x,y) 集合中的弧线和线段,这些点相互跟随,通常它们会创建一个闭合的多边形。
我只是不知道从哪里开始。
也许有人知道 "ready to go" 图书馆(可以付费)哪家能帮我做这样的事情?或者是一些相对容易实现的算法命题?我正在寻找任何建议。
如果您的点没有精确地落在弧线和线段上,但您正在尝试找到最接近的点,请参阅:“https://en.wikipedia.org/wiki/Curve_fitting”。
如果您的点完全遵循弧线或线段,也许这个封闭的解决方案可能适合您。
它假定弧线至少由 4 个点组成。您可以创建具有任意 3 个点的圆弧,因此无法判断它们应该是圆弧还是线段(除非您使用角度阈值)。使用 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;
}
'curve' 是一个包含直线段和弧段的列表。
它应该适用于开放的多段线和多边形(终点与起点相同)。如果多边形的起点位于弧的中间,它将被分成两条弧。
正多边形(形成一个圆)将无法正常工作,因为您将定义具有相同起点和终点的圆弧。
我正准备创建一个程序来检测点 (x,y) 集合中的弧线和线段,这些点相互跟随,通常它们会创建一个闭合的多边形。 我只是不知道从哪里开始。 也许有人知道 "ready to go" 图书馆(可以付费)哪家能帮我做这样的事情?或者是一些相对容易实现的算法命题?我正在寻找任何建议。
如果您的点没有精确地落在弧线和线段上,但您正在尝试找到最接近的点,请参阅:“https://en.wikipedia.org/wiki/Curve_fitting”。
如果您的点完全遵循弧线或线段,也许这个封闭的解决方案可能适合您。 它假定弧线至少由 4 个点组成。您可以创建具有任意 3 个点的圆弧,因此无法判断它们应该是圆弧还是线段(除非您使用角度阈值)。使用 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;
}
'curve' 是一个包含直线段和弧段的列表。
它应该适用于开放的多段线和多边形(终点与起点相同)。如果多边形的起点位于弧的中间,它将被分成两条弧。 正多边形(形成一个圆)将无法正常工作,因为您将定义具有相同起点和终点的圆弧。