From 55c103a9f2b4a949be97e52ad711a1c6731839bb Mon Sep 17 00:00:00 2001 From: yupeng_dyp Date: Sat, 13 Jan 2024 00:14:09 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=A4=AD=E5=9C=86=E8=BE=B9=E7=95=8C=EF=BC=8C?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E4=B8=8D=E6=94=AF=E6=8C=81=E8=BE=B9=E7=95=8C?= =?UTF-8?q?=E4=B8=AD=E5=8C=85=E5=90=AB=E5=A4=9A=E6=9D=A1=E5=A4=9A=E6=AE=B5?= =?UTF-8?q?=E7=BA=BF=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=88=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E9=82=A3=E4=B8=AA=E6=9C=89=E9=97=AE=E9=A2=98=E9=87=8D=E6=96=B0?= =?UTF-8?q?=20PR=20=E4=B8=80=E4=B8=8B=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yupeng_dyp --- .../HatchConverter.cs" | 186 ++++++++++-------- 1 file changed, 104 insertions(+), 82 deletions(-) diff --git "a/src/CAD/IFox.CAD.Shared/ExtensionMethod/\346\226\260\345\273\272\345\241\253\345\205\205/HatchConverter.cs" "b/src/CAD/IFox.CAD.Shared/ExtensionMethod/\346\226\260\345\273\272\345\241\253\345\205\205/HatchConverter.cs" index 9e16d24..ab8edf4 100644 --- "a/src/CAD/IFox.CAD.Shared/ExtensionMethod/\346\226\260\345\273\272\345\241\253\345\205\205/HatchConverter.cs" +++ "b/src/CAD/IFox.CAD.Shared/ExtensionMethod/\346\226\260\345\273\272\345\241\253\345\205\205/HatchConverter.cs" @@ -1,8 +1,4 @@ -namespace IFoxCAD.Cad; - - -using System.Data; -using PointV = Point2d; +namespace IFoxCAD.Cad; /// /// 填充边界转换器 @@ -15,7 +11,7 @@ public class HatchConverter /// class CircleData { - public PointV Center; + public Point2d Center; public double Radius; /// @@ -23,21 +19,29 @@ class CircleData /// /// 对称点1 /// 对称点2 - public CircleData(PointV symmetryAxisPoint1, PointV symmetryAxisPoint2) + public CircleData(Point2d symmetryAxisPoint1, Point2d symmetryAxisPoint2) { Center = PointEx.GetMidPointTo(symmetryAxisPoint1, symmetryAxisPoint2); Radius = symmetryAxisPoint1.GetDistanceTo(symmetryAxisPoint2) * 0.5; } } + /// + /// 段段线顶点 + /// + class PolyLineVertexes : List + { + } + /// /// 填充转换器的数据 /// class HatchConverterData { - public List PolyLineData; + public List PolyLineData; public List CircleData; public List SplineData; + public List EllipseData; /// /// 填充转换器的数据 @@ -47,6 +51,7 @@ public HatchConverterData() PolyLineData = new(); CircleData = new(); SplineData = new(); + EllipseData = new(); } } #endregion @@ -167,7 +172,6 @@ static void HatchLoopIsPolyline(HatchLoop loop, HatchConverterData hcData) ArgumentNullEx.ThrowIfNull(loop); ArgumentNullEx.ThrowIfNull(hcData); - // 判断为圆形: // 上下两个圆弧,然后填充,就会生成此种填充 // 顶点数是3,凸度是半圆,两个半圆就是一个圆形 @@ -180,8 +184,10 @@ static void HatchLoopIsPolyline(HatchLoop loop, HatchConverterData hcData) { // 遍历多段线信息 var bvc = loop.Polyline; + var bvws = new PolyLineVertexes(); for (int i = 0; i < bvc.Count; i++) - hcData.PolyLineData.Add(new BulgeVertexWidth(bvc[i])); + bvws.Add(new BulgeVertexWidth(bvc[i])); + hcData.PolyLineData.Add(bvws); } } @@ -231,38 +237,79 @@ static void HatchLoopIsPolyline(HatchLoop loop, HatchConverterData hcData) /// 收集图元信息 static void HatchLoopIsCurve2d(HatchLoop loop, HatchConverterData hcData) { - // 取每一段曲线,曲线可能是直线来的,但是圆弧会按照顶点来分段 - int curveIsClosed = 0; + int curveIsClosed = 0; // 取每一段曲线,曲线可能是直线来的,但是圆弧会按照顶点来分段 + bool newPline = true; // 是否开始新的多段线(一个边界中可能有多条多段线) + bool firstIsPline = false; //遍历边界的第一个子段为多段线(遍历时不一定从多段线的首段开始) + PolyLineVertexes? bvws = null; // 遍历边界的多个子段 foreach (Curve2d curve in loop.Curves) { // 计数用于实现闭合 curveIsClosed++; - if (curve is NurbCurve2d spl) - { - // 判断为样条曲线: - hcData.SplineData.Add(spl); - continue; - } - var pts = curve.GetSamplePoints(3); - var midPt = pts[1]; - if (curve.StartPoint.IsEqualTo(curve.EndPoint, new Tolerance(1e-6, 1e-6)))// 首尾相同,就是圆形 + if (curve is CircularArc2d or LineSegment2d) { - // 判断为圆形: - // 获取起点,然后采样三点,中间就是对称点(直径点) - hcData.CircleData.Add(new CircleData(curve.StartPoint, midPt)); + var pts = curve.GetSamplePoints(3); + var midPt = pts[1]; + + // 判断为多段线圆: + // 首尾相同,就是圆形 + if (curve.StartPoint.IsEqualTo(curve.EndPoint, new Tolerance(1e-6, 1e-6))) + { + // 获取起点,然后采样三点,中间就是对称点(直径点) + hcData.CircleData.Add(new CircleData(curve.StartPoint, midPt)); + // 添加在中部的多段线末尾点 + if (curveIsClosed > 1 && !newPline) + bvws?.Add(new BulgeVertexWidth(curve.StartPoint, 0)); + // 开始新的多段线 + newPline = true; + continue; + } + + if (curveIsClosed == 1) + firstIsPline = true; + + if (newPline) + { + bvws = new PolyLineVertexes(); + hcData.PolyLineData.Add(bvws); + newPline = false; + } + + // 判断为多段线,圆弧或直线: + double bulge = curve.StartPoint.GetArcBulge(midPt, curve.EndPoint); + bvws?.Add(new BulgeVertexWidth(curve.StartPoint, bulge)); + + // 末尾点,不闭合的情况下就要获取这个 + if (curveIsClosed == loop.Curves.Count) + { + if (firstIsPline && hcData.PolyLineData.Count > 1) + { + // 连接首尾多段线 + hcData.PolyLineData[0].ForEach(bvw => hcData.PolyLineData[^1].Add(bvw)); + hcData.PolyLineData.RemoveAt(0); + } + else + bvws?.Add(new BulgeVertexWidth(curve.EndPoint, 0)); + } + continue; } - // 判断为多段线,圆弧: - double bulge = curve.StartPoint.GetArcBulge(midPt, curve.EndPoint); - hcData.PolyLineData.Add(new BulgeVertexWidth(curve.StartPoint, bulge)); + // 判断为样条曲线: + if (curve is NurbCurve2d spl) + hcData.SplineData.Add(spl); + + // 判断为椭圆: + if (curve is EllipticalArc2d ellipse) + hcData.EllipseData.Add(ellipse); - // 末尾点,不闭合的情况下就要获取这个 - if (curveIsClosed == loop.Curves.Count) - hcData.PolyLineData.Add(new BulgeVertexWidth(curve.EndPoint, 0)); + // 添加在中部的多段线末尾点 + if (curveIsClosed > 1 && !newPline) + bvws?.Add(new BulgeVertexWidth(curve.StartPoint, 0)); + // 开始新的多段线 + newPline = true; } } @@ -273,70 +320,45 @@ static void HatchLoopIsCurve2d(HatchLoop loop, HatchConverterData hcData) [Obsolete("使用带返回值的CreateBoundary替代")] public void CreateBoundary(List outEnts) { + outEnts.AddRange(CreateBoundary()); + } + + /// + /// 创建边界图元 + /// + /// + public List CreateBoundary() + { + var outEnts = new List(); for (int i = 0; i < _hcDatas.Count; i++) { var data = _hcDatas[i]; // 生成边界:多段线 - if (data.PolyLineData.Count > 0) + data.PolyLineData.ForEach(bvws => { - Polyline pl = new(); + if (bvws.Count == 0) return; + var pl = new Polyline(); pl.SetDatabaseDefaults(); - for (int j = 0; j < data.PolyLineData.Count; j++) - { - pl.AddVertexAt(j, - data.PolyLineData[j].Vertex, - data.PolyLineData[j].Bulge, - data.PolyLineData[j].StartWidth, - data.PolyLineData[j].EndWidth); - } + for (int j = 0; j < bvws.Count; j++) + pl.AddVertexAt(j, bvws[j].Vertex, bvws[j].Bulge, bvws[j].StartWidth, bvws[j].EndWidth); outEnts.Add(pl); - } - - // 生成边界:圆 - data.CircleData.ForEach(item => - { - outEnts.Add(new Circle(item.Center.Point3d(), Vector3d.ZAxis, item.Radius)); }); - // 生成边界:样条曲线 - data.SplineData.ForEach(item => - { - outEnts.Add(item.ToCurve()); - }); - } - - if (_oldHatch is not null) - { - outEnts.ForEach(ent => + // 生成边界:椭圆 + data.EllipseData.ForEach(item => { - ent.Color = _oldHatch.Color; - ent.Layer = _oldHatch.Layer; + var startParam = item.IsClockWise ? -item.EndAngle : item.StartAngle; + var endParam = item.IsClockWise ? -item.StartAngle : item.EndAngle; + var ellipse = new Ellipse( + item.Center.Point3d(), + Vector3d.ZAxis, + item.MajorAxis.Convert3d() * item.MajorRadius, + item.MinorRadius / item.MajorRadius, + Math.Atan2(Math.Sin(startParam) * item.MinorRadius, Math.Cos(startParam) * item.MajorRadius), + Math.Atan2(Math.Sin(endParam) * item.MinorRadius, Math.Cos(endParam) * item.MajorRadius)); + outEnts.Add(ellipse); }); - } - } - public List CreateBoundary() - { - List outEnts = new List(); - for (int i = 0; i < _hcDatas.Count; i++) - { - var data = _hcDatas[i]; - - // 生成边界:多段线 - if (data.PolyLineData.Count > 0) - { - Polyline pl = new(); - pl.SetDatabaseDefaults(); - for (int j = 0; j < data.PolyLineData.Count; j++) - { - pl.AddVertexAt(j, - data.PolyLineData[j].Vertex, - data.PolyLineData[j].Bulge, - data.PolyLineData[j].StartWidth, - data.PolyLineData[j].EndWidth); - } - outEnts.Add(pl); - } // 生成边界:圆 data.CircleData.ForEach(item => -- Gitee