AutoCAD C# 两不平行直线倒圆弧算法
参考的博客:https://www.cnblogs.com/JJBox/p/14300098.html
下面是计算示例
主要计算代码:
var peo = new PromptEntityOptions("选择直线1") { AllowNone = false, AllowObjectOnLockedLayer = false }; peo.SetRejectMessage("请选择直线Line"); peo.AddAllowedClass(typeof(Line), false); var per1 = AcEnv.CurEd.GetEntity(peo); peo.Message = "选择直线2"; var per2 = AcEnv.CurEd.GetEntity(peo); var r = AcEnv.CurEd.GetDouble("输入圆弧半径:\n").Value; if (per1.Status == PromptStatus.OK && per2.Status == PromptStatus.OK) { using (var tr = AcEnv.CurDb.TransactionManager.StartTransaction()) { var l1 = (Line)tr.GetObject(per1.ObjectId, OpenMode.ForRead); var l2 = (Line)tr.GetObject(per2.ObjectId, OpenMode.ForRead); var pts = new Point3dCollection(); l1.IntersectWith(l2, Intersect.ExtendBoth, l1.GetPlane(), pts, IntPtr.Zero, IntPtr.Zero); if (pts.Count == 0) { AcApp.Application.ShowAlertDialog("2直线无交点无法到圆角!"); tr.Abort(); return; } var p0 = pts[0]; var p02d = p0.Convert2d(l1.GetPlane()); var voa = p0.GetVectorTo(l1.EndPoint.GetMidPoint(l1.StartPoint)); var vob = p0.GetVectorTo(l2.EndPoint.GetMidPoint(l2.StartPoint)); var angle = voa.GetAngleTo(vob) * 0.5; var doc = r / Math.Sin(angle); var pa = p0.Add(voa.GetNormal() * (double)(r / Math.Tan(angle))); var pb = p0.Add(vob.GetNormal() * (double)(r / Math.Tan(angle))); var isCw = Tools.CrossAclockwise(p02d, pa.Convert2d(l1.GetPlane()), pb.Convert2d(l1.GetPlane())); var pc = pa.Add((isCw ? voa : voa.Negate()).GetPerpendicularVector().GetNormal() * r); var startAngle = pc.GetVectorTo(pb).Convert2d(l1.GetPlane()).GetAngle2XAxis(); var endAngle = pc.GetVectorTo(pa).Convert2d(l1.GetPlane()).GetAngle2XAxis(); Arc a = new Arc(pc, Vector3d.ZAxis, r, isCw ? startAngle : endAngle, isCw ? endAngle : startAngle); //AcEnv.CurDb.AppendEntities(new DBPoint(p0), new DBPoint(pa), new DBPoint(pb), new DBPoint(pc)); AcEnv.CurDb.AppendEntities(a); tr.Commit(); } }
用到的拓展函数
public static Point3d GetMidPoint(this Point3d p1, Point3d p2) { return new Point3d((p1.X + p2.X) * 0.5, (p1.Y + p2.Y) * 0.5, (p1.Z + p2.Z) * 0.5); } /// <summary> /// 叉积,二维叉乘计算 /// </summary> /// <param name="a">传参是向量,表示原点是0,0</param> /// <param name="b">传参是向量,表示原点是0,0</param> /// <returns>其模为a与b构成的平行四边形面积</returns> public static double Cross(Vector2d a, Vector2d b) { return a.X * b.Y - a.Y * b.X; } /// <summary> /// 叉积,二维叉乘计算 /// </summary> /// <param name="o">原点</param> /// <param name="a">oa向量</param> /// <param name="b">ob向量,此为判断点</param> /// <returns>返回值有正负,表示绕原点四象限的位置变换,也就是有向面积</returns> public static double Cross(Point2d o, Point2d a, Point2d b) { return Cross(o.GetVectorTo(a), o.GetVectorTo(b)); } /// <summary> /// 叉积,逆时针方向为真 /// </summary> /// <param name="o">直线点1</param> /// <param name="a">直线点2</param> /// <param name="b">判断点</param> /// <returns>b点在oa的逆时针<see cref="true"/></returns> public static bool CrossAclockwise(Point2d o, Point2d a, Point2d b) { return Cross(o, a, b) > -1e-6;//浮点数容差考虑 } /// <summary> /// X轴到向量的弧度,cad的获取的弧度是1PI,所以转换为2PI(上小,下大) /// </summary> /// <param name="ve">向量</param> /// <returns>弧度</returns> public static double GetAngle2XAxis(this Vector2d ve) { double alz = Vector2d.XAxis.GetAngleTo(ve);//观察方向不要设置 alz = ve.Y > 0 ? alz : Math.PI * 2 - alz; //逆时针为正,如果-负值控制正反 alz = Math.Abs(Math.PI * 2 - alz) < 1e-10 ? 0 : alz; return alz; } public static ObjectIdCollection AppendEntities(this Database acdb, params Entity[] ents) { ObjectIdCollection oids = []; using (var tr = acdb.TransactionManager.StartTransaction()) { var btr = (BlockTableRecord)acdb.CurrentSpaceId.GetObject(OpenMode.ForWrite); foreach (var item in ents) { if (!item.IsNewObject) continue; oids.Add(btr.AppendEntity(item)); tr.AddNewlyCreatedDBObject(item, true); } tr.Commit(); } return oids; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律