diff --git a/__test__/Polyline/Fillet.test.ts b/__test__/Polyline/Fillet.test.ts index 179f77620..6ec15f9fc 100644 --- a/__test__/Polyline/Fillet.test.ts +++ b/__test__/Polyline/Fillet.test.ts @@ -372,3 +372,100 @@ test('多段线平行倒圆弧', () => excepeRes(fres); } }); + +test('多段线直线和圆弧相切,并且在首尾处', () => +{ + { + let f = [1, "Polyline", 8, 2, 3358, false, 1, 1, 0, [0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 4572.503603653264, 0, -1025.8597191053223, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1636.8326377559497, -1209.8835630879712, 255.60719131636785, 1], 0, 2, 6, [647.4999999527496, 270.0000000050004], -0.33167926674619835, [764.893568829822, 182.49999997788927], 0, [857.5, 182.5], 0, [857.5, 240], 0, [955, 240], 0, [955, 270], 0, true]; + let pl = LoadEntityFromFileData(f)[0] as Polyline; + let fillet = new FilletUtils(); + fillet.FilletRadius = 10; + let pts = [new Vector3(4302.503603649588, 0, -296.95034325705024), new Vector3(4326.785097238886, 0, -305.1519667893942)]; + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + expect(fres.cu1.Area).toMatchNumberSnapshot(); + } + } + + { + + let f = [1, "Polyline", 8, 2, 3356, false, 1, 1, 0, [0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 4572.503603653264, 0, -1025.8597191053223, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1636.8326377559497, -1209.8835630879712, 255.60719131636785, 1], 0, 2, 6, [437.5, 182.5], 0, [530.1064311810001, 182.5], -0.3316792664686957, [647.4999999527496, 270.0000000050004], 0, [340, 270], 0, [340, 240], 0, [437.5, 240], 0, true]; + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(4302.503603649214, 0, -436.8107418459585), new Vector3(4314.621003826209, 0, -431.48157577814334)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + expect(fres.cu1.Area).toMatchNumberSnapshot(); + } + + } + + { + let f = [1, "Polyline", 8, 2, 3355, false, 1, 1, 0, [0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 4572.503603653264, 0, -1025.8597191053223, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1636.8326377559497, -1209.8835630879712, 255.60719131636785, 1], 0, 2, 7, [647.500000003, 25.000000005000402], 0, [770, 25], 0, [955, 25], 0, [955, 55], 0, [857.5, 55], 0, [857.5, 112.5], 0, [764.8935688091792, 112.49999996287397], -0.33167926646869544, true]; + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(4523.222110064215, 0, -305.15196679821355), new Vector3(4547.503603651624, 0, -296.0319382205405)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + expect(fres.cu1.Area).toMatchNumberSnapshot(); + } + } + + { + + let f = [1, "Polyline", 8, 2, 3357, false, 1, 1, 0, [0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 4572.503603653264, 0, -1025.8597191053223, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1636.8326377559497, -1209.8835630879712, 255.60719131636785, 1], 0, 2, 7, [437.5, 112.5], 0, [437.5, 55], 0, [340, 55], 0, [340, 25], 0, [525, 25], 0, [647.500000008995, 25.000000005000402], -0.3316792665321118, [530.1064311810001, 112.5], 0, true]; + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(4523.222110052992, 0, -451.56747142027535), new Vector3(4547.503603650764, 0, -439.60971910082475)]; + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + expect(fres.cu1.Area).toMatchNumberSnapshot(); + } + + } +}); diff --git a/__test__/Polyline/__snapshots__/Fillet.test.ts.snap b/__test__/Polyline/__snapshots__/Fillet.test.ts.snap index b2010820a..e3cbccaa3 100644 --- a/__test__/Polyline/__snapshots__/Fillet.test.ts.snap +++ b/__test__/Polyline/__snapshots__/Fillet.test.ts.snap @@ -12,6 +12,14 @@ exports[`多段线平行倒圆弧 2`] = `"4206.03357"`; exports[`多段线平行倒圆弧 3`] = `"4255.49457"`; +exports[`多段线直线和圆弧相切,并且在首尾处 1`] = `"13410.53343"`; + +exports[`多段线直线和圆弧相切,并且在首尾处 2`] = `"13410.53342"`; + +exports[`多段线直线和圆弧相切,并且在首尾处 3`] = `"13410.53342"`; + +exports[`多段线直线和圆弧相切,并且在首尾处 4`] = `"13410.53342"`; + exports[`自交多段线 1`] = `"7791.00495"`; exports[`自交多段线 2`] = `"9003.48566"`; diff --git a/src/Add-on/FilletUtils.ts b/src/Add-on/FilletUtils.ts index 8387cb956..c8373d5bf 100644 --- a/src/Add-on/FilletUtils.ts +++ b/src/Add-on/FilletUtils.ts @@ -9,7 +9,7 @@ import { Line } from "../DatabaseServices/Entity/Line"; import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { Spline } from "../DatabaseServices/Spline"; import { PromptEntityResult, PromptPointResult } from "../Editor/PromptResult"; -import { angle, AsVector2, equalv3, isIntersect2, isParallelTo, midPoint } from "../Geometry/GeUtils"; +import { angle, AsVector2, equaln, equalv3, isIntersect2, isParallelTo, midPoint } from "../Geometry/GeUtils"; import { Orbit } from "../Geometry/Orbit"; import { IntersectOption } from "../GraphicsSystem/IntersectWith"; @@ -307,7 +307,7 @@ export class FilletUtils let keepF1 = 0; if (parF2 + 1 <= pln.LineData.length) { - if (parF1 === 0 || pln.GetBuilgeAt(parF1 - 1) == 0) + if (parF1 === 0 || equaln(pln.GetBuilgeAt(parF1 - 1), 0)) pln.AddVertexAt(parF2 + 1, sp); else { @@ -709,7 +709,7 @@ export class FilletUtils } /** - * 计算直线与圆弧没有交点的情况下倒角结果. + * 计算直线与圆弧没有交点(或相切)的情况下倒角结果 * @param enRes1 * @param enRes2 * @returns line and cir @@ -762,34 +762,52 @@ export class FilletUtils let lineClone = line.Clone(); let arcClone = arc.Clone(); + let lineExtend: ExtendType; let p1Param = line.GetParamAtPoint(arcP1); if (p1Param > param) + { lineClone.StartPoint = arcP1; + lineExtend = ExtendType.Start; + } else + { lineClone.EndPoint = arcP1; + lineExtend = ExtendType.End; + } //裁剪圆弧 let arcParam = arc.GetParamAtPoint(arcP2); let arcDerv = arc.GetFistDeriv(arcParam).normalize(); let narcDerv = narc.GetFistDeriv(1).normalize(); + let arcExtend: ExtendType; if (equalv3(arcDerv, narcDerv)) + { arcClone.StartPoint = arcP2; + arcExtend = ExtendType.Start; + } else + { arcClone.EndPoint = arcP2; + arcExtend = ExtendType.End; + } //先选直线为真 if (enRes1.Entity === line) return { cu1: lineClone, + cu1Extend: lineExtend, cu2: arcClone, + cu2Extend: arcExtend, arc: narc }; else return { cu1: arcClone, + cu1Extend: arcExtend, cu2: lineClone, - arc: narc + cu2Extend: lineExtend, + arc: narc.Reverse()//#I3BWIA 避免起点和终点方向相反导致的多段线连接错误 }; } diff --git a/src/Add-on/SetSmoothEdge/SetSmoothEdgeFace.ts b/src/Add-on/SetSmoothEdge/SetSmoothEdgeFace.ts index 767ca9339..26234308d 100644 --- a/src/Add-on/SetSmoothEdge/SetSmoothEdgeFace.ts +++ b/src/Add-on/SetSmoothEdge/SetSmoothEdgeFace.ts @@ -1,14 +1,14 @@ -import { BoardGetFace, GetSideFaceMtx, BoardFaceType, MatrixIsCoplane2 } from "../../Geometry/DrillParse/BoardGetFace"; -import { Curve } from "../../DatabaseServices/Entity/Curve"; -import { equaln, equalv3 } from "../../Geometry/GeUtils"; -import { Arc } from "../../DatabaseServices/Entity/Arc"; -import { GetBoardSealingCurves, GetBoardHighSeal, HandleRectBoardSealingData } from "../../GraphicsSystem/CalcEdgeSealing"; -import { Face } from "../../Geometry/DrillParse/Face"; import { Box3, Matrix4, Vector3 } from "three"; -import { Polyline } from "../../DatabaseServices/Entity/Polyline"; +import { Arc } from "../../DatabaseServices/Entity/Arc"; import { Board } from "../../DatabaseServices/Entity/Board"; +import { Curve } from "../../DatabaseServices/Entity/Curve"; +import { Polyline } from "../../DatabaseServices/Entity/Polyline"; import { Box3Ext } from "../../Geometry/Box"; -import { ISmoothEdgeOption, IHighSealedItem } from "../../UI/Store/BoardInterface"; +import { BoardFaceType, BoardGetFace, GetSideFaceMtx } from "../../Geometry/DrillParse/BoardGetFace"; +import { Face } from "../../Geometry/DrillParse/Face"; +import { equaln, equalv3 } from "../../Geometry/GeUtils"; +import { GetBoardHighSeal, GetBoardSealingCurves, HandleRectBoardSealingData } from "../../GraphicsSystem/CalcEdgeSealing"; +import { IHighSealedItem, ISmoothEdgeOption } from "../../UI/Store/BoardInterface"; class SetSmoothEdgeFaces extends BoardGetFace {