From f5c46d16638e246fb9cbec562a8569dc896baa0e Mon Sep 17 00:00:00 2001 From: ChenX Date: Thu, 8 Dec 2022 17:18:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=E5=9B=A0=E4=B8=BA=E5=B8=83?= =?UTF-8?q?=E5=B0=94=E9=94=99=E8=AF=AF=E5=AF=BC=E8=87=B4=E7=9A=84=E5=88=87?= =?UTF-8?q?=E5=89=B2=E9=94=99=E8=AF=AF=20fix=20#I650RU?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__snapshots__/bool5.test.ts.snap | 2 ++ __test__/Booloperate/bool5.test.ts | 14 ++++++++++ src/DatabaseServices/Contour.ts | 26 +++++++++++++------ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/__test__/Booloperate/__snapshots__/bool5.test.ts.snap b/__test__/Booloperate/__snapshots__/bool5.test.ts.snap index d50e704f7..604e8b6bf 100644 --- a/__test__/Booloperate/__snapshots__/bool5.test.ts.snap +++ b/__test__/Booloperate/__snapshots__/bool5.test.ts.snap @@ -1,5 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`交点被优化成单个点,导致点在曲线内,导致求交错误 1`] = `"68072.00000"`; + exports[`交点被优化成单个点,导致点在曲线外,导致求交错误 1`] = `"1260.00000"`; exports[`分裂的点在参数周围 1`] = `"5782.01322"`; diff --git a/__test__/Booloperate/bool5.test.ts b/__test__/Booloperate/bool5.test.ts index c5d179535..e9018b1cf 100644 --- a/__test__/Booloperate/bool5.test.ts +++ b/__test__/Booloperate/bool5.test.ts @@ -84,3 +84,17 @@ test('交点被优化成单个点,导致点在曲线外,导致求交错误', () for (let s of regs[0].ShapeManager.ShapeList) expect(s.Area).toMatchNumberSnapshot(); }); + + +test('交点被优化成单个点,导致点在曲线内,导致求交错误', () => +{ + let d = + { "file": [2, "Region", 8, 2, 102, false, 1, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -187, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -187, 0, 0, 1], 0, 2, 4, [314, 0], 0, [314, 536], 0, [187, 536], 0, [187, 0], 0, true, 0, "Region", 8, 2, 103, false, 1, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 535.9999999999998, 0, 1], 0, 0, true, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 535.9999999999998, 0, 1], 0, 2, 4, [0, 0], 0, [127.00000000000023, 0], 0, [127.00000000000023, 18], 0, [0, 18], 0, true, 0], "basePt": { "x": -18, "y": 0, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let regs = LoadRegionsFromFileData(d); + + regs[0].BooleanOper(regs[1], BoolOpeartionType.Subtract); + expect(regs[0].ShapeManager.ShapeList.length).toBe(1); + for (let s of regs[0].ShapeManager.ShapeList) + expect(s.Area).toMatchNumberSnapshot(); +}); diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index 72b7dd30c..c90e2b82e 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -331,11 +331,12 @@ export class Contour if (interPts.length <= 1) { + let areaState = sourceOutline.Area > targetOutline.Area; //反包含 - if (fastCurveInCurve2(targetOutline, sourceOutline) || equalCurve(targetOutline, sourceOutline)) + if ((!areaState && fastCurveInCurve2(targetOutline, sourceOutline, interPts[0]?.pt)) || equalCurve(targetOutline, sourceOutline)) return []; //包含 - if (fastCurveInCurve2(sourceOutline, targetOutline)) + if ((areaState && fastCurveInCurve2(sourceOutline, targetOutline, interPts[0]?.pt))) return [sourceOutline, targetOutline]; else//分离 return [sourceOutline]; @@ -438,11 +439,12 @@ export class Contour let pts = sourceOutline.IntersectWith2(con.Curve, IntersectOption.ExtendNone, COMBINE_FUZZ); if (pts.length <= 1) { + let areaState = sourceOutline.Area > targetOutline.Area; //反包含 - if (fastCurveInCurve2(targetOutline, sourceOutline) || equalCurve(targetOutline, sourceOutline)) + if ((!areaState && fastCurveInCurve2(targetOutline, sourceOutline, pts[0]?.pt)) || equalCurve(targetOutline, sourceOutline)) return { holes, subtractList }; //包含 - if (fastCurveInCurve2(sourceOutline, targetOutline)) + if (areaState && fastCurveInCurve2(sourceOutline, targetOutline, pts[0]?.pt)) holes.push(targetOutline); else//分离 { @@ -619,10 +621,18 @@ function fastCurveInCurve(bigCurve: Polyline | Circle, smallCurve: Curve): boole } //当交点小于等于1时 -export function fastCurveInCurve2(bigCurve: Polyline | Circle, smallCurve: Curve) +export function fastCurveInCurve2(bigCurve: Polyline | Circle, smallCurve: Curve, iPt?: Vector3) { - return bigCurve.PtInCurve(smallCurve.StartPoint) || - bigCurve.PtInCurve(smallCurve.Midpoint); + if (iPt)//提高准确性,避免使用交点去判断 导致的错误 + { + let sp = smallCurve.StartPoint;; + if (equalv3(sp, iPt, 1e-3)) + return bigCurve.PtInCurve(smallCurve.Midpoint); + else + return bigCurve.PtInCurve(smallCurve.StartPoint); + } + else + return bigCurve.PtInCurve(smallCurve.Midpoint) || bigCurve.PtInCurve(smallCurve.StartPoint); } //大曲线是否完全包含小曲线(或者重合) @@ -634,7 +644,7 @@ function CurveContainerCurve(bigCurve: Polyline | Circle, smallCurve: Polyline | if (ipts.length === 0) return fastCurveInCurve(bigCurve, smallCurve); else if (ipts.length === 1) - return fastCurveInCurve2(bigCurve, smallCurve); + return fastCurveInCurve2(bigCurve, smallCurve, ipts[0]); else return isTargetCurInOrOnSourceCur(bigCurve, smallCurve); }