You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
WebCAD/__test__/Geometry/ellipse.test.ts

363 lines
19 KiB

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);
});
});