From 694d641e4e00b647c5d72c573a59b0a8d7839c1e Mon Sep 17 00:00:00 2001 From: ChenX Date: Wed, 18 Mar 2020 15:17:50 +0800 Subject: [PATCH] =?UTF-8?q?!824=20=E4=BF=AE=E5=A4=8D:=E5=B8=83=E5=B0=94?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E5=92=8C=E6=8B=89=E4=BC=B8=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__snapshots__/bool4.test.ts.snap | 6 +- __test__/Booloperate/bool4.test.ts | 9 ++ __test__/Geometry/EdgeGeometry.test.ts | 14 +++ .../__snapshots__/EdgeGeometry.test.ts.snap | 4 + src/DatabaseServices/Contour.ts | 2 +- src/DatabaseServices/Entity/Curve.ts | 3 + src/DatabaseServices/Entity/Polyline.ts | 7 ++ src/Geometry/ExtrudeEdgeGeometry2.ts | 85 +++++++++---------- 8 files changed, 80 insertions(+), 50 deletions(-) diff --git a/__test__/Booloperate/__snapshots__/bool4.test.ts.snap b/__test__/Booloperate/__snapshots__/bool4.test.ts.snap index 431291a97..52dfa7e84 100644 --- a/__test__/Booloperate/__snapshots__/bool4.test.ts.snap +++ b/__test__/Booloperate/__snapshots__/bool4.test.ts.snap @@ -1,11 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`#I16PA6 1`] = `4823.998963178016`; +exports[`#I16PA6 1`] = `4824`; -exports[`#I16PA6 2`] = `4823.998421751374`; +exports[`#I16PA6 2`] = `4824`; exports[`#I118PO 1`] = `6298.780447492156`; exports[`交点大于等于2_但是还是分离 1`] = `310430.5057844047`; exports[`交点大于等于2_但是还是分离 2`] = `40090.549687200226`; + +exports[`共线多余点 1`] = `618903.9999999995`; diff --git a/__test__/Booloperate/bool4.test.ts b/__test__/Booloperate/bool4.test.ts index c0f845f71..c77790ce3 100644 --- a/__test__/Booloperate/bool4.test.ts +++ b/__test__/Booloperate/bool4.test.ts @@ -45,3 +45,12 @@ test(`#I16PA6`, () => expect(reg.ShapeManager.ShapeCount).toBe(1); expect(reg.Area).toMatchSnapshot(); }); + +test('共线多余点', () => +{ + let d = + { "file": [2, "Region", 8, 2, 142, false, 1, 7, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1187.6342759146728, 857.8612440191389, 1], 0, 0, true, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1187.6342759146728, 857.8612440191389, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1187.6342759146728, 857.8612440191389, 1], 0, 0, true, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1187.6342759146728, 857.8612440191389, 1], 0, 2, 4, [0, 0], 0, [304, 0], 0, [304, 2164], 0, [0, 2164], 0, true, 0, "Region", 8, 2, 143, false, 1, 7, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1187.6342759146728, 857.8612440191389, 1], 0, 0, true, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1187.6342759146728, 857.8612440191389, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 1, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1187.6342759146728, 857.8612440191389, 1], 0, 0, true, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1187.6342759146728, 857.8612440191389, 1], 0, 2, 6, [285.9999999999998, 0], 0, [291.9999999999998, 0], 0, [303.9999999999998, 0], 0, [303.9999999999998, 2164], 0, [291.99999999999983, 2164], 0, [285.9999999999998, 2164.0000000000005], 0, true, 0], "basePt": { "x": 0, "y": -1187.6342759146728, "z": 857.8612440191389 } }; + let [reg1, reg2] = LoadRegionsFromFileData(d); + reg1.BooleanOper(reg2.Clone(), BoolOpeartionType.Subtract); + expect(reg1.Area).toMatchSnapshot(); +}); diff --git a/__test__/Geometry/EdgeGeometry.test.ts b/__test__/Geometry/EdgeGeometry.test.ts index 36a87f2a9..eb0a90ae7 100644 --- a/__test__/Geometry/EdgeGeometry.test.ts +++ b/__test__/Geometry/EdgeGeometry.test.ts @@ -42,3 +42,17 @@ test('Geometry构建测试', () => expect(builder.edgeAndLidBuilder.verticesArray.length).toMatchSnapshot(); } }); + +test('极限共线', () => +{ + let d = + { "file": [1, "Board", 8, 2, 100, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 99.18801430379972, -19.70604624960106, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 99.18801430379972, -19.70604624960106, 0, 1], 0, 2, 2164, 304, 18, true, "Polyline", 8, 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, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [304, 0], 0, [304, 2164], 0, [0, 2164], 0, true, 3, 2, 2164.0000000000005, 18, 5, true, "Polyline", 8, 2, 0, false, 0, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -285.9999999999998, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -285.9999999999998, 0, 0, 1], 0, 2, 6, [285.9999999999998, 0], 0, [291.9999999999998, 0], 0, [303.9999999999998, 0], 0, [303.9999999999998, 2164], 0, [291.99999999999983, 2164], 0, [285.9999999999998, 2164.0000000000005], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 99.18801430379972, 266.2939537503987, 0, 1], 2, 829, 12, 9, true, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -291.9999999999998, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -291.9999999999998, 0, 0, 1], 0, 2, 4, [291.9999999999998, 0], 0, [303.9999999999998, 0], 0, [303.9999999999998, 829], 0, [291.9999999999998, 829], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 108.18801430379972, 272.2939537503987, 0, 1], 2, 928.9999999999998, 12, 9, true, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -291.9999999999998, -1234.9999999999993, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -291.9999999999998, -1234.9999999999993, 0, 1], 0, 2, 4, [303.9999999999998, 1234.9999999999993], 0, [303.9999999999998, 2163.999999999999], 0, [291.9999999999998, 2163.999999999999], 0, [291.9999999999998, 1234.9999999999993], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 108.18801430379972, 272.2939537503987, 1234.9999999999993, 1], 3, 0, 0, 0, 9, 1, "立板", "进门鞋柜", "下柜", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 99.18801430379972, "y": -19.70604624960106, "z": 0 } }; + + let brs = LoadBoardsFromFileData(d); + for (let br of brs) + { + let builder = new ExtrudeGeometryBuilder(br); + expect(builder.verticesArray.length).toMatchSnapshot(); + expect(builder.edgeAndLidBuilder.verticesArray.length).toMatchSnapshot(); + } +}); diff --git a/__test__/Geometry/__snapshots__/EdgeGeometry.test.ts.snap b/__test__/Geometry/__snapshots__/EdgeGeometry.test.ts.snap index 0e397d362..5b1215d98 100644 --- a/__test__/Geometry/__snapshots__/EdgeGeometry.test.ts.snap +++ b/__test__/Geometry/__snapshots__/EdgeGeometry.test.ts.snap @@ -47,3 +47,7 @@ exports[`Geometry构建测试 18`] = `1344`; exports[`Geometry构建测试 19`] = `2232`; exports[`Geometry构建测试 20`] = `1584`; + +exports[`极限共线 1`] = `432`; + +exports[`极限共线 2`] = `360`; diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index bfa21fd42..38f590b8a 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -431,7 +431,7 @@ function fastEqualCurve(c1: Curve, c2: Curve, tolerance = 1e-3) )) return false; - return equalv3(c1.GetPointAtParam(c1.EndParam * 0.5), c2.GetPointAtParam(c2.EndParam * 0.5), tolerance); + return equalv3(c1.Midpoint, c2.Midpoint, tolerance); } diff --git a/src/DatabaseServices/Entity/Curve.ts b/src/DatabaseServices/Entity/Curve.ts index ed670b020..7be932a96 100644 --- a/src/DatabaseServices/Entity/Curve.ts +++ b/src/DatabaseServices/Entity/Curve.ts @@ -50,6 +50,9 @@ export abstract class Curve extends Entity get StartParam(): number { return; } get EndPoint(): Vector3 { return; } set EndPoint(v: Vector3) { return; } + + /** 曲线中点 */ + get Midpoint() { return this.GetPointAtParam(0.5); } get EndParam(): number { return; } get Area(): number { return 0; } /** diff --git a/src/DatabaseServices/Entity/Polyline.ts b/src/DatabaseServices/Entity/Polyline.ts index 571e78e61..d2d4f9489 100644 --- a/src/DatabaseServices/Entity/Polyline.ts +++ b/src/DatabaseServices/Entity/Polyline.ts @@ -349,6 +349,13 @@ export class Polyline extends Curve this.SetPointAt(this.EndParam, AsVector2(p)); } + get Midpoint() + { + if (this.EndParam === 1) + return this.GetPointAtParam(0.5); + return this.GetPointAtDistance(this.Length * 0.5); + } + get CurveCount(): number { return this.EndParam; diff --git a/src/Geometry/ExtrudeEdgeGeometry2.ts b/src/Geometry/ExtrudeEdgeGeometry2.ts index 0b24fded4..86dd5cc7f 100644 --- a/src/Geometry/ExtrudeEdgeGeometry2.ts +++ b/src/Geometry/ExtrudeEdgeGeometry2.ts @@ -957,58 +957,44 @@ function Parse(cu1: ExtureContourCurve, cu2: ExtureContourCurve, reverseParse = c2Curves.push({ startParam: n1.argParam, endParam: n2.argParam, startPoint: n1.pt, endPoint: n2.pt }); } - function IsNeighbor(c: CurveSeg, endParam: number): boolean - { - let a = c.startParam; - let b = c.endParam; - if (a > b) - b += endParam; - return b - a < 1.0001; - } //分析共边关系和包含关系 for (let c of c1Curves) { - if (IsNeighbor(c, cu1.EndParam)) + let c1MidPoint = CenterPoint(cu1, c.startParam, c.endParam); + for (let c2 of c2Curves) { - let c1CenParam = CenterParam(c.startParam, c.endParam, cu1.EndParam); - for (let c2 of c2Curves) - { - if (c2.used || !IsNeighbor(c2, cu2.EndParam)) - continue; + if (c2.used) + continue; - let c2CenParam = CenterParam(c2.startParam, c2.endParam, cu2.EndParam); + let c2MidPoint = CenterPoint(cu2, c2.startParam, c2.endParam); + if (!equalv3(c1MidPoint, c2MidPoint)) + continue; - c.used = true; - if (c.startPoint === c2.startPoint - && c.endPoint === c2.endPoint - && equalv3(cu1.GetPointAtParam(c1CenParam), cu2.GetPointAtParam(c2CenParam)) - ) - { - c1Res.syntropy.push([c.startParam, c.endParam]); - c2Res.syntropy.push([c2.startParam, c2.endParam]); - c2.used = true; - break; - } - else if (c.startPoint === c2.endPoint - && c.endPoint === c2.startPoint - && equalv3(cu1.GetPointAtParam(c1CenParam), cu2.GetPointAtParam(c2CenParam)) - ) - { - c1Res.reverse.push([c.startParam, c.endParam]); - c2Res.reverse.push([c2.startParam, c2.endParam]); - c2.used = true; - break; - } - else - c.used = false; + c.used = true; + if (c.startPoint === c2.startPoint + && c.endPoint === c2.endPoint) + { + c1Res.syntropy.push([c.startParam, c.endParam]); + c2Res.syntropy.push([c2.startParam, c2.endParam]); + c2.used = true; + break; + } + else if (c.startPoint === c2.endPoint + && c.endPoint === c2.startPoint) + { + c1Res.reverse.push([c.startParam, c.endParam]); + c2Res.reverse.push([c2.startParam, c2.endParam]); + c2.used = true; + break; } + else + c.used = false; } if (!c.used) { - let p = cu1.GetPointAtParam(CenterParam(c.startParam, c.endParam, cu1.EndParam)); - if (cu2.PtInCurve(p)) + if (cu2.PtInCurve(c1MidPoint)) c1Res.container.push([c.startParam, c.endParam]); else c1Res.outer.push([c.startParam, c.endParam]); @@ -1020,24 +1006,29 @@ function Parse(cu1: ExtureContourCurve, cu2: ExtureContourCurve, reverseParse = for (let c of c2Curves) { if (c.used) continue; - let p = cu2.GetPointAtParam(CenterParam(c.startParam, c.endParam, cu2.EndParam)); + let p = CenterPoint(cu2, c.startParam, c.endParam); if (cu1.PtInCurve(p)) c2Res.container.push([c.startParam, c.endParam]); else c2Res.outer.push([c.startParam, c.endParam]); } - return [c1Res, c2Res]; } -function CenterParam(start: number, end: number, all: number) +function CenterPoint(cu: ExtureContourCurve, start: number, end: number) { + let lenStart = cu.GetDistAtParam(start); + let lenEnd = cu.GetDistAtParam(end); if (end > start) - return (end + start) * 0.5; + return cu.GetPointAtDistance((lenEnd + lenStart) * 0.5); - let sum = (all - start + end) * 0.5 + start; - if (sum > all) return sum - all; - return sum; + let lenAll = cu.Length; + let lenDiv = ((lenAll - lenStart) + lenEnd) * 0.5; + + if (lenStart + lenDiv >= lenAll) + return cu.GetPointAtDistance(lenStart + lenDiv - lenAll); + else + return cu.GetPointAtDistance(lenStart + lenDiv); }