From 7699ec767bef0d1c45b7ebba26c228b3bbe1ce05 Mon Sep 17 00:00:00 2001 From: ZoeLeeFZ Date: Tue, 25 Dec 2018 10:33:14 +0800 Subject: [PATCH] =?UTF-8?q?!224=20=E4=BF=AE=E5=A4=8D=E5=B7=AE=E9=9B=86bug?= =?UTF-8?q?=20Merge=20pull=20request=20!224=20from=20ZoeLeeFZ/fixSub2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Booloperate/bool.test.ts | 7 +++ src/Common/CurveUtils.ts | 7 +-- src/DatabaseServices/Contour.ts | 88 ++++++++++++++++++++++++++----- 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/__test__/Booloperate/bool.test.ts b/__test__/Booloperate/bool.test.ts index 555ddc654..55b295aed 100644 --- a/__test__/Booloperate/bool.test.ts +++ b/__test__/Booloperate/bool.test.ts @@ -114,6 +114,13 @@ test("多都有洞面域,互不相交", () => expect(regs.length).toBe(3); testRegionsBool(regs, 3, 3, 0, 0, 1, 1); }) +test("有问题面域测试", () => +{ + let data = + [2, "Region", 1, 1, 7, false, 7, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 995.4564695921745, 866.7576945200351, 0, 1], 1, 1, 1, 1, "Polyline", 1, 1, 0, false, 7, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 995.4564695921745, 866.7576945200351, 0, 1], 2, 12, [1151.784316715255, 505.6870652512325], 0, [-48.215683284744955, 505.6870652512325], 0, [-48.215683284744955, 436.3728364140229], 0, [-322.28257444753535, 436.3728364140229], 0, [-322.28257444753535, 255.1386559489065], 0, [-48.215683284744955, 255.13865594890694], 0, [-48.215683284744955, 160.58169222797642], 0, [-310.4629539824191, 160.58169222797642], 0, [-310.4629539824191, -12.772741260395605], 0, [-48.215683284744955, -12.772741260395605], 0, [-48.215683284744955, -94.31293474876725], 0, [1151.784316715255, -94.31293474876725], 0, true, 0, "Region", 1, 1, 6, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -983.721937321937, -229.2831908831909, 0, 1], 1, 1, 1, 1, "Polyline", 1, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -983.721937321937, -229.2831908831909, 0, 1], 2, 5, [1966.4056656537157, 1219.4025937658553], 0, [2139.7600991420877, 1219.4025937658553], 0, [2139.7600991420877, 1275.3802040368082], 0, [1966.4056656537157, 1275.3802040368082], 0, [1966.4056656537157, 1219.4025937658553], 0, true, 0] + let regs = LoadRegionsFromFileData(data); + testRegionsBool(regs, 1, 0, 1, 0, 2, 0); +}) function testRegion(reg) { if (reg) diff --git a/src/Common/CurveUtils.ts b/src/Common/CurveUtils.ts index cfef7747a..3d9c5210f 100644 --- a/src/Common/CurveUtils.ts +++ b/src/Common/CurveUtils.ts @@ -178,8 +178,7 @@ export function curveLinkGroup(cus: Curve[]): Array> export function equalCurveAndCurve(cu1: Curve, cu2: Curve) { - - if (cu1.EndParam !== cu2.EndParam || !equaln(cu1.Area, cu2.Area)) return false; + if (cu1.EndParam !== cu2.EndParam || !equaln(cu1.Length, cu2.Length)) return false; let parAtPl2 = cu2.GetParamAtPoint(cu1.StartPoint); if ((cu1 instanceof Polyline) && (cu2 instanceof Polyline)) @@ -200,7 +199,9 @@ export function equalCurveAndCurve(cu1: Curve, cu2: Curve) return ptsAndBuls1.pts.every((pt, i) => { - return equalv2(pt, pts2[i]); + return equalv3( + Vec2DTo3D(pt).applyMatrix4(cu1.OCS), + Vec2DTo3D(pts2[i]).applyMatrix4(cu2.OCS)); }) } else if (cu1 instanceof Circle && cu2 instanceof Circle) diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index cff81be9b..c4e23d6e7 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -76,13 +76,13 @@ export class Contour //交集:结果数组为空则失败 IntersectionBoolOperation(target: Contour): Contour[] { - let resultCus = this.getOperatedCurves(target); + let resultCus = this.getIntersetAndUnionList(target); return Contour.GetAllContour(resultCus.intersectionList); } //并集:结果数组长度大于2,则失败.等于1则成功. UnionBoolOperation(target: Contour): Contour[] { - let resultCus = this.getOperatedCurves(target); + let resultCus = this.getIntersetAndUnionList(target); //并集后的线段表如果有共线的直接合并起来 let cus: Curve[] = []; for (let pl of resultCus.unionList) @@ -112,22 +112,21 @@ export class Contour //差集:等于0完全被减去 SubstactBoolOperation(target: Contour): Contour[] { - let resultCus = this.getOperatedCurves(target); - return Contour.GetAllContour(resultCus.subtractList); + let subtractList = this.getSubtractList(target); + return Contour.GetAllContour(subtractList); } /** * 计算与目标轮廓布尔运算后的结果曲线. * * @private * @param {Contour} target 目标轮廓 - * @returns {intersectionList //交集曲线表, unionList //并集曲线表, subtractList 差集曲线表} + * @returns {intersectionList //交集曲线表, unionList //并集曲线表} * @memberof Contour */ - getOperatedCurves(target: Contour) + getIntersetAndUnionList(target: Contour) { let intersectionList: Curve[] = []; let unionList: Curve[] = []; - let subtractList: Curve[] = []; let sourceOutline = this.m_Curve; let targetOutline = target.Curve; @@ -140,7 +139,6 @@ export class Contour if (sourceContainerTarget)//源包含目标 { intersectionList.push(targetOutline); - subtractList.push(sourceOutline, targetOutline); unionList.push(sourceOutline); } else if (targetContainerSource)//目标包含源 @@ -151,7 +149,6 @@ export class Contour else if (interPts.length === 0)//分离 { unionList.push(sourceOutline, targetOutline); - subtractList.push(sourceOutline); } else//相交 interPts.length > 0 { @@ -192,7 +189,6 @@ export class Contour } else { - subtractList.push(pl); unionList.push(pl); } } @@ -207,7 +203,6 @@ export class Contour if (this.CuInOutline(pl)) { intersectionList.push(pl); - subtractList.push(pl); } else { @@ -215,9 +210,78 @@ export class Contour } } } - return { intersectionList, unionList, subtractList }; + return { intersectionList, unionList }; } + getSubtractList(target: Contour) + { + let subtractList: Curve[] = []; + + let sourceOutline = this.m_Curve; + let targetOutline = target.Curve; + let interPts = sourceOutline.IntersectWith(targetOutline, IntersectOption.OnBothOperands); + + let sourceContainerTarget = this.CuInOutline(targetOutline); + let targetContainerSource = target.CuInOutline(sourceOutline); + + //包含.相交.分离(三种状态) + if (sourceContainerTarget && interPts.length === 0)//源包含目标 + { + subtractList.push(sourceOutline, targetOutline); + } + else if (targetContainerSource)//目标包含源 + { + return []; + } + else if (interPts.length === 0)//分离 + { + subtractList.push(sourceOutline); + } + else//相交 interPts.length > 0 + { + let pars1 = interPts.map(p => sourceOutline.GetParamAtPoint(p)); + let pars2 = interPts.map(p => targetOutline.GetParamAtPoint(p)); + let sourceCus: Array = sourceOutline.GetSplitCurves(pars1); + let targetCus: Array = targetOutline.GetSplitCurves(pars2); + + //是否有相等的曲线 + let hasEqualCus = false; + let equalCus: WeakSet = new WeakSet(); + + for (let pl of sourceCus) + { + //有一样的曲线直接跳过 + hasEqualCus = targetCus.some(l => + { + if (equalCurveAndCurve(pl, l)) + { + equalCus.add(l); + return true; + } + return false; + }); + if (hasEqualCus) + continue; + + if (!target.CuInOutline(pl)) + { + subtractList.push(pl); + } + } + + for (let pl of targetCus) + { + if (equalCus.has(pl)) + continue; + + if (this.CuInOutline(pl)) + { + subtractList.push(pl); + } + } + } + return subtractList; + } /** * 获得全部闭合曲线 * @若传入二维曲线数据,将默认子数组为闭合曲线段