- 积分
- 849
- 明经币
- 个
- 注册时间
- 2019-1-4
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
前端给媳妇编写一个快速偏移多段线并填充图案的函数,刚开始以为多段线偏移的开发还比较简单,但是弄了以后发现多段线的偏移的处理算法设计到凸角的算法和一些特殊端点的处理。弄好以后,想着有类似需求的朋友们可以参考参考。里面可能还有情况没有考虑到,有新发现的,可以多多交流
还是录一个屏说明一下吧。本人非专业程序人员,只是一名机械设计者。函数有不足的地方多多交流。
//快速设计墙体,默认墙体厚度240mm
public class CreateMYWallCommand
{
[CommandMethod("CW")]
public void CreateWallCommand()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptIntegerOptions options = new PromptIntegerOptions("\n请选择向外偏移还是向内偏移 (1 向外偏移, 2 向内偏移): ");
options.AllowNone = false;
options.AllowZero = false;
options.DefaultValue = 1;
PromptIntegerResult result = ed.GetInteger(options);
if (result.Status != PromptStatus.OK)
{
ed.WriteMessage("Invalid input or command canceled.");
return; // 退出命令
}
int userInput = result.Value;
PromptEntityResult peResult = ed.GetEntity("请选折一条多段线: ");
if (peResult.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open the selected polyline
Entity ent = tr.GetObject(peResult.ObjectId, OpenMode.ForRead) as Entity;
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
if (ent is Polyline polyline)
{
// Specify the offset distance
double offsetDistance = 240; // Modify as needed
// 定义并初始化 actualOffsetDistance 变量
double actualOffsetDistance = 0.0;
// Create a new polyline for offset
Polyline newPolyline = new Polyline();
for (int i = 0; i < polyline.NumberOfVertices; i++)
{
Point2d vertex = polyline.GetPoint2dAt(i);
Vector2d offsetVector = new Vector2d(0, 0); // Initialize a zero vector
int nextIndex = (i + 1) % polyline.NumberOfVertices;
int prevIndex = (i + polyline.NumberOfVertices - 1) % polyline.NumberOfVertices;
Point2d nextVertex = polyline.GetPoint2dAt(nextIndex);
Point2d prevVertex = polyline.GetPoint2dAt(prevIndex);
Vector2d nextDir = (nextVertex - vertex).GetNormal();
Vector2d prevDir = (prevVertex - vertex).GetNormal();
offsetVector = (nextDir + prevDir).GetNormal();
// 处理多边形内角大于180度的情况
double crossProduct = nextDir.X * prevDir.Y - nextDir.Y * prevDir.X;
// 计算夹角的一半的正弦值
double angle = Math.Acos(nextDir.DotProduct(prevDir));
double halfAngleSin = Math.Sin(angle / 2.0);
// 计算 actualOffsetDistance
actualOffsetDistance = offsetDistance / halfAngleSin;
if (crossProduct <0)
{
offsetVector = -offsetVector;
}
// 处理多边形内角180度的情况
if (crossProduct == 0) // 夹角为180度的情况
{
offsetVector = nextDir.GetPerpendicularVector();
actualOffsetDistance = offsetDistance;
}
// 处理起点和终点所在线段方向
if (i == 0)
{
offsetVector = nextDir.GetPerpendicularVector(); // 垂直于起点线段方向的向量
actualOffsetDistance = offsetDistance;
}
else if (i == polyline.NumberOfVertices - 1)
{
offsetVector = -prevDir.GetPerpendicularVector(); // 垂直于起点线段方向的向量
actualOffsetDistance = offsetDistance;
}
// 获取起始向量
Vector2d startVector = polyline.GetPoint2dAt(1) - polyline.GetPoint2dAt(0);
// 判断起点向量方向并选择不同命令
if (startVector.X >= 0)
{
if (userInput == 1)
{
offsetVector = offsetVector * actualOffsetDistance; // 向内偏移
}
else
{
offsetVector = -offsetVector * actualOffsetDistance;
}
}
else
{
if (userInput == 2)
{
offsetVector = -offsetVector * actualOffsetDistance; // 向内偏移
}
else
{
offsetVector = offsetVector * actualOffsetDistance;
}
}
// Offset the vertex position
Point2d offsetVertex = vertex + offsetVector;
newPolyline.AddVertexAt(i, offsetVertex, 0, 0, 0);
}
// Add the new polyline to the model space
BlockTableRecord currentSpace = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
currentSpace.AppendEntity(newPolyline);
tr.AddNewlyCreatedDBObject(newPolyline, true);
// 连接起点和终点形成封闭区域
Point2d startVertex = newPolyline.GetPoint2dAt(0);
Point2d endVertex = newPolyline.GetPoint2dAt(newPolyline.NumberOfVertices - 1);
Line closeStartLine = new Line(
new Point3d(polyline.GetPoint2dAt(0).X, polyline.GetPoint2dAt(0).Y, 0),
new Point3d(startVertex.X, startVertex.Y, 0));
Line closeEndLine = new Line(
new Point3d(polyline.GetPoint2dAt(polyline.NumberOfVertices - 1).X, polyline.GetPoint2dAt(polyline.NumberOfVertices - 1).Y, 0),
new Point3d(endVertex.X, endVertex.Y, 0));
btr.AppendEntity(closeStartLine);
btr.AppendEntity(closeEndLine);
tr.AddNewlyCreatedDBObject(closeStartLine, true);
tr.AddNewlyCreatedDBObject(closeEndLine, true);
Point2d startLineStartPoint = new Point2d(closeStartLine.StartPoint.X, closeStartLine.StartPoint.Y);
Point2d startLineEndPoint = new Point2d(closeStartLine.EndPoint.X, closeStartLine.EndPoint.Y);
Point2d endLineStartPoint = new Point2d(closeEndLine.StartPoint.X, closeEndLine.StartPoint.Y);
Point2d endLineEndPoint = new Point2d(closeEndLine.EndPoint.X, closeEndLine.EndPoint.Y);
//创建一个新的封闭多段线,用于填充图案
Polyline closedPolyline = new Polyline();
closedPolyline.Closed = true;
//添加开始线的起点和终点,closedPolyline.NumberOfVertices指的是添加到集合的最后
closedPolyline.AddVertexAt(closedPolyline.NumberOfVertices, startLineStartPoint, 0, 0, 0);
closedPolyline.AddVertexAt(closedPolyline.NumberOfVertices, startLineEndPoint, 0, 0, 0);
//添加偏移多段线的各个点
//1获取偏移多段线的各个点坐标
List<Point2d> newPolylineVertices = new List<Point2d>();
for (int i = 0; i < newPolyline.NumberOfVertices; i++)
{
Point2d vertex = new Point2d(newPolyline.GetPoint3dAt(i).X, newPolyline.GetPoint3dAt(i).Y);
newPolylineVertices.Add(vertex);
}
//2循环添加偏移多段线的各个点坐标
for (int i = 0; i < newPolylineVertices.Count; i++)
{
closedPolyline.AddVertexAt(closedPolyline.NumberOfVertices, newPolylineVertices[i], 0, 0, 0);
}
//添加终点线的起点和终点,
closedPolyline.AddVertexAt(closedPolyline.NumberOfVertices, endLineEndPoint, 0, 0, 0);
closedPolyline.AddVertexAt(closedPolyline.NumberOfVertices, endLineStartPoint, 0, 0, 0);
//添加原多段线的各个点
//1获取原多段线的各个点坐标
List<Point2d> polylineVertices = new List<Point2d>();
for (int i = 0; i < polyline.NumberOfVertices; i++)
{
Point2d vertex = new Point2d(polyline.GetPoint3dAt(i).X, polyline.GetPoint3dAt(i).Y);
polylineVertices.Add(vertex);
}
//2循环添加原多段线的各个点坐标
for (int i = polylineVertices.Count - 1; i >= 0; i--)
{
closedPolyline.AddVertexAt(closedPolyline.NumberOfVertices, polylineVertices[i], 0, 0, 0);
}
// 将封闭多段线添加到模型空间中
ObjectId closedPolylineId = btr.AppendEntity(closedPolyline);
tr.AddNewlyCreatedDBObject(closedPolyline, true);
// 创建填充对象
Hatch hatch = new Hatch();
ObjectIdCollection objectIdCollection = new ObjectIdCollection();
objectIdCollection.Add(closedPolylineId);
hatch.SetHatchPattern(HatchPatternType.PreDefined, "AR-CONC"); // 设置填充图案类型
hatch.AppendLoop(HatchLoopTypes.Default, objectIdCollection);
// 添加填充到模型空间中
btr.AppendEntity(hatch);
tr.AddNewlyCreatedDBObject(hatch, true);
}
tr.Commit();
}
}
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
评分
-
查看全部评分
|