diff --git a/src/CAD/IFox.CAD.Shared/ExtensionMethod/AddMehtodsEx.cs b/src/CAD/IFox.CAD.Shared/ExtensionMethod/AddMehtodsEx.cs new file mode 100644 index 0000000000000000000000000000000000000000..21f9eabdcd08174d711ad5950fed4a770f431c29 --- /dev/null +++ b/src/CAD/IFox.CAD.Shared/ExtensionMethod/AddMehtodsEx.cs @@ -0,0 +1,48 @@ +#if acad +using Autodesk.AutoCAD.Internal; +#endif +namespace IFoxCAD.Cad; +/// +/// Add扩展方法类 +/// +public static class AddMehtodsEx +{ + /// + /// 直线两端点对象集合扩展添加方法 + /// + /// 直线两端点对象集合 + /// 直线起始点 + /// 直线结束点 + public static void Add(this List linePoints, Point2d startPoint, Point2d endPoint) + { + linePoints.Add(new LinePoint2d(startPoint, endPoint)); + } + + /// + /// 直线两端点对象集合扩展添加方法 + /// + /// 直线两端点对象集合 + /// 直线起始点 + /// 直线结束点 + public static void Add(this List linePoints, Point3d startPoint, Point3d endPoint) + { + linePoints.Add(new LinePoint3d(startPoint, endPoint)); + } + +#if acad + /// + /// 快捷命令别名对象集合添加方法 + /// + /// 快捷命令别名对象集合 + /// 原命令别名 + /// 新命令别名 + /// 命令调用函数 + /// 是否移除原别名,默认:移除 + /// 是否覆盖已定义别名,默认:覆盖 + public static void Add(this List aliases, string OldAlias, string NewAlias, CommandCallback CmdAction, bool IsRemoveOld = true, bool IsReplace = true) + { + aliases.Add(new CmdAlias(OldAlias, NewAlias, CmdAction, IsRemoveOld, IsReplace)); + } +#endif +} + diff --git a/src/CAD/IFox.CAD.Shared/ExtensionMethod/Enums.cs b/src/CAD/IFox.CAD.Shared/ExtensionMethod/Enums.cs index 5043cadbe1c1df84a80ed3b5d7d503fe2d5d2230..c8ee4f133c20ca3868e95745f8360cf67189c385 100644 --- a/src/CAD/IFox.CAD.Shared/ExtensionMethod/Enums.cs +++ b/src/CAD/IFox.CAD.Shared/ExtensionMethod/Enums.cs @@ -172,4 +172,25 @@ public enum FontTTF Arial, [Description("Romans")] Romans -} \ No newline at end of file +} + +#region 两点间距离等分所用枚举 +/// +/// 两点距离等分类型(PointBasals Using) +/// +public enum DivideType +{ + /// + /// 默认值:无 + /// + None, + /// + /// 定数等分 + /// + Number, + /// + /// 定距等分 + /// + Distance +} +#endregion 两点间距离等分所用枚举 \ No newline at end of file diff --git a/src/CAD/IFox.CAD.Shared/ExtensionMethod/ErrorInfoEx.cs b/src/CAD/IFox.CAD.Shared/ExtensionMethod/ErrorInfoEx.cs index 00da86efed0fbf0398f6fd5e8b3ed89faa4b0f85..1fc0d0f3f333c687f2c47d4900bf7c805936c771 100644 --- a/src/CAD/IFox.CAD.Shared/ExtensionMethod/ErrorInfoEx.cs +++ b/src/CAD/IFox.CAD.Shared/ExtensionMethod/ErrorInfoEx.cs @@ -6,15 +6,20 @@ public static class ErrorInfoEx { /// - /// 打印CAD错误信息到命令行 - /// 使用方法: - /// try - /// { - /// //你的代码 - /// } - /// catch (AcException acex) { acex.AcErrorInfo(); } - /// catch (Exception) { throw; } - /// + /// CAD错误大全 + /// + /// 引用及别名设置: + /// using AcException = Autodesk.AutoCAD.Runtime.Exception; + /// using AcException = GrxCAD.Runtime.Exception; + /// using AcException = ZwSoft.ZwCAD.Runtime.Exception; + /// 使用方法: + /// try + /// { + /// //你的代码 + /// } + /// catch (AcException acex) { acex.AcErrorInfo(); } + /// catch (Exception) { throw; } + /// /// /// AcException internal static void AcErrorInfo(this AcException acex) diff --git a/src/CAD/IFox.CAD.Shared/ExtensionMethod/PointEx.cs b/src/CAD/IFox.CAD.Shared/ExtensionMethod/PointEx.cs index 76220f90910500510aa37afe67b7933c6ab20075..1c66cd955326da97c35f8b395a0dfabb84f26c13 100644 --- a/src/CAD/IFox.CAD.Shared/ExtensionMethod/PointEx.cs +++ b/src/CAD/IFox.CAD.Shared/ExtensionMethod/PointEx.cs @@ -1,3 +1,6 @@ +using System; +using System.Web.WebSockets; + namespace IFoxCAD.Cad; public static class PointEx @@ -49,29 +52,26 @@ public static double GetAngle(this Point2d startPoint, Point2d endPoint) } /// - /// 获取中点 + /// 获取两个点之间的中点 /// - /// - /// - /// - public static Point2d GetMidPointTo(this Point2d a, Point2d b) + /// 第一点 + /// 第二点 + /// 返回两个点之间的中点 + public static Point2d GetMidPointTo(this Point2d point1, Point2d point2) { // (p1 + p2) / 2; // 溢出风险 - return new Point2d(a.X * 0.5 + b.X * 0.5, - a.Y * 0.5 + b.Y * 0.5); + return point1 + (point2 - point1) * 0.5; } /// /// 获取两个点之间的中点 /// - /// 第一点 - /// 第二点 + /// 第一点 + /// 第二点 /// 返回两个点之间的中点 - public static Point3d GetMidPointTo(this Point3d pt1, Point3d pt2) + public static Point3d GetMidPointTo(this Point3d point1, Point3d point2) { - return new(pt1.X * 0.5 + pt2.X * 0.5, - pt1.Y * 0.5 + pt2.Y * 0.5, - pt1.Z * 0.5 + pt2.Z * 0.5); + return point1 + (point2 - point1) * 0.5; } /// /// Z值归零 @@ -112,8 +112,6 @@ public static Point3d Point3d(this Point2d pt, double z = 0) return new(pt.X, pt.Y, z); } - - /// /// 根据世界坐标计算用户坐标 /// @@ -128,6 +126,7 @@ public static Point3d TransPoint(this Point3d basePt, Point3d userPt, Point3d tr var roMat = Matrix3d.Rotation(-ang, Vector3d.ZAxis, userPt); return transPt.TransformBy(roMat * transMat); } + /// /// 计算指定距离和角度的点 /// @@ -140,6 +139,7 @@ public static Point3d Polar(this Point3d pt, double ang, double len) { return pt + Vector3d.XAxis.RotateBy(ang, Vector3d.ZAxis) * len; } + /// /// 计算指定距离和角度的点 /// @@ -152,9 +152,11 @@ public static Point2d Polar(this Point2d pt, double ang, double len) { return pt + Vector2d.XAxis.RotateBy(ang) * len; } - /// http://www.lee-mac.com/bulgeconversion.html + + /// /// - /// 求凸度,判断三点是否一条直线上 + /// 求凸度,判断三点是否一条直线上
+ /// ///
/// 圆弧起点 /// 圆弧腰点 @@ -181,15 +183,142 @@ public static double GetArcBulge(this Point2d arc1, Point2d arc2, Point2d arc3, bulge = -1; break; default: + { + if (Math.Abs(bulge) < tol) + bulge = 0; + break; + } + } + return bulge; + } + + #region 两点间距离定数等分/定距等分 + /// + /// 两点距离定数等分 + /// + /// 第一个点 + /// 第二个点 + /// 等分数量;大于1 + /// 等分距离和所有等分点的集合 + public static DivideInfo GetNumberDivideTo(this Point3d point1, Point3d point2, int number) + { + if (number < 2) throw new Exception("等分数量应大于1"); + var lenght = point1.DistanceTo(point2) * 1.0 / number; + var angle = point1.GetAngle(point2); + var vector = (point2 - point1) / number; + var points = new List() { point1 }; + for (int i = 1; i < number; i++) + { + points.Add(point1 + vector * i); + } + points.Add(point2); + return new DivideInfo(DivideType.Number, lenght, points, angle); + } + + /// + /// 两点距离定距等分 + /// + /// 第一个点 + /// 第二个点 + /// 等分距离;大于0,且小于两点之间的距离 + /// 等分距离和所有等分点的集合 + public static DivideInfo GetDistanceDivideTo(this Point3d point1, Point3d point2, double distance) + { + var length = point1.DistanceTo(point2); + if (distance <= 0 || distance >= length) throw new Exception("等分距离应大于0,且小于两点间距离:{length}!"); + var angle = point1.GetAngle(point2); + var points = new List() { point1 }; + var vector = (point2 - point1) / length * distance; + var tempPoint = point1 + vector; + while (point1.DistanceTo(tempPoint) < length) + { + points.Add(tempPoint); + tempPoint += vector; + } + points.Add(point2); + return new DivideInfo(DivideType.Distance, distance, points, angle, tempPoint.DistanceTo(point2)); + } + #endregion 两点间距离定数等分/定距等分 + + #region 点集合转直线两端点对象的集合 + /// + /// 点集合转直线两端点的集合 + /// + /// 点的集合 + /// 是否是首尾相连,默认为:首尾不相连 + /// 首尾相连时,是否闭合,默认为:不闭合 + /// 直线两端点集合 + public static List? GetLine2PointList(this List points, bool isEndToEnd = false, + bool isClose = false) + { + if (points.Count < 2) return null; + var lst = new List(); + Point3d endPoint1, endPoint2, firstEndPoint; + var itor = points.GetEnumerator(); + if (isEndToEnd) + { + if (!itor.MoveNext()) return null; + firstEndPoint = endPoint1 = itor.Current; + while (itor.MoveNext()) { - if (Math.Abs(bulge) < tol) - bulge = 0; - break; + endPoint2 = itor.Current; + lst.Add(endPoint1, endPoint2); + endPoint1 = endPoint2; } + if (endPoint1 != firstEndPoint && isClose) lst.Add(endPoint1, firstEndPoint); } - return bulge; + else + { + while (itor.MoveNext()) + { + endPoint1 = itor.Current; + if (!itor.MoveNext()) return null; + endPoint2 = itor.Current; + lst.Add(endPoint1, endPoint2); + } + } + return lst; } + /// + /// 点集合转直线两端点对象的集合 + /// + /// 点集合 + /// 是否是首尾相连,默认为:首尾不相连 + /// 首尾相连时,是否闭合,默认为:不闭合 + /// 直线两端点集合 + public static List? GetLine2PointList(this List points, bool isEndToEnd = false, + bool isClose = false) + { + if (points.Count < 2) return null; + var lst = new List(); + Point2d endPoint1, endPoint2, firstEndPoint; + var itor = points.GetEnumerator(); + if (isEndToEnd) + { + if (!itor.MoveNext()) return null; + firstEndPoint = endPoint1 = itor.Current; + while (itor.MoveNext()) + { + endPoint2 = itor.Current; + lst.Add(endPoint1, endPoint2); + endPoint1 = endPoint2; + } + if (endPoint1 != firstEndPoint && isClose) lst.Add(endPoint1, firstEndPoint); + } + else + { + while (itor.MoveNext()) + { + endPoint1 = itor.Current; + if (!itor.MoveNext()) return null; + endPoint2 = itor.Current; + lst.Add(endPoint1, endPoint2); + } + } + return lst; + } + #endregion 点集合转直线两端点的集合 #region 首尾相连 /// diff --git a/src/CAD/IFox.CAD.Shared/ExtensionMethod/ReferenceTypes.cs b/src/CAD/IFox.CAD.Shared/ExtensionMethod/ReferenceTypes.cs new file mode 100644 index 0000000000000000000000000000000000000000..0f385e8f8af35a6457072548af4ad2721dacd184 --- /dev/null +++ b/src/CAD/IFox.CAD.Shared/ExtensionMethod/ReferenceTypes.cs @@ -0,0 +1,90 @@ +#if acad +using Autodesk.AutoCAD.Internal; +#endif +namespace IFoxCAD.Cad; + +#region PointBasals 引用对象类型 +#region 两点间距离等分所用对象 +/// +/// +/// 定数等分(定距等分)信息引用类(PointBasals Using) +/// +public class DivideInfo +{ + #region 构造函数 + /// + /// 构造函数 + /// + /// 等分类型 + /// 等分长度(定距等分不包含最后一段长度) + /// 等分点集合(含两端点) + /// 角度(弧度值) + /// 定距等分最后一段长度(定数等分最后一段长度与Dis一致) + public DivideInfo(DivideType type, double distance, List points, double angle, double lastDistance = double.NaN) + { + Type = type; + Distance = distance; + Points = points ?? throw new ArgumentNullException(nameof(points)); + LastDistance = type == DivideType.Number ? distance : lastDistance; + Angle = angle; + } + #endregion 构造函数 + + #region 公共属性 + /// + /// 等分类型 + /// + internal DivideType Type { get; } = DivideType.None; + + /// + /// 等分长度(定距等分不包含最后一段长度) + /// + internal double Distance { get; } = 0; + + /// + /// 等分点集合(含两端点) + /// + internal List Points { get; } = new(); + + /// + /// 定距等分最后一段长度(定数等分最后一段长度与Dis一致) + ///
+ /// 默认:与Dis一致 + ///
+ internal double LastDistance { get; } = double.NaN; + + /// + /// 角度 + /// + internal double Angle { get; } = double.NaN; + #endregion 公共属性 +} +#endregion 两点间距离等分所用对象 + +/// +/// 直线两端点对象(点表整理引用类) +/// +/// 直线的起始点 +/// 直线的结束点 +public record class LinePoint2d(Point2d StatrPoint, Point2d EndPoint); + +/// +/// 直线两端点对象(点表整理引用类) +/// +/// 直线的起始点 +/// 直线的结束点 +public record class LinePoint3d(Point3d StatrPoint, Point3d EndPoint); +#endregion PointBasals 引用对象类型 + +#if acad +/// +/// 快捷命令别名对象 +/// +/// 原命令别名 +/// 新命令别名 +/// 命令调用函数 +/// 是否移除原别名,默认:移除 +/// 是否覆盖已定义别名,默认:覆盖 +public record class CmdAlias(string OldAlias, string NewAlias, CommandCallback CmdAction, bool IsRemoveOld = true, bool IsReplace = true); +#endif + diff --git a/src/CAD/IFox.CAD.Shared/ExtensionMethod/Tools.cs b/src/CAD/IFox.CAD.Shared/ExtensionMethod/Tools.cs index b5b8f2c339ea48602c6aca5f459e0860035a69ec..bf3234581407bd080636399bd436a2ab5e2b6969 100644 --- a/src/CAD/IFox.CAD.Shared/ExtensionMethod/Tools.cs +++ b/src/CAD/IFox.CAD.Shared/ExtensionMethod/Tools.cs @@ -1,7 +1,12 @@ -using static IFoxCAD.Basal.Timer; +#if acad +using Autodesk.AutoCAD.Internal; +#endif +using static IFoxCAD.Basal.Timer; namespace IFoxCAD.Cad; - +/// +/// 工具类 +/// public static class Tools { /// @@ -57,7 +62,8 @@ public static void TestTimes3(int count, string message, Action action) public static void TestTimes(int count, string message, Action action, TimeEnum timeEnum = TimeEnum.Millisecond) { - var time = RunTime(() => { + var time = RunTime(() => + { for (int i = 0; i < count; i++) action.Invoke(); }, timeEnum); @@ -66,19 +72,45 @@ public static void TestTimes(int count, string message, Action action, switch (timeEnum) { case TimeEnum.Second: - timeNameZn = " 秒"; - break; + timeNameZn = " 秒"; + break; case TimeEnum.Millisecond: - timeNameZn = " 毫秒"; - break; + timeNameZn = " 毫秒"; + break; case TimeEnum.Microsecond: - timeNameZn = " 微秒"; - break; + timeNameZn = " 微秒"; + break; case TimeEnum.Nanosecond: - timeNameZn = " 纳秒"; - break; + timeNameZn = " 纳秒"; + break; } Env.Print($"{message} 代码执行 {count} 次的时间:{time} ({timeNameZn})"); } +#if acad + /// + /// 公共工具 + /// + public static class UtilsEx + { + /// + /// 快捷命令别名重定义 + /// + /// 快捷命令别名对象集合 + public static void ReSetCmds(params CmdAlias[] aliases) + { + foreach (var alias in aliases) + { + if (Utils.IsCommandDefined(alias.NewAlias) && !alias.IsReplace) return; + // 卸载原命令(卸载前前可判断命令是否已经定义) + if (Utils.IsCommandDefined(alias.OldAlias) && alias.IsRemoveOld) + { + Utils.RemoveCommand(alias.OldAlias, alias.OldAlias); + } + // 定义ReSet7命令调用Test777函数 + Utils.AddCommand(alias.NewAlias, alias.NewAlias, alias.NewAlias, CommandFlags.Modal, alias.CmdAction); + } + } + } +#endif } \ No newline at end of file