C# CAD2016 判断多边形的方向正时针或逆时针旋转
//已知块文件名称 GXGLQTC
//块文件需要插入的坐标点 scaledPoint
// 插入块到当前图纸中的指定位置
ObjectId newBlockId;
BlockTable currentBlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
newBlockId = currentBlockTable["GXGLQTC"];
using (Transaction transaction = db.TransactionManager.StartTransaction())
{
BlockReference blockRef = new BlockReference(scaledPoint, newBlockId);
BlockTable bt = transaction.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord activeSpace = transaction.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
activeSpace.AppendEntity(blockRef);
transaction.AddNewlyCreatedDBObject(blockRef, true);
transaction.Commit();
}
另外,还提供了一个辅助方法GetCenterOfPolyline
,用于计算给定多段线的中心点,但在当前代码片段中并未使用此方法来确定文本标签或块参照的位置。
namespace cad自定义面板集.jzd
{
internal class jzd01
{
// 选定"宗地"图层上的封闭对象(例如闭合多段线)
[CommandMethod("GenerateBoundaryPoints")]
public static void GenerateBoundaryPoints()
{
// 获取当前活动文档和数据库
// 获取当前AutoCAD应用中的活动文档、数据库和编辑器对象
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// 创建一个选择过滤器,限制用户只能选择"宗地"图层上的LWPOLYLINE对象作为外部边界
SelectionFilter outerFilter = new SelectionFilter(new TypedValue[] {
new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
new TypedValue((int)DxfCode.LayerName, "宗地")
});
// 提示用户根据上述规则进行实体选择,并获取选择结果
PromptSelectionResult outerSelRes = ed.GetSelection(outerFilter);
// 检查用户是否成功选择了实体
if (outerSelRes.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())// 开始事务处理以确保数据一致性
{
foreach (ObjectId outerId in outerSelRes.Value.GetObjectIds())// 遍历所有被选中的外部多段线
{
Polyline outerPolyline = (Polyline)tr.GetObject(outerId, OpenMode.ForRead);
// 确保所选多段线是闭合的且至少有一个顶点
if (outerPolyline.Closed && outerPolyline.NumberOfVertices > 0)
{
List sortedOuterPoints = new List();
for (int i = 0; i < outerPolyline.NumberOfVertices; i++)
{
Point2d point = outerPolyline.GetPoint2dAt(i);
sortedOuterPoints.Add(point);
}
多边形顶点集合outerPoints的边界框
//var boundingBox = outerPoints.Aggregate(
// new { MinX = double.MaxValue, MaxX = double.MinValue, MinY = double.MaxValue, MaxY = double.MinValue },
// (a, b) =>
// {
// return new
// {
// MinX = Math.Min(a.MinX, b.X),
// MaxX = Math.Max(a.MaxX, b.X),
// MinY = Math.Min(a.MinY, b.Y),
// MaxY = Math.Max(a.MaxY, b.Y)
// };
// });
找到左上角的顶点作为候选西北角
//Point2d topLeftCorner = new Point2d(boundingBox.MinX, boundingBox.MaxY);
找到最接近左上角(西北方向)的顶点索引
//int startVertexIndex = outerPoints.IndexOf(outerPoints.OrderBy(p => Math.Pow(p.X - topLeftCorner.X, 2) + Math.Pow(p.Y - topLeftCorner.Y, 2)).First());
确保起始顶点是真正的西北角,并按照顺时针排序
//bool isClockwiseFromNorthwest = true;
//int j = outerPoints.Count - 1;
//double sum = 0;
//for (int i = 0; i < outerPoints.Count - 1 || (i == outerPoints.Count - 2 && j == outerPoints.Count - 1); i++)
//{
// // Shoelace公式的实现,计算三角形对角线乘积之和
// if (i != outerPoints.Count - 2 || j != outerPoints.Count - 1)
// {
// sum += (outerPoints[j].X - outerPoints[i].X) * (outerPoints[(j + 1) % outerPoints.Count].Y + outerPoints[i].Y);
// }
// else
// {
// // 处理最后一个三角形,连接最后一个顶点和第一个顶点
// sum += (outerPoints[j].X - outerPoints[i].X) * (outerPoints[0].Y + outerPoints[i].Y);
// }
// // 更新下一次迭代的索引值(注意这里在循环体内部更新j以正确处理最后一个元素之后的“下一个”顶点)
// j = i;
//}
//ed.WriteMessage(sum + "sum\n");
根据有符号面积判断多边形的方向
//if (sum > 0)
//{
// isClockwiseFromNorthwest = false;
//}
//else
//{
// isClockwiseFromNorthwest = true;
//}
//ed.WriteMessage(isClockwiseFromNorthwest + "方向\n");
创建一个新的列表,包含从西北角开始按顺时针顺序排列的顶点
//List sortedOuterPoints = new List();
//if (!isClockwiseFromNorthwest)
//{
// ed.WriteMessage(isClockwiseFromNorthwest + "方向1");
// // 如果原始顺序不是从西北角开始顺时针排列,则反转整个列表并重新调整起始点位置
// var reversedOuterPoints = outerPoints.ToList();
// reversedOuterPoints.Reverse();//反序
// sortedOuterPoints.AddRange(reversedOuterPoints);
// sortedOuterPoints.RemoveAt(sortedOuterPoints.Count - 1); // 移除最后一个顶点(与第一个顶点重叠)
// sortedOuterPoints.Insert(0, outerPoints[startVertexIndex]);
//}
//else
//{
// ed.WriteMessage(isClockwiseFromNorthwest + "方向2");
// // 否则直接使用原始列表并调整起始顶点位置
// sortedOuterPoints.AddRange(outerPoints.Skip(startVertexIndex));
// sortedOuterPoints.Insert(0, outerPoints[startVertexIndex]);
//}
// 使用sortedOuterPoints进行后续操作
if (sortedOuterPoints.Count > 0)
{
Dictionary pointIndexDict = new Dictionary();
for (int i = 0; i < sortedOuterPoints.Count; i++)
{
// 创建并设置文本对象
Point2d point = sortedOuterPoints[i];
// 获取多边形的中心点
Point3d center = GetCenterOfPolyline(outerPolyline);
// 定义你的扩展因子,比如 1.5 表示扩大1.5倍
double scaleFactor = 1.1;
// 将顶点向中心点平移,然后按比例缩放
Point3d scaledPoint = new Point3d(
(point.X - center.X) * scaleFactor + center.X,
(point.Y - center.Y) * scaleFactor + center.Y,
0
);
scaledPoint = new Point3d(point.X, point.Y,0);
DBText text = new DBText();
text.TextString = "T"+(i + 1).ToString();
text.Height = 0.85;
text.Position = scaledPoint;
// 将文本添加到模型空间
using (Transaction transaction = db.TransactionManager.StartTransaction())
{
BlockTable bt = transaction.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord ms = transaction.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
ms.AppendEntity(text);
transaction.AddNewlyCreatedDBObject(text, true);
transaction.Commit();
}
// 插入块到当前图纸中的指定位置
ObjectId newBlockId;
BlockTable currentBlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
newBlockId = currentBlockTable["GXGLQTC"];
using (Transaction transaction = db.TransactionManager.StartTransaction())
{
BlockReference blockRef = new BlockReference(scaledPoint, newBlockId);
BlockTable bt = transaction.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord activeSpace = transaction.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
activeSpace.AppendEntity(blockRef);
transaction.AddNewlyCreatedDBObject(blockRef, true);
transaction.Commit();
}
}
}
}
}
tr.Commit();
}
}
}
private static Point3d GetCenterOfPolyline(Polyline polyline)
{
double xSum = 0, ySum = 0, zSum = 0;
for (int i = 0; i < polyline.NumberOfVertices; i++)
{
Point3d vertex = polyline.GetPoint3dAt(i);
xSum += vertex.X;
ySum += vertex.Y;
zSum += vertex.Z;
}
return new Point3d(xSum / polyline.NumberOfVertices, ySum / polyline.NumberOfVertices, zSum / polyline.NumberOfVertices);
}
}
}
//感谢大家的点赞,收藏,转发,关注
//附送AI 图片无版权 随意用 龙年大吉大利
通义万相 阿里最新推出的A绘画创作模型