diff --git a/__test__/Booloperate/__snapshots__/bool5.test.ts.snap b/__test__/Booloperate/__snapshots__/bool5.test.ts.snap index 37500ff83..54a14ceb7 100644 --- a/__test__/Booloperate/__snapshots__/bool5.test.ts.snap +++ b/__test__/Booloperate/__snapshots__/bool5.test.ts.snap @@ -3,3 +3,11 @@ exports[`差集共线(圆) 1`] = `442426.78778792813`; exports[`差集问题 1`] = `546438.8158863322`; + +exports[`弧形板差集 1`] = `165548.3611026407`; + +exports[`弧形板差集 2`] = `331151.31923948776`; + +exports[`弧形板差集2 1`] = `165548.36022878048`; + +exports[`弧形板差集2 2`] = `331151.3192394876`; diff --git a/__test__/Booloperate/bool5.test.ts b/__test__/Booloperate/bool5.test.ts index ba828e021..73d1e9aea 100644 --- a/__test__/Booloperate/bool5.test.ts +++ b/__test__/Booloperate/bool5.test.ts @@ -23,3 +23,24 @@ test('差集问题', () => expect(regs[0].Explode().length).toBe(16); expect(regs[0].Area).toMatchSnapshot(); }); + +test("弧形板差集", () => +{ + let d = { "file": [2, "Region", 8, 2, 239, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7164.031205116695, -312.3853909685172, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7164.031205116695, -312.3853909685172, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7164.031205116695, -312.3853909685172, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7164.031205116695, -312.3853909685172, 0, 1], 0, 2, 4, [1488.2724956409866, -403.9906338621595], 0, [1556.769411177408, -276.18933276551024], 0.25108720252037403, [-1817.9873510282487, -276.1893327618018], 0, [-1749.4904354922473, -403.99063385883346], -0.25108720252039435, true, 0, "Region", 8, 2, 238, false, 1, 7, 0, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6729.018004950986, -356.8947148198645, 0, 1], 0, 0, true, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6729.018004950986, -356.8947148198645, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 4, 0, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6729.018004950986, -356.8947148198645, 0, 1], 0, 0, true, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6729.018004950986, -356.8947148198645, 0, 1], 0, 2, 4, [0, 0], 0, [145.0094999623654, 0], 0, [145.0094999623654, 18], 0, [0, 18], 0, true, 0], "basePt": { "x": -8982.018556144943, "y": -716.3760248306767, "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(2); + for (let s of regs[0].ShapeManager.ShapeList) + expect(s.Area).toMatchSnapshot(); +}); +test("弧形板差集2", () => +{ + let d = { "file": [2, "Region", 8, 2, 237, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -6781.659977097809, -1502.9438267095907, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -6781.659977097809, -1502.9438267095907, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -6781.659977097809, -1502.9438267095907, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -6781.659977097809, -1502.9438267095907, 0, 1], 0, 2, 4, [1488.2724956409866, -403.9906338621595], 0, [1556.769411177408, -276.18933276551024], 0.25108720252037403, [-1817.9873510282487, -276.1893327618018], 0, [-1749.4904354922473, -403.99063385883346], -0.25108720252039435, true, 0, "Region", 8, 2, 236, false, 1, 7, 0, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6346.646776932101, -1547.453150560938, 0, 1], 0, 0, true, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6346.646776932101, -1547.453150560938, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 4, 0, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6346.646776932101, -1547.453150560938, 0, 1], 0, 0, true, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6346.646776932101, -1547.453150560938, 0, 1], 0, 2, 4, [0, 0], 0, [144.9994999623654, 0], 0, [144.9994999623654, 18], 0, [0, 18], 0, true, 0], "basePt": { "x": -8599.647328126059, "y": -1906.9344605717502, "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(2); + for (let s of regs[0].ShapeManager.ShapeList) + expect(s.Area).toMatchSnapshot(); +}); diff --git a/__test__/CurveUtils/PolylineSpliteRect.test.ts b/__test__/CurveUtils/PolylineSpliteRect.test.ts new file mode 100644 index 000000000..fa8445071 --- /dev/null +++ b/__test__/CurveUtils/PolylineSpliteRect.test.ts @@ -0,0 +1,91 @@ +import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util"; +import { PolylineSpliteRect } from "../../src/Common/CurveUtils"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; + +describe("封闭多段线分割矩形测试", () => +{ + test("轮廓1", () => + { + let data = { "file": [1, "Polyline", 8, 2, 176, false, 1, 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, 9, [8387.713348727397, 1084.5343505247351], 0, [7226.765061171589, 1084.5343505247351], 0, [7226.765061171589, 829.0146317325472], 0, [4632.684437781331, 829.0146317325472], 0, [4632.684437781331, 1078.9795740292527], 0, [5965.830796697095, 1078.9795740292527], 0, [5965.830796697095, 1301.1706338485465], 0, [8387.713348727397, 1301.1706338485465], 0, [8387.713348727397, 1084.5343505247351], 0, false], "basePt": { "x": 4632.684437781331, "y": 829.0146317325472, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let pl = LoadCurvesFromFileData(data) as Polyline[]; + + let cons = PolylineSpliteRect(pl[0]); + + expect(cons.length).toBe(3); + + for (let c of cons) + expect(c.Area).toMatchSnapshot(); + + }); + test("轮廓2", () => + { + let data = { "file": [1, "Polyline", 8, 2, 209, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5376.119285317616, -2438.550333164698, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 17, [0, 0], 0, [0, -2396.493624880947], 0, [774.4127870794337, -2396.493624880947], 0, [774.4127870794337, -805.8079000691391], 0, [1852.3116663926985, -805.8079000691391], 0, [1852.3116663926985, -1789.521440413283], 0, [2972.0706963589055, -1789.521440413283], 0, [2972.0706963589055, -1088.3639169765001], 0, [4029.0395003456997, -1088.3639169765001], 0, [4029.0395003456997, -2155.797758626529], 0, [4719.731986119246, -2155.797758626529], 0, [4719.731986119246, -1517.4304611691587], 0, [7095.295535673724, -1517.4304611691587], 0, [7095.295535673724, -690.6924857735476], 0, [4426.7109315486505, -690.6924857735476], 0, [4426.7109315486505, 0], 0, [0, 0], 0, false], "basePt": { "x": 5376.119285317616, "y": -4835.043958045645, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let pl = LoadCurvesFromFileData(data) as Polyline[]; + + let cons = PolylineSpliteRect(pl[0]); + + expect(cons.length).toBe(7); + + for (let c of cons) + expect(c.Area).toMatchSnapshot(); + + }); + test("轮廓3", () => + { + let data = { "file": [1, "Polyline", 8, 2, 204, false, 1, 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, 13, [6757.27535177342, -889.6497705352106], 0, [8091.75010660756, -889.6497705352106], 0, [8091.75010660756, -490.4058330764652], 0, [6922.134064474898, -490.4058330764652], 0, [6922.134064474898, -259.85651707916213], 0, [5668.170711611516, -259.85651707916213], 0, [5668.170711611516, -479.1595249790362], 0, [4577.27882616086, -479.1595249790362], 0, [4577.27882616086, -889.6497705352106], 0, [5898.729096631669, -889.6497705352106], 0, [5898.729096631669, -658.1101316379868], 0, [6757.27535177342, -658.1101316379868], 0, [6757.27535177342, -889.6497705352106], 0, false], "basePt": { "x": 4577.27882616086, "y": -889.6497705352106, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let pl = LoadCurvesFromFileData(data) as Polyline[]; + + let cons = PolylineSpliteRect(pl[0]); + + expect(cons.length).toBe(5); + + for (let c of cons) + expect(c.Area).toMatchSnapshot(); + + }); + test("轮廓4", () => + { + let data = { "file": [1, "Polyline", 8, 2, 187, false, 1, 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, 7, [-93.87293003759919, -1554.1191971829958], 0, [-93.87293003759919, -706.4182647686482], 0, [1667.016560471175, -706.4182647686482], 0, [1667.016560471175, -993.8361774756588], 0, [2743.9241827657966, -993.8361774756588], 0, [2743.9241827657966, -1554.1191971829958], 0, [-93.87293003759919, -1554.1191971829958], 0, false], "basePt": { "x": -93.87293003759919, "y": -1554.1191971829958, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let pl = LoadCurvesFromFileData(data) as Polyline[]; + + let cons = PolylineSpliteRect(pl[0]); + + expect(cons.length).toBe(2); + + for (let c of cons) + expect(c.Area).toMatchSnapshot(); + + }); + test("轮廓5", () => + { + let data = { "file": [1, "Polyline", 8, 2, 216, false, 1, 3, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2422.6764429900863, -452.7252899848789, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2422.6764429900863, -452.7252899848789, 0, 1], 0, 2, 6, [784.7209559691166, 681.8216720645796], 0, [193.7209559691164, 681.8216720645796], 0, [193.7209559691164, 663.8216720645796], 0, [1173, 663.8216720645796], 0, [1173, 672.8216720645801], 0, [784.7209559691164, 672.8216720645801], 0, true], "basePt": { "x": 2616.3973989592027, "y": 211.09638207970073, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let pl = LoadCurvesFromFileData(data) as Polyline[]; + + let cons = PolylineSpliteRect(pl[0]); + + expect(cons.length).toBe(2); + + for (let c of cons) + expect(c.Area).toMatchSnapshot(); + + }); + test("轮廓6", () => + { + let data = { "file": [1, "Polyline", 8, 2, 226, false, 1, 3, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1095.4517523011439, -5530.527123641856, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1095.4517523011439, -5530.527123641856, 0, 1], 0, 2, 8, [749.147341015374, 360.98889708156776], 0, [740.147341015374, 360.98889708156776], 0, [740.1473410153737, 582], 0, [731.147341015374, 582], 0, [731.1473410153742, 0], 0, [740.1473410153849, 0], 0, [740.1473410153849, 168.38705445030928], 0, [749.147341015374, 168.38705445030945], 0, true], "basePt": { "x": 1826.5990933165178, "y": -5530.527123641856, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let pl = LoadCurvesFromFileData(data) as Polyline[]; + + let cons = PolylineSpliteRect(pl[0]); + + expect(cons.length).toBe(2); + + for (let c of cons) + expect(c.Area).toMatchSnapshot(); + + }); +}); diff --git a/__test__/CurveUtils/__snapshots__/PolylineSpliteRect.test.ts.snap b/__test__/CurveUtils/__snapshots__/PolylineSpliteRect.test.ts.snap new file mode 100644 index 000000000..9adddfe95 --- /dev/null +++ b/__test__/CurveUtils/__snapshots__/PolylineSpliteRect.test.ts.snap @@ -0,0 +1,43 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`封闭多段线分割矩形测试 轮廓1 1`] = `333239.8526794412`; + +exports[`封闭多段线分割矩形测试 轮廓1 2`] = `595357.6812453549`; + +exports[`封闭多段线分割矩形测试 轮廓1 3`] = `251503.5221472336`; + +exports[`封闭多段线分割矩形测试 轮廓2 1`] = `1855875.3072621506`; + +exports[`封闭多段线分割矩形测试 轮廓2 2`] = `868579.4324262962`; + +exports[`封闭多段线分割矩形测试 轮廓2 3`] = `2003832.7922209054`; + +exports[`封闭多段线分割矩形测试 轮廓2 4`] = `1150366.7076290324`; + +exports[`封闭多段线分割矩形测试 轮廓2 5`] = `857299.1800571308`; + +exports[`封闭多段线分割矩形测试 轮廓2 6`] = `429306.6921083182`; + +exports[`封闭多段线分割矩形测试 轮廓2 7`] = `1963968.5993822813`; + +exports[`封闭多段线分割矩形测试 轮廓3 1`] = `447800.4779338776`; + +exports[`封闭多段线分割矩形测试 轮廓3 2`] = `145204.1154134143`; + +exports[`封闭多段线分割矩形测试 轮廓3 3`] = `341919.1493761451`; + +exports[`封闭多段线分割矩形测试 轮廓3 4`] = `103826.90503283963`; + +exports[`封闭多段线分割矩形测试 轮廓3 5`] = `466962.1139759575`; + +exports[`封闭多段线分割矩形测试 轮廓4 1`] = `1492707.6629829132`; + +exports[`封闭多段线分割矩形测试 轮廓4 2`] = `603373.0545650794`; + +exports[`封闭多段线分割矩形测试 轮廓5 1`] = `10638`; + +exports[`封闭多段线分割矩形测试 轮廓5 2`] = `3494.5113962781616`; + +exports[`封闭多段线分割矩形测试 轮廓6 1`] = `5238`; + +exports[`封闭多段线分割矩形测试 轮廓6 2`] = `1733.4165836796165`; diff --git a/src/Common/CurveUtils.ts b/src/Common/CurveUtils.ts index 7e8b9fb2f..25514ac0d 100644 --- a/src/Common/CurveUtils.ts +++ b/src/Common/CurveUtils.ts @@ -8,7 +8,7 @@ import { Polyline } from '../DatabaseServices/Entity/Polyline'; import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline'; import { Count } from '../Geometry/Count'; import { CurveMap, Vertice } from '../Geometry/CurveMap'; -import { AsVector2, AsVector3, equaln, equalv2, equalv3, isParallelTo, ZeroVec } from '../Geometry/GeUtils'; +import { AsVector2, AsVector3, equaln, equalv2, equalv3, isParallelTo, ZeroVec, XAxis, YAxis, isIntersect } from '../Geometry/GeUtils'; import { Orbit } from '../Geometry/Orbit'; import { PlaneExt } from '../Geometry/Plane'; import { IntersectOption, IntersectResult } from '../GraphicsSystem/IntersectWith'; @@ -684,3 +684,84 @@ export function Pts2Polyline(pts: (Vector3 | Vector2)[], isClose: boolean) } return pl; } + +const PolylineSpliteRectFuzz = 1e-3; +/**封闭多段线 分割成矩形 */ +export function PolylineSpliteRect(outline: Polyline): Polyline[] +{ + if (!outline.IsClose || IsRect(outline).isRect) + return [outline]; + + let firstDerv = outline.GetFistDeriv(0).normalize(); + if (!isParallelTo(firstDerv, XAxis, PolylineSpliteRectFuzz) && !isParallelTo(firstDerv, YAxis, PolylineSpliteRectFuzz)) return [outline]; + + let cus = outline.Explode(); + let yCus: Curve[] = []; + + for (let c of cus) + { + let derv = c.GetFistDeriv(0).normalize(); + if (isParallelTo(derv, YAxis, PolylineSpliteRectFuzz)) + yCus.push(c); + else + if (!isParallelTo(derv, XAxis, PolylineSpliteRectFuzz) || c instanceof Arc) + { + console.log(derv.clone().cross(XAxis).lengthSq()); + return [outline]; + } + } + + yCus.sort((c1, c2) => c1.StartPoint.x - c2.StartPoint.x); + + + let rects: Polyline[] = []; + + for (let i = 0; i < yCus.length - 1; i++) + { + let c1 = yCus[i]; + let c2 = yCus[i + 1]; + + let x1 = c1.StartPoint.x; + let x2 = c2.StartPoint.x; + if (equaln(x1, x2)) + continue; + + let y1: number; + let y2: number; + + let res = c1.IntersectWith2(outline, IntersectOption.ExtendThis); + + let res2 = c2.IntersectWith2(outline, IntersectOption.ExtendThis); + let pars = [...res.map(r => Math.floor(r.argParam)), ...res2.map(r => Math.floor(r.argParam))]; + pars = [...new Set(pars)]; + pars.sort((a, b) => a - b); + + let ys: number[] = []; + for (let par of pars) + { + let c = outline.GetCurveAtIndex(par); + let derv = c.GetFistDeriv(0).normalize(); + if (isParallelTo(derv, XAxis, PolylineSpliteRectFuzz)) + { + let x3 = c.StartPoint.x; + let x4 = c.EndPoint.x; + if (x3 > x4) + [x3, x4] = [x4, x3]; + if (isIntersect(x1, x2, x3, x4, -PolylineSpliteRectFuzz)) + ys.push(c.StartPoint.y); + } + } + + if (ys.length < 2) return [outline]; + + ys.sort((a, b) => a - b); + + y1 = ys[0]; + y2 = arrayLast(ys); + + rects.push(new Polyline().RectangleFrom2Pt(new Vector3(x1, y1), new Vector3(x2, y2))); + } + + return rects; + +} diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index 2e5ce4342..11555a9c2 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -43,7 +43,7 @@ export class Contour return; } - let closeCurve = Contour.Combine(cus, needLink) as Polyline | Circle; + let closeCurve = Contour.Combine(cus, needLink, 1e-2) as Polyline | Circle; if (closeCurve && closeCurve.IsClose) { if (closeCurve instanceof Polyline && closeCurve.CloseMark === false) @@ -450,7 +450,7 @@ export class Contour let plMidParam = pl.MidParam; let plDir = pl.GetFistDeriv(plMidParam).normalize(); - let index = targetCus.findIndex(cu => fastEqualCurve(cu, pl)); + let index = targetCus.findIndex(cu => fastEqualCurve(cu, pl, 0.05)); if (index !== -1) { let cu = targetCus[index]; @@ -526,9 +526,9 @@ export class Contour let gclone = g.map(c => c.Clone()); - arrayRemoveDuplicateBySort(gclone, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True); + arrayRemoveDuplicateBySort(gclone, (cu1: Curve, cu2: Curve) => cu1.Join(cu2, false, tolerance) === Status.True); - if (gclone.length > 1 && gclone[0].Join(arrayLast(gclone))) + if (gclone.length > 1 && gclone[0].Join(arrayLast(gclone), false, tolerance)) gclone.pop(); let pl = Polyline.Combine(gclone, tolerance); diff --git a/src/DatabaseServices/Entity/Extrude.ts b/src/DatabaseServices/Entity/Extrude.ts index 2d3a6f552..00d4845e7 100644 --- a/src/DatabaseServices/Entity/Extrude.ts +++ b/src/DatabaseServices/Entity/Extrude.ts @@ -2,7 +2,7 @@ import { BoxGeometry, BufferGeometry, ExtrudeGeometry, ExtrudeGeometryOptions, L import { Line2 } from "three/examples/jsm/lines/Line2"; import { arrayClone, arrayLast, arrayRemoveIf, arrayRemoveOnce, arraySortByNumber, arraySum } from "../../Common/ArrayExt"; import { ColorMaterial } from "../../Common/ColorPalette"; -import { equalCurve } from "../../Common/CurveUtils"; +import { equalCurve, PolylineSpliteRect } from "../../Common/CurveUtils"; import { DisposeThreeObj } from "../../Common/Dispose"; import { Log } from "../../Common/Log"; import { matrixSetVector, Vector2ApplyMatrix4 } from "../../Common/Matrix4Utils"; @@ -1025,24 +1025,31 @@ export class ExtrudeSolid extends Entity } return grooves; } - project.ApplyMatrix(target.OCSInv); + // project.ApplyMatrix(target.OCSInv); project.Z0(); let c1 = Contour.CreateContour(project); let c2 = Contour.CreateContour(target.ContourCurve); //投影轮廓列表 let contours = c1.IntersectionBoolOperation(c2); - + let outlines: ExtureContourCurve[] = []; + for (let c of contours) + { + if (c.Curve instanceof Polyline) + outlines.push(...PolylineSpliteRect(c.Curve)); + else + outlines.push(c.Curve); + } let xv = this.Normal; let zv = target.Normal; let yv = zv.clone().cross(xv); //把<投影轮廓>对齐到肉的侧面坐标系上 let projection2SideMatrix4 = new Matrix4().makeBasis(xv, yv, zv); - for (let c of contours) + for (let c of outlines) { let g = target.Clone().ClearDraw(); let gs = [g]; - g.ContourCurve = c.Curve; + g.ContourCurve = c; g.GrooveCheckAll(gs); for (let g1 of gs) @@ -1928,7 +1935,7 @@ function ProjectBoard(knifBoard: ExtrudeSolid, projectBoard: ExtrudeSolid) })); pl.CloseMark = true; - pl.ApplyMatrix(knifBoard.OCS); + // pl.ApplyMatrix(knifBoard.OCS); return pl; } diff --git a/src/Geometry/GeUtils.ts b/src/Geometry/GeUtils.ts index 1fe554b29..e59a469ac 100644 --- a/src/Geometry/GeUtils.ts +++ b/src/Geometry/GeUtils.ts @@ -180,9 +180,9 @@ export function createLookAtMat4(dir: Vector3): Matrix4 /** * 判断2个向量是不是平行,尽量传入单位向量,才能保证计算精度 */ -export function isParallelTo(v1: Vector3, v2: Vector3): boolean +export function isParallelTo(v1: Vector3, v2: Vector3, fuzz = 1e-8): boolean { - return v1.clone().cross(v2).lengthSq() < 1e-8; + return v1.clone().cross(v2).lengthSq() < fuzz; } /**