import { Vector2, Vector3 } from 'three'; import { CADFiler } from '../../src/DatabaseServices/CADFiler'; import { Polyline } from '../../src/DatabaseServices/Entity/Polyline'; import { equaln, equalv3 } from '../../src/Geometry/GeUtils'; test("多段线点获取参数", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(pl.GetParamAtPoint(new Vector3(5, 0, 0))).toBe(1); expect(pl.GetParamAtPoint(new Vector3(6, 0, 0)) /*?*/).toBe(NaN); expect(pl.GetParamAtPoint(new Vector3(-2.5, 0, 0))/*?*/).toBe(-0.5); expect(pl.GetParamAtPoint(new Vector3(7.5, 2.5, 0))).toBe(1.5); expect(pl.GetParamAtPoint(new Vector3(5, 5, 0))).toBe(2); expect(pl.GetParamAtPoint(pl.GetPointAtParam(1.25)) /*?*/).toBe(1.25); expect(equaln(pl.GetParamAtPoint(new Vector3(0, 5, 0)), 4.5)).toBeTruthy(); expect(pl.GetParamAtPoint(new Vector3(0, -5, 0))).toBe(5.5); expect(pl.GetParamAtPoint(new Vector3(0, 10, 0))).toBe(4); let pl2 = new Polyline([ { pt: new Vector2(1.5, 8.5), bul: 0 }, { pt: new Vector2(1.5, 1.5), bul: 0 } ]); expect(pl2.GetParamAtPoint(new Vector3(1.5, 5))).toBe(0.5); }); describe('多段线', () => { test("多段线参数获取点", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(equalv3(pl.GetPointAtParam(1), new Vector3(5, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(0.5), new Vector3(2.5, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(-0.5), new Vector3(-2.5, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(4.5), new Vector3(0, 5, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(5), new Vector3(0, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(5.5), new Vector3(0, -5, 0))).toBeTruthy(); }); test("多段线参数获取弧长", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(pl.GetDistAtParam(1)).toBe(5); expect(pl.GetDistAtParam(2)).toBe(5 + Math.PI * 2.5); expect(pl.GetDistAtParam(1.5)).toBe(5 + Math.PI * 2.5 / 2); expect(pl.GetDistAtParam(3)).toBe(5 + Math.PI * 5); expect(pl.GetDistAtParam(4)).toBe(5 + Math.PI * 5 + 5); expect(pl.GetDistAtParam(3.5)).toBe(5 + Math.PI * 5 + 2.5); }); test("多段线弧长获取点", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(equalv3(pl.GetPointAtDistance(5), new Vector3(5, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(2.5), new Vector3(2.5, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(5 + Math.PI * 2.5), new Vector3(5, 5, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(5 + Math.PI * 2.5 * 2), new Vector3(5, 10, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(0), new Vector3(0, 0, 0))).toBeTruthy(); }); test("多段线距离获取参数", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(pl.GetParamAtDist(5)).toBe(1); expect(pl.GetParamAtDist(5 + Math.PI * 2.5)).toBe(2); expect(pl.GetParamAtDist(5 + Math.PI * 2.5 / 2)).toBe(1.5); }); test("多段线点获取弧长", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(pl.GetDistAtPoint(new Vector3(0, 0, 0))).toBe(0); expect(pl.GetDistAtPoint(new Vector3(5, 0, 0))).toBe(5); expect(pl.GetDistAtPoint(new Vector3(7.5, 2.5, 0))).toBe(5 + Math.PI / 2 * 2.5); expect(pl.GetDistAtPoint(new Vector3(7.5, 2.5, 0))).toBe(5 + Math.PI / 2 * 2.5); expect(pl.Length).toMatchSnapshot(); }); test("多段线延伸,不闭合", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); let pl2 = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 } ]); expect(pl.IsClose).toBeTruthy(); pl.Extend(5.5); expect(pl.EndPoint).toEqual(new Vector3(0, -5, 0)); expect(pl.LineData.length).toEqual(6); expect(pl.GetPointAtParam(5)).toEqual(new Vector3(0, -5, 0)); pl.Extend(-0.5); expect(pl.StartPoint).toEqual(new Vector3(-2.5, 0, 0)); expect(pl.IsClose).toBeFalsy(); pl2.Extend(4.5); expect(pl2.EndPoint).toEqual(new Vector3(-2.5, 10, 0)); pl2.Extend(-0.5); expect(pl2.EndPoint).toEqual(new Vector3(-2.5, 10, 0)); expect(pl2.StartPoint).toEqual(new Vector3(-2.5, 0, 0)); let pl3 = new Polyline([ { pt: new Vector2(0, 0), bul: 1 }, { pt: new Vector2(0, 5), bul: 0 } ]); pl3.Extend(1.5); expect(equalv3(pl3.EndPoint, new Vector3(-2.5, 2.5, 0))).toBeTruthy(); pl3.Extend(1 + 1 / 3); // expect(pl3.EndPoint).toEqual(new Vector3(0, 0, 0)); expect(equalv3(pl3.EndPoint /*?*/, new Vector3(0, 0, 0))).toBeTruthy(); }); test("多段线延伸,闭合", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); pl.CloseMark = true; pl.Extend(5.5); expect(pl.EndPoint).toEqual(new Vector3()); }); test("多段线点在线上", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(pl.GetParamAtPoint(new Vector3())).toBe(0); expect(pl.PtOnCurve(new Vector3(0, 0, 0))).toBeTruthy(); expect(pl.PtOnCurve(new Vector3(5, 0, 0))).toBeTruthy(); expect(pl.PtOnCurve(new Vector3(7.5, 2.5, 0))).toBeTruthy(); expect(pl.PtOnCurve(new Vector3(7.5, 3.5, 0))).toBeFalsy(); }); test("多段线最近点", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(pl.GetClosestPointTo(new Vector3(), true)).toEqual(new Vector3()); expect(pl.GetClosestPointTo(new Vector3(3.5, 2.5), true)).toEqual(new Vector3(3.5, 0, 0)); expect(pl.GetClosestPointTo(new Vector3(1.5, 3.5), true)).toEqual(new Vector3(0, 3.5, 0)); expect(equalv3(pl.GetClosestPointTo(new Vector3(1.5, 3.5), true), new Vector3(0, 3.5, 0))).toBeTruthy(); expect(equalv3(pl.GetClosestPointTo(new Vector3(-0.5, -1), true), new Vector3(0, -1, 0))).toBeTruthy(); }); test("多段线包围盒", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 }, { pt: new Vector2(0, 0), bul: 0 } ]); expect(pl.BoundingBox.getSize(new Vector3())).toEqual(new Vector3(7.5, 10, 0)); }); test("多段线反转", () => { let pl = new Polyline([ { pt: new Vector2(0, 0), bul: 0 }, { pt: new Vector2(5, 0), bul: 1 }, { pt: new Vector2(5, 5), bul: -1 }, { pt: new Vector2(5, 10), bul: 0 }, { pt: new Vector2(0, 10), bul: 0 } ]); pl.Reverse(); expect(pl.StartPoint).toEqual(new Vector3(0, 10, 0)); }); //直线和圆的求交的det精度不能为0.1 太大了.请保证这个测试是通过的 test('最近点精度', () => { let f = new CADFiler(); f.Data = [1, "Polyline", 1, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 5, [0, 0], 0, [2, 0], 1, [2, 2], -1, [2, 4], 0, [0, 4], 0, true]; f.Read(); let pl = f.ReadObject() as Polyline; pl.Reverse(); let cp = pl.GetClosestPointTo(new Vector3(2 - 1e-2, 3.8), false); expect(cp).toMatchSnapshot(); }); test('优化参数在端点上的时候', () => { let pl = new Polyline(); pl.AddVertexAt(0, new Vector2(0, 0)); pl.AddVertexAt(1, new Vector2(5, 0)); pl.AddVertexAt(2, new Vector2(5, 5)); pl.CloseMark = true; let p = pl.GetPointAtParam(3); expect(p).toMatchSnapshot(); }); test('存在大圆弧的多段线面积', () => { let f = new CADFiler(); f.Data = [1, "Polyline", 1, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -19.17745164184445, -6.335408131680751, 0, 1], 2, 5, [11.884352072596577, -75.64730611519322], -1.9523252757782086, [16.25360183965801, -70.58112080246555], 0, [14.621427950114992, -70.9720172143345], 1.8583004340984604, [11.834326201222096, -73.95002751582643], 0, [11.884352072596577, -75.64730611519322], 0, false]; f.Read(); let pl = f.ReadObject() as Polyline; expect(pl.Area2).toMatchSnapshot(); }); }); test('最近点参数刚好在端点上', () => { let f = new CADFiler(); f.Data = [1, "Polyline", 1, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 15.725529745042493, -3.9968028886505635e-15, 0, 1], 2, 3, [13.07875354107649, 3.8181303116147296], 0, [18.159206798866855, 3.8181303116147296], 0.664293193717279, [18.159206798866855, -1.4844192634560907], -0.10977222864644352, false]; f.Read(); let pl = f.ReadObject() as Polyline; let p = new Vector3(33.88473654390935, 3.8181303116147256, 0); let cp = pl.GetClosestPointTo(p, false); let param = pl.GetParamAtPoint(cp); expect(equaln(param, 1)).toBeTruthy(); }); function loadFile(data) { let file = new CADFiler(); file.Data = data; let cus: Polyline[] = []; let count = file.Read(); for (let i = 0; i < count; i++) { cus.push(file.ReadObject(undefined) as Polyline); } return cus; } //https://gitee.com/BearCAD/WebThreeJs/issues/IKWGF#note_977523 test('点在线上精度', () => { let data = [1, "Polyline", 1, 1, 0, false, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 6.283029954893735, -0.21450491241551983, 0, 1], 2, 5, [-6.290104635739899, 3.3748564511765324], -0.10216571300036131, [-6.136537456708874, 3.2958817075766764], 0, [-6.236783847999098, 3.0649817075766763], 0.44141445079284647, [-6.5210046357398985, 3.121255471298752], 0, [-6.290104635739899, 3.3748564511765324], 0, false]; let pl = loadFile(data)[0]; let pt = new Vector3().fromArray([-0.23760717950533072, 2.9070744830224284, 0]); expect(pl.PtOnCurve(pt)).toBeFalsy(); });