AutoCAD C# 两不平行直线倒圆弧算法

news/2024/10/10 8:20:46

下面是计算示例

主要计算代码:

   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;}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/27779.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

sublime设置默认打开侧边栏(失败)

描述 每次使用sublime打开某个目录,总是不显示侧边栏,还得手动打开。 过程 在设置里找了半天似乎没有这个选项,有点离谱,网上搜到的全是手动打开侧边栏。看来只能Ctrl+KB按得勤快些了。// Display the toggle sidebar button in the status bar"show_sidebar_button&q…

C++模板

C++模板 C++是一个面向对象编程的语言,提供了类的继承和组合机制,虽然在层次结构上很简单,但使用起来非常糟糕。C++使用关键字template,告诉编译器声明的类或者对象是一个模板。模板不是像继承和组合那样重用目标代码,而是重用源代码。容器不再包含名为 Object 的泛型基类…

Matlab安装教程(Linux)

解压安装包 在虚拟机中,文件直接通过拖拽文件的方式将安装包拉入虚拟机时,文件通常存放在/tmp/VMwareDnD中,因此需要将存放文件位置的文件转移到/home/<用户名>/<存放目录>中 参考命令如下: mv /tmp/VMwareDnD/<文件存放目录>/* /home/<用户名>/&l…

2. 基础配置

1. 配置文件格式 1.1 配置文件自动提示功能消失解决方案 ​​ 1.2 SpringBoot配置文件加载顺序(了解) application.properties > application.yml > application.yaml 1.3 注意事项 SpringBoot核心配置文件名为application SpringBoot内置属性过多,且所有属性集中…

Qt/C++音视频开发72-倍速推流/音视频同步倍速推流/不改变帧率和采样率/低倍速和高倍速

一、前言 最近多了个新需求,需要倍速推流,推流界的扛把子obs也有倍速推流功能,最高支持到两倍速。这里所说的倍速,当然只限定在文件,只有文件才可能有倍速功能,因为也只有文件才能倍速解码播放。实时视频流是不可能倍速的,因为没有时长,有时长的才可以按照播放进度来。…

Excel求解器使用教程

添加规则求解加载项创建excel文件,点击文件点击选项选择加载项->规则求解加载项->转到选择规则求解加载项->确定求解器所在位置---数据->规划求解在excel文档中填写相关的计算公式,用来求解点击规则求解,填写对应的目标,可变单元和约束,选择求解方法来求解通过…

虚拟机创建教程

虚拟机创建 创建虚拟机的时候,选择自定义,自己来创建虚拟机在虚拟机中,选择创建16.2.X版本的虚拟机,兼容性比较好在创建虚拟机的操作系统时,选择稍后安装操作系统,实测中如果选择其他的在安装过程中会跳过系统安装的部分阶段选择对应的系统和版本选择名称和安装位置,个人…

union 和union all 使用区别

union 和union all 把 查询user表前5条数据查询user表数据从第7条数据开始,查询两条 通过union来把两个sql中的数据合并到一张表中,只查询出一条数据,会把重复的数据去掉 通过union all查询 出现出了两条数据,不会去重