diff --git a/src/IFoxCAD.Cad/ExtensionMethod/CurveEx.cs b/src/IFoxCAD.Cad/ExtensionMethod/CurveEx.cs index ba8f5d1850473fff80811854da3de62755267ec4..fd3bf8362e3840362e3c1ebaf25f0b42d3623322 100644 --- a/src/IFoxCAD.Cad/ExtensionMethod/CurveEx.cs +++ b/src/IFoxCAD.Cad/ExtensionMethod/CurveEx.cs @@ -644,7 +644,7 @@ public static EllipticalArc3d ToEllipticalArc3d(this Arc arc) public static NurbCurve3d ToNurbCurve3d(this Arc arc) { return new NurbCurve3d(ToEllipticalArc3d(arc)); - } + } #endregion Arc diff --git a/src/IFoxCAD.Cad/ExtensionMethod/EntityEx.cs b/src/IFoxCAD.Cad/ExtensionMethod/EntityEx.cs index 38efca400d715572ef61b7dc806b06a82d54a2ad..90e0dbb31369dcd899003a97599b01dd677f1620 100644 --- a/src/IFoxCAD.Cad/ExtensionMethod/EntityEx.cs +++ b/src/IFoxCAD.Cad/ExtensionMethod/EntityEx.cs @@ -232,5 +232,112 @@ public static string GetUnFormatString(this MText mt) return string.Join("", strs.ToArray()); } #endregion + + #region 圆弧 + + /// + /// 根据圆心、起点和终点来创建圆弧(二维) + /// + /// 圆弧对象 + /// 起点 + /// 圆心 + /// 终点 + /// 圆弧 + public static Arc CreateArcSCE(Point3d startPoint, Point3d centerPoint, Point3d endPoint) + { + Arc arc = new(); + arc.Center = centerPoint; + arc.Radius = centerPoint.DistanceTo(startPoint); + Vector2d startVector = new(startPoint.X - centerPoint.X, startPoint.Y - centerPoint.Y); + Vector2d endVector = new(endPoint.X - centerPoint.X, endPoint.Y - centerPoint.Y); + //计算起始和终止角度 + arc.StartAngle = startVector.Angle; + arc.EndAngle = endVector.Angle; + return arc; + } + /// + /// 三点法创建圆弧(二维) + /// + /// 圆弧对象 + /// 起点 + /// 圆弧上的点 + /// 终点 + /// 圆弧 + public static Arc CreateArc(Point3d startPoint, Point3d pointOnArc, Point3d endPoint) + { + //创建一个几何类的圆弧对象 + CircularArc3d geArc = new(startPoint, pointOnArc, endPoint); + //将几何类圆弧对象的圆心和半径赋值给圆弧 +#if ac2009 + return geArc.ToArc(); +#elif ac2013 + return (Arc)Curve.CreateFromGeCurve(geArc); +#endif + } + + /// + /// 根据起点、圆心和圆弧角度创建圆弧(二维) + /// + /// 圆弧对象 + /// 起点 + /// 圆心 + /// 圆弧角度 + /// 圆弧 + public static Arc CreateArc(Point3d startPoint, Point3d centerPoint, double angle) + { + Arc arc = new(); + arc.Center = centerPoint; + arc.Radius = centerPoint.DistanceTo(startPoint); + Vector2d startVector = new(startPoint.X - centerPoint.X, startPoint.Y - centerPoint.Y); + arc.StartAngle = startVector.Angle; + arc.EndAngle = startVector.Angle + angle; + return arc; + } + + #endregion + + #region 圆 + + /// + /// 两点创建圆(两点中点为圆心) + /// + /// 起点 + /// 终点 + /// + public static Circle CreateCircle(Point3d startPoint, Point3d endPoint) + { + Circle circle = new(); + circle.Center = startPoint.GetMidPointTo(endPoint); + circle.Radius = startPoint.DistanceTo(endPoint) * 0.5; + return circle; + } + + /// + /// 三点法创建圆(失败则返回Null) + /// + /// 第一点 + /// 第二点 + /// 第三点 + /// + public static Circle CreateCircle(Point3d pt1, Point3d pt2, Point3d pt3) + { + //先判断三点是否共线,得到pt1点指向pt2、pt2点的矢量 + Vector3d va = pt1.GetVectorTo(pt2); + Vector3d vb = pt1.GetVectorTo(pt3); + //如两矢量夹角为0或180度(π弧度),则三点共线. + if (va.GetAngleTo(vb) == 0 | va.GetAngleTo(vb) == Math.PI) + { + return null; + } + else + { + //创建一个几何类的圆弧对象 + CircularArc3d geArc = new(pt1, pt2, pt3); + geArc.ToCircle(); + return geArc.ToCircle(); + } + } + + #endregion } } diff --git a/src/IFoxCAD.Cad/ExtensionMethod/GeometryEx.cs b/src/IFoxCAD.Cad/ExtensionMethod/GeometryEx.cs index 46eee82feffaf3aba53c1e1071ed8c435214420d..1f15466440674f7099246d3b1c6cfa74f4f04ccd 100644 --- a/src/IFoxCAD.Cad/ExtensionMethod/GeometryEx.cs +++ b/src/IFoxCAD.Cad/ExtensionMethod/GeometryEx.cs @@ -58,7 +58,7 @@ public enum PointOnRegionType /// public static class GeometryEx { - + #region Point&Circle /// @@ -719,6 +719,27 @@ public static Point2d Point2d(this Point3d pt) return new Point2d(pt.X, pt.Y); } + /// + /// 将二维点转换为三维点 + /// + /// 二维点 + /// 三维点 + public static Point3d Point3d(this Point2d pt) + { + return new Point3d(pt.X, pt.Y, 0); + } + + /// + /// 获取两个点之间的中点 + /// + /// 第一点 + /// 第二点 + /// 返回两个点之间的中点 + public static Point3d GetMidPointTo(this Point3d pt1, Point3d pt2) + { + return new Point3d((pt1.X + pt2.X) * 0.5, (pt1.Y + pt2.Y) * 0.5, (pt1.Z + pt2.Z) * 0.5); + } + public static IEnumerable Point2d(this IEnumerable pts) { return pts.Select(pt => pt.Point2d()); diff --git a/src/IFoxCAD.Cad/ExtensionMethod/SymbolTableRecordEx.cs b/src/IFoxCAD.Cad/ExtensionMethod/SymbolTableRecordEx.cs index b3b98907174e38f06a83e4f0740ae173cd05d29f..2c874114b86d7a6b8084d4c3f99ae775878ee534 100644 --- a/src/IFoxCAD.Cad/ExtensionMethod/SymbolTableRecordEx.cs +++ b/src/IFoxCAD.Cad/ExtensionMethod/SymbolTableRecordEx.cs @@ -125,25 +125,11 @@ public static ObjectId AddCircle(this BlockTableRecord btr, Point3d center, doub /// 圆属性设置委托 /// 事务管理器 /// 三点有外接圆则返回圆的id,否则返回ObjectId.Null - public static ObjectId AddCircle(this BlockTableRecord btr, Point3d p0, Point3d p1, Point3d p2, Action action = default, Transaction trans = default) + public static ObjectId AddCircle(this BlockTableRecord btr, Point3d p0, Point3d p1, Point3d p2, + Action action = default, Transaction trans = default) { - var dx1 = p1.X - p0.X; - var dy1 = p1.Y - p0.Y; - var dx2 = p2.X - p0.X; - var dy2 = p2.Y - p0.Y; - - var d = dx1 * dy2 - dx2 * dy1; - - if (d != 0.0) - { - var d2 = d * 2; - var c1 = (p0.X + p1.X) * dx1 + (p0.Y + p1.Y) * dy1; - var c2 = (p0.X + p2.X) * dx2 + (p0.Y + p2.Y) * dy2; - var ce = new Point3d((c1 * dy2 - c2 * dy1) / d2, (c2 * dx1 - c1 * dx2) / d2, 0); - var circle = new Circle(ce, Vector3d.ZAxis, p0.DistanceTo(ce)); - return btr.AddEnt(circle, action, trans); - } - return ObjectId.Null; + Circle circle = EntityEx.CreateCircle(p0, p1, p2); + return circle is not null ? btr.AddEnt(circle, action, trans) : throw new ArgumentNullException(nameof(circle), "对象为 null"); } /// /// 在指定的绘图空间添加轻多段线 @@ -181,13 +167,8 @@ public static ObjectId AddPline(this BlockTableRecord btr, List pts, Li /// 圆弧id public static ObjectId AddArc(this BlockTableRecord btr, Point3d startPoint, Point3d pointOnArc, Point3d endPoint, Action action = default, Transaction trans = default) { - - var arc = new CircularArc3d(startPoint, pointOnArc, endPoint); -#if ac2009 - return btr.AddEnt(arc.ToArc(), action, trans); -#elif ac2013 - return btr.AddEnt(Curve.CreateFromGeCurve(arc) as Arc, action, trans); -#endif + var arc = EntityEx.CreateArc(startPoint, pointOnArc, endPoint); + return btr.AddEnt(arc, action, trans); } #endregion diff --git a/tests/DBTrans.test/Test.cs b/tests/DBTrans.test/Test.cs index ae6e9b8a3239383ab36ac87c7fdd488d111c55be..14e956b4bb4061201c6ce31b9931926fe6d2955c 100644 --- a/tests/DBTrans.test/Test.cs +++ b/tests/DBTrans.test/Test.cs @@ -69,7 +69,32 @@ public void Addent() public void drawarc() { using var tr = new DBTrans(); - tr.CurrentSpace.AddArc(new Point3d(0, 0, 0), new Point3d(1, 1, 0), new Point3d(2, 0, 0)); + Arc arc1 = EntityEx.CreateArcSCE(new Point3d(2, 0, 0), new Point3d(0, 0, 0), new Point3d(0, 2, 0));//起点,圆心,终点 + Arc arc2 = EntityEx.CreateArc(new Point3d(4, 0, 0), new Point3d(0, 0, 0), Math.PI / 2);//起点,圆心,弧度 + Arc arc3 = EntityEx.CreateArc(new Point3d(1, 0, 0), new Point3d(0, 0, 0), new Point3d(0, 1, 0));//起点,圆上一点,终点 + tr.CurrentSpace.AddEntity(arc1, arc2, arc3); + tr.CurrentSpace.AddArc(new Point3d(0, 0, 0), new Point3d(1, 1, 0), new Point3d(2, 0, 0));//起点,圆上一点,终点 + } + + [CommandMethod("drawcircle")] + public void draCircle() + { + using var tr = new DBTrans(); + Circle circle1 = EntityEx.CreateCircle(new Point3d(0, 0, 0), new Point3d(1, 0, 0));//起点,终点 + Circle circle2 = EntityEx.CreateCircle(new Point3d(-2, 0, 0), new Point3d(2, 0, 0), new Point3d(0, 2, 0));//三点画圆,成功 + Circle circle3 = EntityEx.CreateCircle(new Point3d(-2, 0, 0), new Point3d(0, 0, 0), new Point3d(2, 0, 0));//起点,圆心,终点,失败 + tr.CurrentSpace.AddEntity(circle1, circle2); + if (circle3 is not null) + { + tr.CurrentSpace.AddEntity(circle3); + } + else + { + tr.Editor.WriteMessage("三点画圆失败"); + } + tr.CurrentSpace.AddEntity(circle3); + tr.CurrentSpace.AddCircle(new Point3d(0, 0, 0), new Point3d(1, 1, 0), new Point3d(2, 0, 0));//三点画圆,成功 + tr.CurrentSpace.AddCircle(new Point3d(0, 0, 0), new Point3d(1, 1, 0), new Point3d(2, 2, 0));//起点,圆上一点,终点(共线) } [CommandMethod("layertest")]