From be1c50d0abfd07a425dd4ae7295b67813457edd6 Mon Sep 17 00:00:00 2001 From: ChenX Date: Wed, 19 Feb 2020 23:07:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BD=AE=E5=BB=93=E5=B8=83?= =?UTF-8?q?=E5=B0=94=E8=BF=90=E7=AE=97=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Booloperate/bool4.test.ts | 3 +- src/DatabaseServices/Contour.ts | 76 +++++++++++++++--------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/__test__/Booloperate/bool4.test.ts b/__test__/Booloperate/bool4.test.ts index f30c4b34a..c0f845f71 100644 --- a/__test__/Booloperate/bool4.test.ts +++ b/__test__/Booloperate/bool4.test.ts @@ -29,7 +29,8 @@ test(`#I118PO`, () => }); test(`#I16PA6`, () => { - let d = [2, "Region", 6, 2, 102, false, 1, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, 1, 1, 1, 1, "Polyline", 6, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, 2, 4, [0, 0], 0, [268, 0], 0, [268, 18], 0, [0, 18], 0, true, 0, "Region", 6, 2, 103, false, 1, 2, 0, [0, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 268.0018656456669, 309.4999930386355, 0, 1], 0, 0, true, 1, 1, 1, 1, "Polyline", 6, 2, 0, false, 0, 7, 0, [0, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 268.0018656456669, 309.4999930386355, 0, 1], 0, 0, true, 2, 5, [0, 0], 0, [582.9999860772712, 0.0037312913331012574], 0, [581.9999860772712, 268.0037312913331], 0, [199, 268], 0.4152503874339878, [0, 68], 0, true, 0]; + let d = + [2, "Region", 6, 2, 102, false, 1, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, 1, 1, 1, 1, "Polyline", 6, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, 2, 4, [0, 0], 0, [268, 0], 0, [268, 18], 0, [0, 18], 0, true, 0, "Region", 6, 2, 103, false, 1, 2, 0, [0, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 268.0018656456669, 309.4999930386355, 0, 1], 0, 0, true, 1, 1, 1, 1, "Polyline", 6, 2, 0, false, 0, 7, 0, [0, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 268.0018656456669, 309.4999930386355, 0, 1], 0, 0, true, 2, 5, [0, 0], 0, [582.9999860772712, 0.0037312913331012574], 0, [581.9999860772712, 268.0037312913331], 0, [199, 268], 0.4152503874339878, [0, 68], 0, true, 0]; let [reg1, reg2] = LoadRegionsFromFileData(d); let reg = reg1.Clone(); diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index 8781e0139..bfa21fd42 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -1,9 +1,9 @@ import { Vector3 } from "three"; -import { arrayLast, arrayRemoveDuplicateBySort, arrayRemoveIf } from "../Common/ArrayExt"; +import { arrayLast, arrayRemoveDuplicateBySort } from "../Common/ArrayExt"; import { curveLinkGroup, equalCurve } from "../Common/CurveUtils"; import { Status } from "../Common/Status"; import { FixIndex } from "../Common/Utils"; -import { equaln, equalv2, equalv3, rotatePoint } from "../Geometry/GeUtils"; +import { equaln, equalv2, equalv3 } from "../Geometry/GeUtils"; import { RegionParse, Route } from "../Geometry/RegionParse"; import { isTargetCurInOrOnSourceCur } from "../GraphicsSystem/BoolOperateUtils"; import { IntersectOption } from "../GraphicsSystem/IntersectWith"; @@ -192,6 +192,8 @@ export class Contour let sourceOutline = this._Curve; let targetOutline = target.Curve; + let isEqualNormal = equalv3(sourceOutline.Normal, targetOutline.Normal, 1e-3); + let interPts = sourceOutline.IntersectWith2(targetOutline, IntersectOption.OnBothOperands); let sourceContainerTarget = this.CuInOutline(targetOutline); @@ -220,56 +222,44 @@ export class Contour let sourceCus: Array = sourceOutline.GetSplitCurves(pars1); let targetCus: Array = targetOutline.GetSplitCurves(pars2); - //是否有相等的曲线 - let hasEqualCus = false; - //共同线段是否连接2区域 - let disLink = false; - for (let pl of sourceCus) { - //在目标分离曲线数组从若有相等的曲线,且相等的线段不连接2区域,则直接加入合并和相交集合中 - //在目标数组中就直接跳过不在添加,在2轮廓有共线部分时需此判断 - hasEqualCus = targetCus.some(l => fastEqualCurve(pl, l)); - if (hasEqualCus) + let hasEqualCus = false; + for (let i = 0; i < targetCus.length; i++) { - //获得共有线段中点2侧的点,判断是否有存在2区域外的点 - let tmpPt = pl.GetPointAtParam(0.5); - let tmpDerv = rotatePoint(pl.GetFistDeriv(0.5).normalize(), Math.PI / 2); - let sidePts = [tmpPt.clone().add(tmpDerv), tmpPt.add(tmpDerv.negate())]; - disLink = sidePts.some(p => !sourceOutline.PtInCurve(p) && !targetOutline.PtInCurve(p)); - if (disLink) + let cu = targetCus[i]; + hasEqualCus = fastEqualCurve(cu, pl); + if (hasEqualCus) { - unionList.push(pl); - intersectionList.push(pl); - continue; + //方向相同 + if ( + equalv3(cu.GetFistDeriv(cu.EndParam * 0.5).normalize(), pl.GetFistDeriv(pl.EndParam * 0.5).normalize(), 1e-3) + === isEqualNormal + ) + { + unionList.push(pl); + intersectionList.push(pl); + } + targetCus.splice(i, 1); + break; } } + if (hasEqualCus) + continue; + if (target.CuInOutline(pl)) - { intersectionList.push(pl); - } else - { unionList.push(pl); - } } for (let pl of targetCus) { - let hasEqualCus = sourceCus.some(l => fastEqualCurve(pl, l)); - if (hasEqualCus && disLink) - { - continue; - } if (this.CuInOutline(pl)) - { intersectionList.push(pl); - } else - { unionList.push(pl); - } } //特殊的分离 @@ -285,6 +275,8 @@ export class Contour let sourceOutline = this._Curve as Polyline; let targetOutline = target.Curve as Polyline; + let isEqualNormal = equalv3(sourceOutline.Normal, targetOutline.Normal, 1e-3); + let interPts = sourceOutline.IntersectWith2(targetOutline, IntersectOption.OnBothOperands, 1e-3); if (interPts.length <= 1) @@ -307,14 +299,22 @@ export class Contour for (let pl of sourceCus) { let hasEqualCus = false; - arrayRemoveIf(targetCus, cu => + for (let i = 0; i < targetCus.length; i++) { - if (hasEqualCus) return false; + let cu = targetCus[i]; hasEqualCus = fastEqualCurve(cu, pl); - if (hasEqualCus && !equalv3(cu.GetFistDeriv(cu.EndParam * 0.5).normalize(), pl.GetFistDeriv(pl.EndParam * 0.5).normalize(), 1e-3)) + if (hasEqualCus && + (!equalv3(cu.GetFistDeriv(cu.EndParam * 0.5).normalize(), pl.GetFistDeriv(pl.EndParam * 0.5).normalize(), 1e-3)) + === isEqualNormal) + { subtractList.push(pl); - return hasEqualCus; - }); + targetCus.splice(i, 1); + } + + if (hasEqualCus) + break; + } + if (hasEqualCus) continue;