本文只适用于闭合多段线组成的图像,其他情况(圆、弧、椭圆、未封闭line)暂不支持。
效果如下图所示:
原始图:
代码运行后图:
附代码:
cs
public class 外轮廓
{
Database db = HostApplicationServices.WorkingDatabase;
[CommandMethod("xx")]
public void Demo()
{
try
{
//ObjectId obj = db.GetCenterPl();
// return;
// List<DBText> dbtext = db.SelectEntities<DBText>();
// return;
// db.GetEntities(out List<Curve> curve, "aa");
// return;
if (!db.GetEntities(out List<Curve> curve, "框选识别外轮廓的图像"))
return;
List<Line> lines = new List<Line>();
foreach (var item in curve)
{
if (item is Line) lines.Add(item as Line);
else if (item is Polyline pl)
{
List<Curve> cus = PmPolyLineMethod.ExplodePolyLine(pl);
foreach (var cu in cus)
{
if (cu is Line) lines.Add(cu as Line);
}
}
}
//lines.ForEach(line => line.ColorIndex = 1);
//foreach (var item in lines)
//{
// db.AddEntityToModeSpace(item);
//}
//return;
Dictionary<Line, List<Point3d>> pointsOnLine = new Dictionary<Line, List<Point3d>>();
foreach (var item in lines)
{
pointsOnLine.Add(item, new List<Point3d>());
}
for (int i = 0; i < lines.Count - 1; i++)
{
for (int j = i + 1; j < lines.Count; j++)
{
Point3dCollection pos = new Point3dCollection();
lines[i].IntersectWith(lines[j], Intersect.OnBothOperands, pos, IntPtr.Zero, IntPtr.Zero);
if (pos.Count > 0)
{
foreach (Point3d item in pos)
{
pointsOnLine[lines[i]].Add(item);
pointsOnLine[lines[j]].Add(item);
}
}
}
}
lines.Clear();
foreach (var item in pointsOnLine)
{
Line line = item.Key;
List<Point3d> points = item.Value;
if (points.Count == 0)
{
lines.Add(line);
}
else
{
if (points.Count > 1)
{
points = points.OrderBy(x => line.GetParameterAtPoint(x)).ToList();//点排序
}
Point3dCollection pos = new Point3dCollection();
points.ForEach(x => pos.Add(x));//点集合加点
DBObjectCollection dbs = line.GetSplitCurves(pos);//打断线
foreach (var dbobject in dbs)
{
if (dbobject is Line)
{
lines.Add(dbobject as Line);//最终线段list
}
}
}
}
//lines.ForEach(line => line.ColorIndex = 1);
//lines.ForEach(line => db.AddEntityToModeSpace(line));
//return;
if (!PmPolyLineMethod.GetPoint(out Point3d point, "请选择外面一点")) return;
Line firstLine = lines.OrderBy(x => x.GetClosestPointTo(point, false).DistanceTo(point)).First();
//firstLine.ColorIndex = 1;
//db.AddEntityToModeSpace(firstLine);
//return;
lines.Remove(firstLine);
Polyline polyline = new Polyline();
polyline.AddVertexAt(0, firstLine.StartPoint.Convert2d(new Plane()), 0, 0, 0);
polyline.AddVertexAt(1, firstLine.EndPoint.Convert2d(new Plane()), 0, 0, 0);
Vector3d v1 = firstLine.StartPoint - point;
Vector3d v2 = firstLine.EndPoint - point;
if (v1.CrossProduct(v2).Z > 0) polyline.ReverseCurve();
//polyline.ColorIndex = 1;
//db.AddEntityToModeSpace(polyline);
//return;
while (true)
{
List<Line> tmps = new List<Line>();
foreach (var item in lines)
{
if (item.StartPoint == polyline.EndPoint)
{
tmps.Add(item);
}
else if (item.EndPoint == polyline.EndPoint)
{
item.ReverseCurve();
tmps.Add(item);
}
}
if (tmps.Count == 0) break;
Vector3d vector = -polyline.GetFirstDerivative(polyline.EndPoint);//顺时针
double maxAngle = 0;
Line bigLine = new Line();
foreach (var item in tmps)//
{
double angle = vector.GetAngleTo(item.Delta, -Vector3d.ZAxis);
if (angle > maxAngle)
{
maxAngle = angle;
bigLine = item;
}
}
polyline.JoinEntity(bigLine);
lines.Remove(bigLine);
if (polyline.EndPoint == polyline.StartPoint) break;
}
polyline.ColorIndex = 1;
db.AddEntityToModeSpace(polyline);
return;
}
catch (System.Exception)
{
throw;
}
}
}
说明:db.GetEntities 等函数为本博封装函数。获取联系下方↓↓↓