mirror of https://gitee.com/cf-fz/WebCAD.git
parent
13a0a1be8d
commit
6081b35a9e
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,240 +1,20 @@
|
|||||||
import { Vector3 } from 'three';
|
import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util";
|
||||||
import { Line } from '../../src/DatabaseServices/Entity/Line';
|
import { RegionParse } from "../../src/Geometry/RegionParse";
|
||||||
import { LoadCurvesFromFileData } from '../Utils/LoadEntity.util';
|
import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
|
||||||
import { RegionParse } from './../../src/Geometry/RegionParse';
|
import "../Utils/jest.util";
|
||||||
|
|
||||||
function expectReg(alg: RegionParse)
|
test('面域分析测试', () =>
|
||||||
{
|
{
|
||||||
let data1 = alg.RegionsInternal.map(o =>
|
let cus = LoadCurvesFromFileData(require("./curves.json"));
|
||||||
{
|
|
||||||
let res = [];
|
|
||||||
o.forEach(r => { res.push(r.to.position.toArray()); });
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
let data2 = alg.RegionsOutline.map(o =>
|
|
||||||
{
|
|
||||||
let res = [];
|
|
||||||
o.forEach(r => { res.push(r.to.position.toArray()); });
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(data1).toMatchSnapshot();
|
|
||||||
expect(data2).toMatchSnapshot();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
test('两个相连的区域', () =>
|
|
||||||
{
|
|
||||||
|
|
||||||
let culist = [];
|
|
||||||
|
|
||||||
let l1 = new Line(new Vector3(0, 0, 0), new Vector3(5, 5, 0));
|
|
||||||
let l2 = new Line(new Vector3(0, 0, 0), new Vector3(3, 2, 0));
|
|
||||||
|
|
||||||
let l3 = new Line(new Vector3(5, 5, 0), new Vector3(5, 25, 0));
|
|
||||||
let l4 = new Line(new Vector3(5, 25, 0), new Vector3(0, 0, 0));
|
|
||||||
|
|
||||||
let l5 = new Line(new Vector3(3, 2, 0), new Vector3(4, 3, 0));
|
|
||||||
let l6 = new Line(new Vector3(4, 3, 0), new Vector3(20, 5, 0));
|
|
||||||
let l7 = new Line(new Vector3(20, 5, 0), new Vector3(3, 2, 0));
|
|
||||||
|
|
||||||
culist.push(l1, l2, l3, l4, l5, l6, l7);
|
|
||||||
|
|
||||||
let g = new RegionParse(culist);
|
|
||||||
g.RegionsOutline.length; //?
|
|
||||||
g.RegionsInternal.length; //?
|
|
||||||
expect(g.RegionsOutline.length).toBe(2);
|
|
||||||
expect(g.RegionsInternal.length).toBe(0);
|
|
||||||
|
|
||||||
expectReg(g);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('区域内有分割-三角形', () =>
|
|
||||||
{
|
|
||||||
|
|
||||||
let culist = [];
|
|
||||||
|
|
||||||
let l1 = new Line(new Vector3(0, 0, 0), new Vector3(5, 0, 0));
|
|
||||||
let l2 = new Line(new Vector3(5, 0, 0), new Vector3(0, 5, 0));
|
|
||||||
|
|
||||||
let l3 = new Line(new Vector3(0, 5, 0), new Vector3(0, 0, 0));
|
|
||||||
let l4 = new Line(new Vector3(0, 0, 0), new Vector3(0, -5, 0));
|
|
||||||
|
|
||||||
let l5 = new Line(new Vector3(5, 0, 0), new Vector3(0, -5, 0));
|
|
||||||
|
|
||||||
culist.push(l1, l2, l3, l4, l5);
|
|
||||||
|
|
||||||
let g = new RegionParse(culist);
|
|
||||||
g.RegionsOutline.length; //?
|
|
||||||
g.RegionsInternal.length; //?
|
|
||||||
expect(g.RegionsOutline.length).toBe(1);
|
|
||||||
expect(g.RegionsInternal.length).toBe(2);
|
|
||||||
|
|
||||||
expectReg(g);
|
|
||||||
});
|
|
||||||
test('区域有延长线', () =>
|
|
||||||
{
|
|
||||||
|
|
||||||
let culist = [];
|
|
||||||
|
|
||||||
let l1 = new Line(new Vector3(0, 0, 0), new Vector3(5, 0, 0));
|
|
||||||
let l2 = new Line(new Vector3(5, 0, 0), new Vector3(0, 5, 0));
|
|
||||||
|
|
||||||
let l3 = new Line(new Vector3(0, 5, 0), new Vector3(0, 0, 0));
|
|
||||||
let l4 = new Line(new Vector3(0, 0, 0), new Vector3(0, -5, 0));
|
|
||||||
|
|
||||||
let l5 = new Line(new Vector3(5, 0, 0), new Vector3(0, -5, 0));
|
|
||||||
let l6 = new Line(new Vector3(5, 0, 0), new Vector3(7, 0, 0));
|
|
||||||
culist.push(l1, l2, l3, l4, l5, l6);
|
|
||||||
|
|
||||||
let g = new RegionParse(culist);
|
|
||||||
g.RegionsOutline.length; //?
|
|
||||||
g.RegionsInternal.length; //?
|
|
||||||
expect(g.RegionsOutline.length).toBe(1);
|
|
||||||
expect(g.RegionsInternal.length).toBe(2);
|
|
||||||
|
|
||||||
expectReg(g);
|
|
||||||
});
|
|
||||||
test('区域内多条线', () =>
|
|
||||||
{
|
|
||||||
|
|
||||||
let culist = [];
|
|
||||||
|
|
||||||
let l1 = new Line(new Vector3(0, 0, 0), new Vector3(5, 0, 0));
|
|
||||||
let l2 = new Line(new Vector3(5, 0, 0), new Vector3(0, 5, 0));
|
|
||||||
|
|
||||||
let l3 = new Line(new Vector3(0, 4, 0), new Vector3(0, 0, 0));
|
let reg = new RegionParse(cus);
|
||||||
let l4 = new Line(new Vector3(0, 0, 0), new Vector3(0, -5, 0));
|
|
||||||
|
|
||||||
let l5 = new Line(new Vector3(5, 0, 0), new Vector3(0, -5, 0));
|
expect(reg.RegionsOutline.length).toMatchSnapshot();
|
||||||
let l6 = new Line(new Vector3(0, 4, 0), new Vector3(5, 0, 0));
|
expect(reg.RegionsInternal.length).toMatchSnapshot();
|
||||||
let l7 = new Line(new Vector3(0, 4, 0), new Vector3(0, 5, 0));
|
|
||||||
|
|
||||||
culist.push(l1, l2, l3, l4, l5, l6, l7);
|
for (let routes of [...reg.RegionsOutline, ...reg.RegionsInternal])
|
||||||
|
{
|
||||||
let g = new RegionParse(culist);
|
let pl = Polyline.Combine(routes.map(r => r.curve), 1e-3);
|
||||||
g.RegionsOutline.length; //?
|
expect(pl.Length).toMatchNumberSnapshot();
|
||||||
g.RegionsInternal.length; //?
|
}
|
||||||
expect(g.RegionsOutline.length).toBe(1);
|
|
||||||
expect(g.RegionsInternal.length).toBe(3);
|
|
||||||
|
|
||||||
expectReg(g);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('包含区域', () =>
|
|
||||||
{
|
|
||||||
|
|
||||||
let culist = [];
|
|
||||||
|
|
||||||
let l1 = new Line(new Vector3(0, 0, 0), new Vector3(5, 0, 0));
|
|
||||||
let l2 = new Line(new Vector3(5, 0, 0), new Vector3(5, 5, 0));
|
|
||||||
|
|
||||||
let l3 = new Line(new Vector3(5, 5, 0), new Vector3(0, 5, 0));
|
|
||||||
let l4 = new Line(new Vector3(0, 5, 0), new Vector3(0, 0, 0));
|
|
||||||
|
|
||||||
let l5 = new Line(new Vector3(1, 1, 0), new Vector3(2, 1, 0));
|
|
||||||
let l6 = new Line(new Vector3(2, 1, 0), new Vector3(2, 2, 0));
|
|
||||||
let l7 = new Line(new Vector3(2, 2, 0), new Vector3(1, 2, 0));
|
|
||||||
let l8 = new Line(new Vector3(1, 2, 0), new Vector3(1, 1, 0));
|
|
||||||
|
|
||||||
culist.push(l1, l2, l3, l4, l5, l6, l7, l8);
|
|
||||||
|
|
||||||
let g = new RegionParse(culist);
|
|
||||||
g.RegionsOutline.length; //?
|
|
||||||
g.RegionsInternal.length; //?
|
|
||||||
expect(g.RegionsOutline.length).toBe(2);
|
|
||||||
expect(g.RegionsInternal.length).toBe(0);
|
|
||||||
|
|
||||||
expectReg(g);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
test('测试复杂形状', () =>
|
|
||||||
{
|
|
||||||
let culist = [
|
|
||||||
new Line(new Vector3().fromArray([3.9668615984405444, -1.042884990253411, 0]), new Vector3().fromArray([2.553606237816763, -2.3391812865497075, 0])),
|
|
||||||
new Line(new Vector3().fromArray([2.553606237816763, -2.3391812865497075, 0]), new Vector3().fromArray([4.912280701754386, -2.7777777777777777, 0])),
|
|
||||||
new Line(new Vector3().fromArray([4.912280701754386, -2.7777777777777777, 0]), new Vector3().fromArray([3.011695906432749, -3.469785575048733, 0])),
|
|
||||||
new Line(new Vector3().fromArray([3.011695906432749, -3.469785575048733, 0]), new Vector3().fromArray([1.306042884990254, -0.30214424951267027, 0])),
|
|
||||||
new Line(new Vector3().fromArray([2.348927875243664, -1.042884990253411, 0]), new Vector3().fromArray([2.553606237816763, -2.3391812865497075, 0])),
|
|
||||||
new Line(new Vector3().fromArray([2.553606237816763, -2.3391812865497075, 0]), new Vector3().fromArray([3.011695906432749, -3.469785575048733, 0])),
|
|
||||||
new Line(new Vector3().fromArray([3.011695906432749, -3.469785575048733, 0]), new Vector3().fromArray([4.844054580896684, -3.898635477582846, 0])),
|
|
||||||
new Line(new Vector3().fromArray([4.844054580896684, -3.898635477582846, 0]), new Vector3().fromArray([4.912280701754386, -2.7777777777777777, 0])),
|
|
||||||
new Line(new Vector3().fromArray([4.912280701754386, -2.7777777777777777, 0]), new Vector3().fromArray([3.9668615984405444, -1.042884990253411, 0])),
|
|
||||||
new Line(new Vector3().fromArray([2.465886939571151, 1.939571150097466, 0]), new Vector3().fromArray([1.306042884990254, -0.30214424951267027, 0])),
|
|
||||||
new Line(new Vector3().fromArray([1.306042884990254, -0.30214424951267027, 0]), new Vector3().fromArray([3.586744639376219, 0.253411306042885, 0])),
|
|
||||||
new Line(new Vector3().fromArray([3.586744639376219, 0.253411306042885, 0]), new Vector3().fromArray([2.348927875243664, -1.042884990253411, 0])),
|
|
||||||
new Line(new Vector3().fromArray([2.348927875243664, -1.042884990253411, 0]), new Vector3().fromArray([3.9668615984405444, -1.042884990253411, 0])),
|
|
||||||
new Line(new Vector3().fromArray([1.306042884990254, -0.30214424951267027, 0]), new Vector3().fromArray([2.348927875243664, -1.042884990253411, 0])),
|
|
||||||
new Line(new Vector3().fromArray([3.9668615984405444, -1.042884990253411, 0]), new Vector3().fromArray([3.586744639376219, 0.253411306042885, 0])),
|
|
||||||
new Line(new Vector3().fromArray([3.586744639376219, 0.253411306042885, 0]), new Vector3().fromArray([2.465886939571151, 1.939571150097466, 0])),
|
|
||||||
];
|
|
||||||
|
|
||||||
let g = new RegionParse(culist);
|
|
||||||
g.RegionsOutline.length; //?
|
|
||||||
g.RegionsInternal.length; //?
|
|
||||||
expect(g.RegionsOutline.length).toBe(1);
|
|
||||||
expect(g.RegionsInternal.length).toBe(8);
|
|
||||||
|
|
||||||
expectReg(g);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
test('矩形套矩形', () =>
|
|
||||||
{
|
|
||||||
let culist = [
|
|
||||||
new Line(new Vector3().fromArray([12.781615108958839, -0.7407480871670697, 0]), new Vector3().fromArray([12.781615108958837, -5.947836900726392, 0])),
|
|
||||||
new Line(new Vector3().fromArray([12.781615108958837, -5.947836900726392, 0]), new Vector3().fromArray([19.5123215496368, -5.947836900726394, 0])),
|
|
||||||
new Line(new Vector3().fromArray([19.5123215496368, -5.947836900726394, 0]), new Vector3().fromArray([19.5123215496368, -0.7407480871670714, 0])),
|
|
||||||
new Line(new Vector3().fromArray([19.5123215496368, -0.7407480871670714, 0]), new Vector3().fromArray([12.781615108958839, -0.7407480871670697, 0])),
|
|
||||||
new Line(new Vector3().fromArray([12.781615108958839, -0.7407480871670697, 0]), new Vector3().fromArray([14.054086973365617, -2.0467060532687644, 0])),
|
|
||||||
new Line(new Vector3().fromArray([14.054086973365617, -2.0467060532687644, 0]), new Vector3().fromArray([18.54122460048426, -2.0467060532687653, 0])),
|
|
||||||
new Line(new Vector3().fromArray([18.54122460048426, -2.0467060532687653, 0]), new Vector3().fromArray([18.54122460048426, -5.026969104116222, 0])),
|
|
||||||
new Line(new Vector3().fromArray([18.54122460048426, -5.026969104116222, 0]), new Vector3().fromArray([14.054086973365617, -5.026969104116221, 0])),
|
|
||||||
new Line(new Vector3().fromArray([14.054086973365617, -5.026969104116221, 0]), new Vector3().fromArray([14.054086973365617, -2.0467060532687644, 0])),
|
|
||||||
new Line(new Vector3().fromArray([18.54122460048426, -5.026969104116222, 0]), new Vector3().fromArray([19.5123215496368, -5.947836900726394, 0])),
|
|
||||||
new Line(new Vector3().fromArray([14.054086973365617, -2.0467060532687644, 0]), new Vector3().fromArray([18.54122460048426, -5.026969104116222, 0]))
|
|
||||||
];
|
|
||||||
|
|
||||||
let g = new RegionParse(culist);
|
|
||||||
g.RegionsOutline.length; //?
|
|
||||||
g.RegionsInternal.length; //?
|
|
||||||
expect(g.RegionsOutline.length).toBe(1);
|
|
||||||
expect(g.RegionsInternal.length).toBe(4);
|
|
||||||
|
|
||||||
expectReg(g);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('保护伞', () =>
|
|
||||||
{
|
|
||||||
let culist = [
|
|
||||||
new Line(new Vector3().fromArray([-2.0843672456575684, 1.9106699751861045, 0]), new Vector3().fromArray([-4.01985111662531, -0.7196029776674939, 0])),
|
|
||||||
new Line(new Vector3().fromArray([-4.01985111662531, -0.7196029776674939, 0]), new Vector3().fromArray([-1.4640198511166256, -0.7196029776674939, 0])),
|
|
||||||
new Line(new Vector3().fromArray([-1.4640198511166256, -0.7196029776674939, 0]), new Vector3().fromArray([-2.0843672456575684, 1.9106699751861045, 0])),
|
|
||||||
new Line(new Vector3().fromArray([-2.0843672456575684, 1.9106699751861045, 0]), new Vector3().fromArray([-4.156327543424318, 2.7171215880893302, 0])),
|
|
||||||
new Line(new Vector3().fromArray([-4.156327543424318, 2.7171215880893302, 0]), new Vector3().fromArray([-1.7121588089330027, 4.094292803970223, 0])),
|
|
||||||
new Line(new Vector3().fromArray([-1.7121588089330027, 4.094292803970223, 0]), new Vector3().fromArray([-2.0843672456575684, 1.9106699751861045, 0])),
|
|
||||||
new Line(new Vector3().fromArray([-2.0843672456575684, 1.9106699751861045, 0]), new Vector3().fromArray([-0.33498759305210907, 2.7543424317617866, 0])),
|
|
||||||
new Line(new Vector3().fromArray([-0.33498759305210907, 2.7543424317617866, 0]), new Vector3().fromArray([-0.33498759305210946, 0.5583126550868487, 0])),
|
|
||||||
new Line(new Vector3().fromArray([-0.33498759305210946, 0.5583126550868487, 0]), new Vector3().fromArray([-2.0843672456575684, 1.9106699751861045, 0])),
|
|
||||||
];
|
|
||||||
let g = new RegionParse(culist);
|
|
||||||
g.RegionsOutline.length; //?
|
|
||||||
g.RegionsInternal.length; //?
|
|
||||||
expect(g.RegionsOutline.length).toBe(3);
|
|
||||||
expect(g.RegionsInternal.length).toBe(0);
|
|
||||||
|
|
||||||
expectReg(g);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
test('带圆弧的复杂图形测试', () =>
|
|
||||||
{
|
|
||||||
let cus = LoadCurvesFromFileData(
|
|
||||||
[23, "Line", 1, 1, -1, false, 0, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [135.10332884629918, 7.41153204925861, 0], [141.2013396407662, -3.6141642356868466, 0], "Line", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [141.2013396407662, -3.6141642356868466, 0], [129.0669141204631, -3.614164235686845, 0], "Line", 1, 1, -1, false, 2, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [129.0669141204631, -3.614164235686845, 0], [118.90356279635137, 9.936970863128803, 0], "Line", 1, 1, -1, false, 3, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [118.90356279635137, 9.936970863128803, 0], [129.25170232635605, 16.219769863488786, 0], "Line", 1, 1, -1, false, 4, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [129.25170232635605, 16.219769863488786, 0], [131.77714114022623, 24.28885485414719, 0], "Line", 1, 1, -1, false, 5, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [131.77714114022623, 24.28885485414719, 0], [121.09714288582433, 18.21968481731883, 0], "Line", 1, 1, -1, false, 6, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [121.09714288582433, 18.21968481731883, 0], [115.57737509027845, 20.531494667657398, 0], "Line", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [115.57737509027845, 20.531494667657398, 0], [118.90356279635137, 9.936970863128803, 0], "Line", 1, 1, -1, false, 0, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [129.25170232635605, 16.219769863488786, 0], [135.10332884629918, 7.41153204925861, 0], "Line", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [135.10332884629918, 7.41153204925861, 0], [141.07814750350425, 7.411532049258609, 0], "Line", 1, 1, -1, false, 2, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [141.07814750350425, 7.411532049258609, 0], [150.9951145530921, 6.9187635002107655, 0], "Line", 1, 1, -1, false, 3, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [150.9951145530921, 6.9187635002107655, 0], [146.62179368029246, 22.625761001110725, 0], "Line", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [115.57737509027845, 20.531494667657398, 0], [122.16815443379333, 33.2818808742703, 0], "Line", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [122.16815443379333, 33.2818808742703, 0], [131.77714114022623, 24.28885485414719, 0], "Line", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [131.77714114022623, 24.28885485414719, 0], [140.3389946799325, 29.339732481887566, 0], "Line", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [140.3389946799325, 29.339732481887566, 0], [146.62179368029246, 22.625761001110725, 0], "Arc", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 151.10541370131332, 26.821442121699068, 0, 1], 2, 6.14056907448819, 3.8938276244846772, 6.018122149019185, false, "Arc", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 161.1393080144557, 24.097737845466003, 0, 1], 2, 4.256430496141867, 2.8765294954293896, 5.103001249079749, true, "Arc", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 164.0426698023552, 17.04682100167833, 0, 1], 2, 3.368852318904628, 1.9614085954899536, 5.109952481560101, false, "Arc", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 168.0577082733428, 7.485478534075631, 0, 1], 2, 7.001287685275334, 1.9683598279703076, 3.2491377039705007, true, "Arc", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 156.0343039466818, 6.18741259702873, 0, 1], 2, 5.091984278064126, 0.10754505038070734, 2.997466317295445, false, "Arc", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 146.05997836303806, 7.635012886374687, 0, 1], 2, 4.986840923627034, 6.139058970885238, 3.1864217771069283, true, "Arc", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 138.09073817490173, 7.277519322534491, 0, 1], 2, 2.9904136682983347, 0.04482912351713572, 3.0967635300726575, false]
|
|
||||||
);
|
|
||||||
let g = new RegionParse(cus);
|
|
||||||
|
|
||||||
expect(g.RegionsInternal.length).toBe(7);
|
|
||||||
expect(g.RegionsOutline.length).toBe(1);
|
|
||||||
});
|
});
|
||||||
|
@ -1,94 +1,152 @@
|
|||||||
import { Vector3 } from "three";
|
import { Vector3 } from "three";
|
||||||
import { ToFixed } from "../Common/Utils";
|
import { Arc } from "../DatabaseServices/Entity/Arc";
|
||||||
import { Curve } from "../DatabaseServices/Entity/Curve";
|
import { Curve } from "../DatabaseServices/Entity/Curve";
|
||||||
import { angle, equalv3 } from "./GeUtils";
|
import { angle, clampRad, equalv3 } from "./GeUtils";
|
||||||
import { Route, Stand } from "./RegionParse";
|
|
||||||
|
//顶点
|
||||||
|
export interface Vertice
|
||||||
|
{
|
||||||
|
//位置
|
||||||
|
position: Vector3;
|
||||||
|
//路径
|
||||||
|
routes: Route[];
|
||||||
|
}
|
||||||
|
|
||||||
|
//路线
|
||||||
|
export interface Route
|
||||||
|
{
|
||||||
|
curve: Curve; //路线的曲线
|
||||||
|
from: Vertice;
|
||||||
|
to: Vertice; //终点的点
|
||||||
|
length: number;
|
||||||
|
isReverse: boolean;
|
||||||
|
an?: number; //角度
|
||||||
|
|
||||||
|
s: Vector3;
|
||||||
|
e: Vector3;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 曲线地图,使用站点连接.
|
* 曲线地图,使用站点连接.
|
||||||
*/
|
*/
|
||||||
export class CurveMap
|
export class CurveMap
|
||||||
{
|
{
|
||||||
constructor(public fractionDigits = 4)
|
constructor(
|
||||||
{
|
public numdimensions = 4,
|
||||||
|
public _RemoveSortLine = false,
|
||||||
}
|
private multiplier = 10 ^ numdimensions,
|
||||||
|
) { }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
节点图.
|
节点图.
|
||||||
每个节点对应下一个路口的路线表.
|
每个节点对应下一个路口的路线表.
|
||||||
路口表使用逆时针排序,起始角度使用正x轴.
|
路口表使用逆时针排序,起始角度使用正x轴.
|
||||||
*/
|
*/
|
||||||
m_NodeMap = new Map<Vector3, Stand>();
|
_NodeMap = new Map<Vector3, Vertice>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 得到节点图的所有站点列表
|
* 得到节点图的所有站点列表
|
||||||
* @type {Stand[]}
|
|
||||||
*/
|
*/
|
||||||
get Stands(): Stand[]
|
get Stands(): Vertice[]
|
||||||
{
|
{
|
||||||
let stands = [];
|
let stands: Vertice[] = [];
|
||||||
this.m_NodeMap.forEach(s => stands.push(s));
|
this._NodeMap.forEach(s => stands.push(s));
|
||||||
return stands;
|
return stands;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCurveToMap(cu: Curve)
|
AddCurveToMap(curve: Curve, isArc: boolean = curve instanceof Arc, removeDuplicate: boolean = false)
|
||||||
{
|
{
|
||||||
cu.TempData = 0;
|
let sp = curve.StartPoint;
|
||||||
let sp = cu.StartPoint;
|
let ep = curve.EndPoint;
|
||||||
let ep = cu.EndPoint;
|
|
||||||
let startS = this.GetStand(sp);
|
let startS = this.GetStand(sp);
|
||||||
let endS = this.GetStand(ep);
|
let endS = this.GetStand(ep);
|
||||||
let routeS2E: Route = { curve: cu, to: endS, s: sp, e: ep };
|
|
||||||
CalcRouteAngle(routeS2E, startS.position);
|
//在面域分析中,路线指向同一个顶点已经没有意义了
|
||||||
let routeE2S: Route = { curve: cu, to: startS, s: ep, e: sp };
|
if (this._RemoveSortLine && startS === endS)
|
||||||
CalcRouteAngle(routeE2S, endS.position);
|
return;
|
||||||
|
|
||||||
|
if (removeDuplicate)//删除重复
|
||||||
|
{
|
||||||
|
let index = startS.routes.findIndex(r =>
|
||||||
|
{
|
||||||
|
if (r.to === endS && r.curve.constructor.name === curve.constructor.name)
|
||||||
|
{
|
||||||
|
if (isArc)
|
||||||
|
return equalv3(curve.GetPointAtParam(0.5), r.curve.GetPointAtParam(0.5));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (index !== -1) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let length = curve.Length;
|
||||||
|
curve.TempData = 0;
|
||||||
|
|
||||||
|
let routeS2E: Route = { curve, isReverse: false, length, from: startS, to: endS, s: sp, e: ep };
|
||||||
|
let routeE2S: Route = { curve, isReverse: true, length, from: endS, to: startS, e: sp, s: ep };
|
||||||
|
|
||||||
|
if (!isArc)
|
||||||
|
{
|
||||||
|
let an = angle(ep.clone().sub(sp));
|
||||||
|
routeS2E.an = an;
|
||||||
|
routeE2S.an = clampRad(an + Math.PI);
|
||||||
|
}
|
||||||
startS.routes.push(routeS2E);
|
startS.routes.push(routeS2E);
|
||||||
endS.routes.push(routeE2S);
|
endS.routes.push(routeE2S);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得指定点的站台.
|
* 获得唯一的顶点
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Vector3} p
|
|
||||||
* @returns {Stand}
|
|
||||||
* @memberof RegionAlg
|
|
||||||
*/
|
*/
|
||||||
GetStand(p: Vector3): Stand
|
GetStand(p: Vector3): Vertice
|
||||||
{
|
{
|
||||||
let gp = this.GenerateP(p);
|
let gp = this.GenerateP(p);
|
||||||
if (this.m_NodeMap.has(gp))
|
if (this._NodeMap.has(gp))
|
||||||
return this.m_NodeMap.get(gp);
|
return this._NodeMap.get(gp);
|
||||||
|
|
||||||
let stand = { position: gp, routes: [] };
|
let stand = { position: gp, routes: [] };
|
||||||
this.m_NodeMap.set(p, stand);
|
this._NodeMap.set(p, stand);
|
||||||
return stand;
|
return stand;
|
||||||
}
|
}
|
||||||
|
|
||||||
private m_vecMap = new Map<string, Vector3>();
|
_LookupTable: { [key: string]: Vector3; } = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成一个唯一的向量.
|
* 生成一个唯一的向量.
|
||||||
*
|
|
||||||
* @param {Vector3} v
|
|
||||||
* @returns {Vector3}
|
|
||||||
* @memberof RegionAlg
|
|
||||||
*/
|
*/
|
||||||
private GenerateP(v: Vector3): Vector3
|
GenerateP(v: Vector3): Vector3
|
||||||
{
|
{
|
||||||
let str = v.toArray().map(v => ToFixed(v, this.fractionDigits)).join(",");
|
let key = "";
|
||||||
if (this.m_vecMap.has(str))
|
let els = v.toArray();
|
||||||
return this.m_vecMap.get(str);
|
for (let n of els)
|
||||||
this.m_vecMap.set(str, v);
|
{
|
||||||
return v;
|
let valueQuantized = Math.round(n * this.multiplier);
|
||||||
|
key += valueQuantized + '/';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function CalcRouteAngle(r: Route, standPoint: Vector3)
|
if (key in this._LookupTable)
|
||||||
{
|
return this._LookupTable[key];
|
||||||
if (equalv3(r.curve.StartPoint, standPoint))
|
|
||||||
r.an = angle(r.curve.GetFistDeriv(0));
|
let hashparts = els.map((el) =>
|
||||||
else
|
{
|
||||||
r.an = angle(r.curve.GetFistDeriv(r.curve.EndParam).negate());
|
let q0 = Math.floor(el * this.multiplier);
|
||||||
|
let q1 = q0 + 1;
|
||||||
|
return ['' + q0 + '/', '' + q1 + '/'];
|
||||||
|
});
|
||||||
|
|
||||||
|
let numelements = els.length;
|
||||||
|
let numhashes = 1 << numelements;
|
||||||
|
for (let hashmask = 0; hashmask < numhashes; ++hashmask)
|
||||||
|
{
|
||||||
|
let hashmaskShifted = hashmask;
|
||||||
|
key = '';
|
||||||
|
hashparts.forEach(function (hashpart)
|
||||||
|
{
|
||||||
|
key += hashpart[hashmaskShifted & 1];
|
||||||
|
hashmaskShifted >>= 1;
|
||||||
|
});
|
||||||
|
this._LookupTable[key] = v;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in new issue