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")]