import { Vector3 } from "three"; import { Status } from "../../src/Common/Status"; import { Arc } from "../../src/DatabaseServices/Entity/Arc"; import { Circle } from "../../src/DatabaseServices/Entity/Circle"; import { Curve } from "../../src/DatabaseServices/Entity/Curve"; import { Ellipse } from "../../src/DatabaseServices/Entity/Ellipse"; import { Line } from "../../src/DatabaseServices/Entity/Line"; import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import { equalv3 } from "../../src/Geometry/GeUtils"; import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util"; describe('完整椭圆', () => { let el = new Ellipse(new Vector3(), 250, 100, 0); let p1 = el.GetPointAtParam(0); let p2 = el.GetPointAtParam(0.1); let p3 = el.GetPointAtParam(0.25); let p4 = el.GetPointAtParam(0.5); let p5 = el.GetPointAtParam(0.6); let p6 = el.GetPointAtParam(0.75); let p7 = el.GetPointAtParam(0.8); test("几何数据", () => { expect(el.Length).toMatchSnapshot(); expect(el.Length).toBeCloseTo(1150, -1); expect(el.Area).toMatchSnapshot(); expect(el.Area).toBeCloseTo(78539.82, -1); }); test("PtOnCurve", () => { let pt = new Vector3(160.20983328761838, 76.76750283077186); [pt, new Vector3(250), new Vector3(0, -100)].forEach(p => { expect(el.PtOnCurve(p)).toBeTruthy(); }); }); test("GetPointAtParam", () => { expect(equalv3(p1, new Vector3(250))).toBeTruthy(); expect(equalv3(p2, new Vector3(202.25424859373686, 58.778525229247315))).toBeTruthy(); expect(equalv3(p3, new Vector3(0, 100))).toBeTruthy(); expect(equalv3(p4, new Vector3(-250))).toBeTruthy(); }); test("GetParamAtPoint", () => { expect(el.GetParamAtPoint(p1)).toBeCloseTo(0); expect(el.GetParamAtPoint(p2)).toBeCloseTo(0.1); expect(el.GetParamAtPoint(p3)).toBeCloseTo(0.25); expect(el.GetParamAtPoint(p5)).toBeCloseTo(0.6); expect(el.GetParamAtPoint(p7)).toBeCloseTo(0.8); }); test("GetDistAtParam", () => { expect(el.GetDistAtParam(0.5)).toBeCloseTo(el.Length * 0.5); }); test("GetParamAtDist", () => { expect(el.GetParamAtDist(el.Length * 0.5)).toBeCloseTo(0.5); }); test("GetFirstDeriv", () => { expect(equalv3(el.GetFirstDeriv(0), new Vector3(0, 1))).toBeTruthy(); expect(equalv3(el.GetFirstDeriv(0.5), new Vector3(0, -1))).toBeTruthy(); expect(equalv3(el.GetFirstDeriv(0.25), new Vector3(-1))).toBeTruthy(); expect(equalv3(el.GetFirstDeriv(0.75), new Vector3(1))).toBeTruthy(); expect(equalv3(el.GetFirstDeriv(0.1), new Vector3(-1, 0.5505527681884694))).toBeTruthy(); expect(equalv3(el.GetFirstDeriv(0.3), new Vector3(-1, -0.1299678784931625))).toBeTruthy(); expect(equalv3(el.GetFirstDeriv(0.6), new Vector3(1, -0.5505527681884692))).toBeTruthy(); expect(equalv3(el.GetFirstDeriv(0.8), new Vector3(1, 0.12996787849316255))).toBeTruthy(); }); test("GetClosestPointTo", () => { expect(el.GetClosestPointTo(new Vector3(180, 130), true)).toMatchSnapshot(); expect(el.GetClosestPointTo(new Vector3(-150, -150), true)).toMatchSnapshot(); expect(equalv3(el.GetClosestPointTo(new Vector3(), true), new Vector3(250))).toBeTruthy(); }); test('offset', () => { for (let d of [0, -50, -100, 200]) { let els = el.GetOffsetCurves(d); for (let e of els) { expect(e.GetGripPoints()).toMatchSnapshot(); } } }); test("join", () => { let el1 = el.Clone(); el1.StartAngle = Math.PI * 0.2; el1.EndAngle = Math.PI * 0.5; let el2 = el.Clone(); el2.StartAngle = Math.PI * 0.5; el2.EndAngle = Math.PI * 0.2; expect(el1.Join(el2)).toBe(Status.True); expect(el1.IsClose).toBeTruthy(); }); test("GetSplitCurves", () => { let els = el.GetSplitCurves([0, 0.1, 0.5, 0.75]); expect(els.length).toBe(4); let len = 0; els.forEach(l => len += l.Length); expect(len).toBeCloseTo(el.Length); }); test("椭圆和直线相交", () => { let l = new Line(new Vector3(250), new Vector3(250, 300)); let pts = el.IntersectWith(l, 0); expect(pts.length).toBe(1); l = new Line(new Vector3(250), new Vector3(-200, 200)); pts = el.IntersectWith(l, 0); expect(pts.length).toBe(2); l = new Line(new Vector3(130, 50), new Vector3(-200, 200)); pts = el.IntersectWith(l, 0); expect(pts.length).toBe(1); l = new Line(new Vector3(200, -300), new Vector3(200, 300)); pts = el.IntersectWith(l, 0); expect(pts.length).toBe(2); }); test("椭圆和圆弧相交", () => { let l = new Arc(new Vector3(200, 90), 120, 1.2667, 4.204); let pts = el.IntersectWith(l, 0); expect(pts.length).toBe(1); pts = el.IntersectWith(l, 3); expect(pts.length).toBe(2); let cir = new Circle(new Vector3(), 100); pts = el.IntersectWith(cir, 0); expect(pts.length).toBe(2); cir = new Circle(new Vector3(), 250); pts = el.IntersectWith(cir, 0); expect(pts.length).toBe(2); cir = new Circle(new Vector3(), 200); pts = el.IntersectWith(cir, 0); expect(pts.length).toBe(4); cir = new Circle(new Vector3(0, 100), 100); pts = el.IntersectWith(cir, 0); expect(pts.length).toBe(2); cir = new Circle(new Vector3(400), 100); pts = el.IntersectWith(cir, 0); expect(pts.length).toBe(0); let data = { "file": [2, "Ellipse", 3, 2, 833, false, 0, 7, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 11102.861204896697, 0, 2032.2646535460103, 1], 1, 3731.0773801284895, 1822.1540693650747, -0.7853981633972875, 0, 6.283185307179586, "Circle", 3, 2, 842, false, 1, 7, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 11102.861204896697, 0, 2032.2646535460103, 1], 1, 3001.2505191312093], "basePt": { "x": 20324.11883779178, "y": 0, "z": 2875.7945530299553 } }; let cus = LoadCurvesFromFileData(data) as Curve[]; pts = cus[0].IntersectWith(cus[1], 0); expect(pts.length).toBe(4); }); test("椭圆和多段线相交", () => { let data = { "file": [1, "Polyline", 3, 2, 112, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [-335.6038995638465, -82.43257813770273], 0, [-106.1153157638372, -6.7633694252672285], 0, [12.970652045897396, -45.21821319716078], 0, [117.1708738794153, 118.52499254122434], 0, false], "basePt": { "x": 55.14693231184518, "y": 32.93195317797762, "z": 0 } }; let pl = LoadCurvesFromFileData(data)[0]; let pts = el.IntersectWith(pl, 0); expect(pts.length).toBe(2); data = { "file": [1, "Polyline", 3, 2, 113, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 5, [-410.1219439207879, -125.67070828328724], 0, [-173.79584080236958, -1.6724443014010655], 0.2825944770646096, [-68.76201719418361, 174.84273148457797], -2.140757839596393, [63.989065421717896, 66.8913016650536], 0, [441.8190697900534, -102.32985859257917], 0, false], "basePt": { "x": 435.98385736737646, "y": -78.98900890187124, "z": 0 } }; pl = LoadCurvesFromFileData(data)[0]; pts = el.IntersectWith(pl, 0); expect(pts.length).toBe(4); }); test("椭圆椭圆相交", () => { let pts = el.IntersectWith(el.Clone(), 0); expect(pts.length).toBe(0); let el2 = el.Clone(); el2.Center = new Vector3(250); pts = el.IntersectWith(el2, 0); expect(pts.length).toBe(2); let data = { "file": [1, "Ellipse", 3, 2, 115, false, 1, 7, 0, [-0.4190581774617472, -0.9079593845004515, 0, 0, 0.9079593845004515, -0.4190581774617472, 0, 0, 0, 0, 1, 0, 20.59763950762874, 46.6612008780327, 0, 1], 1, 250, 100, 0, 0, 6.283185307179586], "basePt": { "x": 735.3489273304585, "y": 121.3525062483825, "z": 0 } }; let el3 = LoadCurvesFromFileData(data)[0]; pts = el.IntersectWith(el3, 0); expect(pts.length).toBe(4); data = { "file": [1, "Ellipse", 3, 2, 115, false, 1, 7, 0, [-0.4190581774617472, -0.9079593845004515, 0, 0, 0.9079593845004515, -0.4190581774617472, 0, 0, 0, 0, 1, 0, 187.7445845668207, 364.27473348939463, 0, 1], 1, 250, 100, 0, 0, 6.283185307179586], "basePt": { "x": 317.9344290644616, "y": 379.38531948896275, "z": 0 } }; el3 = LoadCurvesFromFileData(data)[0]; pts = el.IntersectWith(el3, 0); expect(pts.length).toBe(0); }); }); describe("非完整椭圆", () => { let data = { "file": [1, "Ellipse", 3, 2, 121, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, 250, 100, 0, 3.2624068331327574, 1.8128125175408325], "basePt": { "x": 948.626520974941, "y": -75.40395225389025, "z": 0 } }; let el = LoadCurvesFromFileData(data)[0] as Ellipse; data = { "file": [1, "Ellipse", 3, 2, 124, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 29.61201700564709, 641.6901339885158, 0, 1], 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 3.934994981148553, 1.3332220725861395], "basePt": { "x": 334.56716843563856, "y": 365.4059797015151, "z": 0 } }; let el2 = LoadCurvesFromFileData(data)[0] as Ellipse; test("几何参数", () => { expect(el.Length).toMatchSnapshot(); expect(el.Area).toMatchSnapshot(); expect(el2.Length).toMatchSnapshot(); expect(el.Area).toMatchSnapshot(); }); test("PtOnCurve", () => { let p = new Vector3(-283.26124450979813, 673.4306820783466); let data = { "file": [1, "Ellipse", 3, 2, 124, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 29.61201700564709, 641.6901339885158, 0, 1], 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 3.934994981148553, 1.3332220725861395], "basePt": { "x": 2681.2570394768845, "y": -1593.4506532289088, "z": 0 } }; let l = LoadCurvesFromFileData(data)[0] as Ellipse; expect(l.PtOnCurve(p)).toBeTruthy(); p = new Vector3(2397.1610323469677, 85.35748381925586); data = { "file": [1, "Ellipse", 3, 2, 444, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2079.1139796352218, 127.64566779152159, 0, 1], 1, 225.54490978414742, 418.1552083854798, -2.2679288522075365, 5.505791307943451, 2.904018399381034], "basePt": { "x": 3700.685116502911, "y": -68.9791965641534, "z": 0 } }; l = LoadCurvesFromFileData(data)[0] as Ellipse; expect(l.PtOnCurve(p)).toBeTruthy(); }); test("GetPointAtParam", () => { expect(el2.GetPointAtParam(0.2)).toMatchSnapshot(); expect(el2.GetPointAtParam(0.5)).toMatchSnapshot(); }); test("GetParamAtPoint", () => { let data = { "file": [1, "Ellipse", 3, 2, 124, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 29.61201700564709, 641.6901339885158, 0, 1], 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 3.934994981148553, 1.3332220725861395], "basePt": { "x": 2681.2570394768845, "y": -1593.4506532289088, "z": 0 } }; let l = LoadCurvesFromFileData(data)[0] as Ellipse; let p = new Vector3(246.01582144145584, 746.3383795723034); expect(l.GetParamAtPoint(p)).toBeCloseTo(1); p = new Vector3(73.23667922398035, 886.2085173816399); expect(l.GetParamAtPoint(p)).toBeGreaterThan(1); p = new Vector3(-317.46308327988817, 769.1547312689645); expect(l.GetParamAtPoint(p)).toBeLessThan(1); expect(l.GetParamAtPoint(l.GetPointAtParam(0.2))).toBeCloseTo(0.2); expect(l.GetParamAtPoint(l.GetPointAtParam(0.5))).toBeCloseTo(0.5); expect(l.GetParamAtPoint(l.GetPointAtParam(0.8))).toBeCloseTo(0.8); }); test("GetDistAtParam", () => { expect(el2.GetParamAtDist(el2.GetDistAtParam(0.2))).toBeCloseTo(0.2); expect(el2.GetParamAtDist(el2.GetDistAtParam(0.5))).toBeCloseTo(0.5); expect(el2.GetParamAtDist(el2.GetDistAtParam(0.8))).toBeCloseTo(0.8); }); test("GetParamAtDist", () => { expect(el2.GetDistAtParam(0.2)).toMatchSnapshot(); expect(el2.GetDistAtParam(0.5)).toMatchSnapshot(); expect(el2.GetDistAtParam(0.8)).toMatchSnapshot(); }); test("GetFirstDeriv", () => { let p = new Vector3(3245.070906808509, -20.406490193093504); let data = { "file": [1, "Ellipse", 3, 2, 131, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2910.330625096328, 62.245373351688414, 0, 1], 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 3.934994981148553, 1.3332220725861395], "basePt": { "x": 3893.631897322025, "y": -235.90267753572692, "z": 0 } }; let el = LoadCurvesFromFileData(data)[0] as Ellipse; let derv = el.GetFirstDeriv(p); expect(derv.x < 0).toBeTruthy(); expect(derv.y > 0).toBeTruthy(); derv = el.GetFirstDeriv(0.2); expect(derv.x > 0).toBeTruthy(); expect(derv.y < 0).toBeTruthy(); derv = el.GetFirstDeriv(0.5); expect(derv.x > 0).toBeTruthy(); expect(derv.y > 0).toBeTruthy(); }); test("GetClosestPointTo", () => { let p = new Vector3(-485.6180207115862, 791.5205029837365); let data = { "file": [1, "Ellipse", 3, 2, 124, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 29.61201700564709, 641.6901339885158, 0, 1], 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 3.934994981148553, 1.3332220725861395], "basePt": { "x": 1514.970345140928, "y": 460.6123732805639, "z": 0 } }; let l = LoadCurvesFromFileData(data)[0] as Ellipse; let closePt = l.GetClosestPointTo(p, false); expect(equalv3(closePt, l.StartPoint)).toBeTruthy(); p = new Vector3(255.02021875477413, 873.0660067450125); closePt = l.GetClosestPointTo(p, false); expect(equalv3(closePt, l.EndPoint)).toBeTruthy(); p = new Vector3(-301.20629379808594, 636.6952439507315); closePt = l.GetClosestPointTo(p, false); expect(l.PtOnCurve(closePt)).toBeTruthy(); }); test('offset', () => { for (let d of [0, -50, -100, 200]) { let els = el2.GetOffsetCurves(d); for (let e of els) { expect(e.GetGripPoints()).toMatchSnapshot(); } } }); test("join", () => { expect(el.Join(el2)).toBeFalsy(); let data = { "file": [2, "Ellipse", 3, 2, 834, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2910.330625096328, 62.245373351688414, 0, 1], 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 6.343188564109003, 7.616407379765725, "Ellipse", 3, 2, 833, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2910.330625096327, 62.24537335168705, 0, 1], 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 3.934994981148553, 6.34318856410901], "basePt": { "x": 3070.6075022402556, "y": -251.35268998703185, "z": 0 } }; let els = LoadCurvesFromFileData(data) as Ellipse[]; expect(els[0].Join(els[1])).toBeTruthy(); expect(els[0].StartAngle).toBeCloseTo(el2.StartAngle); // expect(els[0].EndAngle).toBeCloseTo(el2.EndAngle); todo 垃圾测试 垃圾join实现 }); test("GetSplitCurves", () => { let cus = el2.GetSplitCurves(0.2); expect(cus.length).toBe(2); cus = el2.GetSplitCurves([0, 1]); expect(cus.length).toBe(1); expect(cus[0].Length).toBeCloseTo(el2.Length); }); test("椭圆和直线相交", () => { let data = { "file": [1, "Line", 3, 2, 835, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [40.99635967060419, 828.344303500637, 0], [419.2963252629038, 79.65300513942876, 0]], "basePt": { "x": 1547.6371722986987, "y": 505.9487058831845, "z": 0 } }; let l = LoadCurvesFromFileData(data)[0] as Line; let intPts = el2.IntersectWith(l, 0); expect(intPts.length).toBe(1); data = { "file": [1, "Line", 3, 2, 836, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [-508.03376696505734, 378.26728108419354, 0], [1506.1407092390264, 857.0726240804099, 0]], "basePt": { "x": 819.8530509444495, "y": 697.4708430816711, "z": 0 } }; l = LoadCurvesFromFileData(data)[0] as Line; intPts = el2.IntersectWith(l, 0); expect(intPts.length).toBe(2); }); test("椭圆和圆弧相交", () => { let data = { "file": [1, "Circle", 3, 2, 837, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 29.61201700564709, 641.6901339885158, 0, 1], 1, 240.28658436372382], "basePt": { "x": 1747.976477968104, "y": 478.1948499374774, "z": 0 } }; let cir = LoadCurvesFromFileData(data)[0] as Circle; let intPts = el2.IntersectWith(cir, 0); expect(intPts.length).toBe(3); let cus = el2.GetSplitCurvesByPts(intPts); expect(cus.length).toBe(3); data = { "file": [1, "Circle", 3, 2, 829, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 187.80449653238327, 687.2252854417625, 0, 1], 1, 142.38840109430407], "basePt": { "x": 230.04137781057622, "y": 568.9620178628227, "z": 0 } }; cir = LoadCurvesFromFileData(data)[0] as Circle; intPts = el2.IntersectWith(cir, 0); expect(intPts.length).toBe(1); data = { "file": [1, "Arc", 3, 2, 830, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.981256652944406, 734.2425700250855, 0, 1], 2, 380.9050292698399, 3.8973798333988365, 0.296805111427033, false], "basePt": { "x": 676.8826456844006, "y": 686.8100446096855, "z": 0 } }; let arc = LoadCurvesFromFileData(data)[0] as Arc; intPts = el2.IntersectWith(arc, 0); expect(intPts.length).toBe(2); }); test("椭圆和多段线相交", () => { let data = { "file": [1, "Polyline", 3, 2, 831, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [-199.7615585356133, 411.90419659644084], 0, [67.50801592170811, 509.64849811226117], 0, [316.4505338448129, 443.97654553131935], 0, [316.4505338448129, 828.844732749862], 0, false], "basePt": { "x": 1289.3117848694626, "y": 358.45028170497653, "z": 0 } }; let l = LoadCurvesFromFileData(data)[0] as Polyline; let pts = el2.IntersectWith(l, 0); expect(pts.length).toBe(2); }); test("椭圆椭圆相交", () => { let data = { "file": [1, "Ellipse", 3, 2, 121, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 280.916829323563, 321.0478049412151, 0, 1], 1, 250, 100, 0, 3.2624068331327574, 1.8128125175408325], "basePt": { "x": 217.06597636418695, "y": 243.35797242008385, "z": 0 } }; let l = LoadCurvesFromFileData(data)[0] as Ellipse; let pts = el2.IntersectWith(l, 0); expect(pts.length).toBe(1); }); });