分离equalv3 和equalv2(使用equaln而不是distansSq)

直线使用新的计算最近点算法
提高了点在区线上的精度需求(大概1e-6)
pull/76/head
ChenX 6 years ago
parent 0eac5b2838
commit 615563bbb3

@ -1,6 +1,6 @@
import { Vector3 } from 'three'; import { Vector3 } from 'three';
import { Arc } from '../../src/DatabaseServices/Arc'; import { Arc } from '../../src/DatabaseServices/Arc';
import { equal, equaln } from '../../src/Geometry/GeUtils'; import { equaln, equalv3 } from '../../src/Geometry/GeUtils';
test("三点共线", () => test("三点共线", () =>
{ {
@ -124,7 +124,7 @@ test("由距离得到对应点", () =>
{ {
let arc = new Arc(new Vector3(5, 0, 0), 5, Math.PI, 0); let arc = new Arc(new Vector3(5, 0, 0), 5, Math.PI, 0);
expect(equal(arc.GetPointAtDistance(0.5 * Math.PI * 5), new Vector3(5, 5, 0))).toBeTruthy(); expect(equalv3(arc.GetPointAtDistance(0.5 * Math.PI * 5), new Vector3(5, 5, 0))).toBeTruthy();
} }
); );

@ -1,10 +1,6 @@
import { Vector3 } from 'three';
import { Circle } from '../../src/DatabaseServices/Circle'; import { Circle } from '../../src/DatabaseServices/Circle';
import { Vector3, Vector2 } from 'three'; import { equaln, equalv3 } from '../../src/Geometry/GeUtils';
import { app } from '../../src/ApplicationServices/Application';
import { Command } from '../../src/Editor/CommandMachine';
import { PromptStatus } from '../../src/Editor/PromptResult';
import { RenderType } from '../../src/GraphicsSystem/Enum';
import { equal, equaln } from '../../src/Geometry/GeUtils';
test('圆参数', () => test('圆参数', () =>
{ {
@ -62,7 +58,7 @@ test("由距离得到圆参数", () =>
test("由距离得到对应点", () => test("由距离得到对应点", () =>
{ {
let circle = new Circle(new Vector3(5, 0, 0), 5); let circle = new Circle(new Vector3(5, 0, 0), 5);
expect(equal(circle.GetPointAtDistance(0.5 * Math.PI * 5), new Vector3(5, 5, 0))).toBeTruthy(); expect(equalv3(circle.GetPointAtDistance(0.5 * Math.PI * 5), new Vector3(5, 5, 0))).toBeTruthy();
} }
); );

@ -1,6 +1,5 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { equaln, equalv3 } from '../../src/Geometry/GeUtils';
import { equaln ,equal} from '../../src/Geometry/GeUtils';
import { Orbit } from '../../src/Geometry/Orbit'; import { Orbit } from '../../src/Geometry/Orbit';
test("", () => test("", () =>
@ -17,7 +16,7 @@ test("", () =>
//试着还原 //试着还原
orb.UpdateDirection(dir); orb.UpdateDirection(dir);
expect(equal(dir, new THREE.Vector3(0, 1, 0))).toBe(true); expect(equalv3(dir, new THREE.Vector3(0, 1, 0))).toBe(true);
//试试新的 //试试新的
dir.set(1, 0, 0); dir.set(1, 0, 0);
@ -27,7 +26,7 @@ test("", () =>
//试着还原 //试着还原
orb.UpdateDirection(dir); orb.UpdateDirection(dir);
expect(equal(dir, new THREE.Vector3(1, 0, 0))).toBe(true); expect(equalv3(dir, new THREE.Vector3(1, 0, 0))).toBe(true);
//试试新的 //试试新的
dir.set(0.5, 0.5, 0).normalize(); dir.set(0.5, 0.5, 0).normalize();
@ -38,7 +37,7 @@ test("", () =>
//试着还原 //试着还原
orb.UpdateDirection(dir); orb.UpdateDirection(dir);
console.log('dir: ', dir); console.log('dir: ', dir);
expect(equal(dir, dirc)).toBe(true); expect(equalv3(dir, dirc)).toBe(true);
//试试新的 //试试新的
dir.set(0.5, 0.5, 1).normalize(); dir.set(0.5, 0.5, 1).normalize();
@ -48,7 +47,7 @@ test("", () =>
//试着还原 //试着还原
orb.UpdateDirection(dir); orb.UpdateDirection(dir);
console.log('dir: ', dir); console.log('dir: ', dir);
expect(equal(dir, dirc)).toBe(true); expect(equalv3(dir, dirc)).toBe(true);
dir.set(0, 0, -1); dir.set(0, 0, -1);
dirc = dir.clone(); dirc = dir.clone();
@ -60,7 +59,7 @@ test("", () =>
//试着还原 //试着还原
orb.UpdateDirection(dir); orb.UpdateDirection(dir);
console.log('dir: ', dir); console.log('dir: ', dir);
expect(equal(dir, dirc)).toBe(true); expect(equalv3(dir, dirc)).toBe(true);
let newDir = orb.UpdateDirection(); let newDir = orb.UpdateDirection();
@ -68,7 +67,7 @@ test("", () =>
let up = Orbit.ComputUpDirection(new THREE.Vector3(0, 0, 1)); let up = Orbit.ComputUpDirection(new THREE.Vector3(0, 0, 1));
expect(equal(up, new THREE.Vector3(0, -1, 0))).toBe(true); expect(equalv3(up, new THREE.Vector3(0, -1, 0))).toBe(true);
Orbit.ComputUpDirection(new THREE.Vector3(0, 0, -1), up); Orbit.ComputUpDirection(new THREE.Vector3(0, 0, -1), up);
console.log(up); console.log(up);
@ -80,7 +79,7 @@ test("", () =>
let newD = orb.UpdateDirection(); let newD = orb.UpdateDirection();
console.log(newD); console.log(newD);
expect(equal(newD, new THREE.Vector3(0, 0, -1))).toBe(true); expect(equalv3(newD, new THREE.Vector3(0, 0, -1))).toBe(true);
}) })

@ -34,8 +34,8 @@ Vector3 {
exports[`最近点 1`] = ` exports[`最近点 1`] = `
Vector3 { Vector3 {
"x": -2.499999999999999, "x": -2.4999999999999996,
"y": -2.499999999999999, "y": -2.4999999999999996,
"z": 0, "z": 0,
} }
`; `;
@ -127,3 +127,7 @@ Vector3 {
"z": 0, "z": 0,
} }
`; `;
exports[`直线参数 1`] = `-0.9999999999999999`;
exports[`直线参数 2`] = `1.9999999999999998`;

@ -12,9 +12,9 @@ test('直线参数', () =>
expect(l.GetParamAtPoint(new Vector3(5, 5, 0))).toBe(1); expect(l.GetParamAtPoint(new Vector3(5, 5, 0))).toBe(1);
expect(l.GetParamAtPoint(new Vector3(-5, -5, 0))).toBe(-1); expect(l.GetParamAtPoint(new Vector3(-5, -5, 0))).toMatchSnapshot();
expect(l.GetParamAtPoint(new Vector3(10, 10, 0))).toBe(2); expect(l.GetParamAtPoint(new Vector3(10, 10, 0))).toMatchSnapshot();
expect(l.GetParamAtPoint(new Vector3(11, 10, 0))).toBe(NaN); expect(l.GetParamAtPoint(new Vector3(11, 10, 0))).toBe(NaN);

@ -12,10 +12,48 @@ exports[`IKKGK圆与直线补圆弧 5`] = `1`;
exports[`IKKGK圆与直线补圆弧 6`] = `52.52605376818707`; exports[`IKKGK圆与直线补圆弧 6`] = `52.52605376818707`;
exports[`IKKGK圆与直线补圆弧 7`] = `2`;
exports[`IKKGK圆与直线补圆弧 8`] = `15.234528310991957`;
exports[`IKKGK圆与直线补圆弧 9`] = `37.292463663372004`;
exports[`IKKGK圆与直线补圆弧 10`] = `6.283185307179586`;
exports[`IKKGK圆与直线补圆弧 11`] = `39.37762788501941`;
exports[`IKKGK圆与直线补圆弧 12`] = `58.582296960642424`;
exports[`IKKGK圆与直线补圆弧 13`] = `5`;
exports[`IKKGK圆与直线补圆弧 14`] = `52.52605376818707`;
exports[`IKKGK圆与直线补圆弧 15`] = `12.10385896662238`;
exports[`IKKGK圆与直线补圆弧 16`] = `12.10385896662238`;
exports[`IKKGK圆与直线补圆弧 17`] = `37.51446423182355`;
exports[`IKKGK圆与直线补圆弧 18`] = `71.87112445902166`;
exports[`中间区域需要圆裁剪 1`] = `1`; exports[`中间区域需要圆裁剪 1`] = `1`;
exports[`中间区域需要圆裁剪 2`] = `24.711300177432392`; exports[`中间区域需要圆裁剪 2`] = `24.711300177432392`;
exports[`中间区域需要圆裁剪 3`] = `223.68139693559328`;
exports[`中间区域需要圆裁剪 4`] = `223.68139693559328`;
exports[`中间区域需要圆裁剪 5`] = `150.4931383967326`;
exports[`中间区域需要圆裁剪 6`] = `106.06313658304032`;
exports[`中间区域需要圆裁剪 7`] = `223.68139693559328`;
exports[`中间区域需要圆裁剪 8`] = `223.68139693559328`;
exports[`中间区域需要圆裁剪 9`] = `223.68139693559328`;
exports[`圆求交错误导致的线丢失 1`] = `4148.643109243218`; exports[`圆求交错误导致的线丢失 1`] = `4148.643109243218`;
exports[`圆求交错误导致的线丢失 2`] = `4425.268216257021`; exports[`圆求交错误导致的线丢失 2`] = `4425.268216257021`;
@ -40,6 +78,34 @@ exports[`多段线存在0长度线段导致偏移错误 3`] = `1`;
exports[`多段线存在0长度线段导致偏移错误 4`] = `86143.95799639553`; exports[`多段线存在0长度线段导致偏移错误 4`] = `86143.95799639553`;
exports[`多段线存在0长度线段导致偏移错误 5`] = `12931.456758241411`;
exports[`多段线存在0长度线段导致偏移错误 6`] = `10056.231029584353`;
exports[`多段线存在0长度线段导致偏移错误 7`] = `17891.674969196265`;
exports[`多段线存在0长度线段导致偏移错误 8`] = `9355.91677188456`;
exports[`多段线存在0长度线段导致偏移错误 9`] = `2140.6181396506136`;
exports[`多段线存在0长度线段导致偏移错误 10`] = `8`;
exports[`多段线存在0长度线段导致偏移错误 11`] = `9773.1166496292`;
exports[`多段线存在0长度线段导致偏移错误 12`] = `11370.157165896057`;
exports[`多段线存在0长度线段导致偏移错误 13`] = `9341.707068201697`;
exports[`多段线存在0长度线段导致偏移错误 14`] = `14993.848091308573`;
exports[`多段线存在0长度线段导致偏移错误 15`] = `10038.32067141617`;
exports[`多段线存在0长度线段导致偏移错误 16`] = `18161.102674842623`;
exports[`多段线存在0长度线段导致偏移错误 17`] = `9582.108634127204`;
exports[`多段线存在0长度线段导致偏移错误 18`] = `2883.804539574228`;
exports[`拱门偏移 1`] = `1`; exports[`拱门偏移 1`] = `1`;
exports[`拱门偏移 2`] = `4.314156035548454`; exports[`拱门偏移 2`] = `4.314156035548454`;
@ -48,6 +114,26 @@ exports[`拱门偏移 3`] = `1`;
exports[`拱门偏移 4`] = `6.827404319936081`; exports[`拱门偏移 4`] = `6.827404319936081`;
exports[`拱门偏移 5`] = `3`;
exports[`拱门偏移 6`] = `2`;
exports[`拱门偏移 7`] = `2.827433388230814`;
exports[`拱门偏移 8`] = `2`;
exports[`拱门偏移 9`] = `6.827404319936081`;
exports[`拱门偏移 10`] = `2.5132741228718345`;
exports[`拱门偏移 11`] = `2.5132741228718345`;
exports[`拱门偏移 12`] = `4.800000000000001`;
exports[`拱门偏移 13`] = `5.198184497678349`;
exports[`拱门偏移 14`] = `4.800000000000001`;
exports[`简单图形因为点在线内算法错误导致的丢失 1`] = `8.675026988029915`; exports[`简单图形因为点在线内算法错误导致的丢失 1`] = `8.675026988029915`;
exports[`简单图形因为点在线内算法错误导致的丢失 2`] = `8.252659494518674`; exports[`简单图形因为点在线内算法错误导致的丢失 2`] = `8.252659494518674`;

@ -2,9 +2,9 @@
exports[`补充bug测试#IKWGF 1`] = `1.1376402440608806`; exports[`补充bug测试#IKWGF 1`] = `1.1376402440608806`;
exports[`补充bug测试#IKWGF 2`] = `0.44573816538516137`; exports[`补充bug测试#IKWGF 2`] = `0.44573896329246554`;
exports[`补充bug测试#IKWGF 3`] = `10.733056812077686`; exports[`补充bug测试#IKWGF 3`] = `10.73282822209507`;
exports[`补充bug测试#IKWGF 4`] = `12.786755410504352`; exports[`补充bug测试#IKWGF 4`] = `12.786755410504352`;
@ -14,9 +14,9 @@ exports[`补充bug测试#IKWGF 6`] = `10.586543051841131`;
exports[`补充bug测试#IKWGF 7`] = `14.066950838248612`; exports[`补充bug测试#IKWGF 7`] = `14.066950838248612`;
exports[`补充bug测试#IKWGF 8`] = `2.16930889523746`; exports[`补充bug测试#IKWGF 8`] = `2.168984971098264`;
exports[`补充bug测试#IKWGF 9`] = `11.890848111457423`; exports[`补充bug测试#IKWGF 9`] = `11.89085508498112`;
exports[`补充bug测试#IKWGF 10`] = `1.0803373815793473`; exports[`补充bug测试#IKWGF 10`] = `1.0803373815793473`;

@ -59,4 +59,4 @@ test('补充bug测试#IKWGF', () =>
expect(cus[1].Length).toMatchSnapshot(); expect(cus[1].Length).toMatchSnapshot();
expect(cus[2].Length).toMatchSnapshot(); expect(cus[2].Length).toMatchSnapshot();
}) });

@ -1,8 +1,7 @@
import { Vector2, Vector3 } from 'three'; import { Vector2, Vector3 } from 'three';
import { Polyline } from '../../src/DatabaseServices/Polyline';
import { equal, equaln } from '../../src/Geometry/GeUtils';
import { CADFile } from '../../src/DatabaseServices/CADFile'; import { CADFile } from '../../src/DatabaseServices/CADFile';
import { Polyline } from '../../src/DatabaseServices/Polyline';
import { equaln, equalv3 } from '../../src/Geometry/GeUtils';
test("多段线点获取参数", () => test("多段线点获取参数", () =>
{ {
@ -88,12 +87,12 @@ describe('多段线', () =>
} }
]) ])
expect(equal(pl.GetPointAtParam(1), new Vector3(5, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(1), new Vector3(5, 0, 0))).toBeTruthy();
expect(equal(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(equal(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(equal(pl.GetPointAtParam(4.5), new Vector3(0, 5, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(4.5), new Vector3(0, 5, 0))).toBeTruthy();
expect(equal(pl.GetPointAtParam(5), new Vector3(0, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(5), new Vector3(0, 0, 0))).toBeTruthy();
expect(equal(pl.GetPointAtParam(5.5), new Vector3(0, -5, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtParam(5.5), new Vector3(0, -5, 0))).toBeTruthy();
}) })
test("多段线参数获取弧长", () => test("多段线参数获取弧长", () =>
{ {
@ -158,11 +157,11 @@ describe('多段线', () =>
bul: 0 bul: 0
} }
]) ])
expect(equal(pl.GetPointAtDistance(5), new Vector3(5, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(5), new Vector3(5, 0, 0))).toBeTruthy();
expect(equal(pl.GetPointAtDistance(2.5), new Vector3(2.5, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(2.5), new Vector3(2.5, 0, 0))).toBeTruthy();
expect(equal(pl.GetPointAtDistance(5 + Math.PI * 2.5), new Vector3(5, 5, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(5 + Math.PI * 2.5), new Vector3(5, 5, 0))).toBeTruthy();
expect(equal(pl.GetPointAtDistance(5 + Math.PI * 2.5 * 2), new Vector3(5, 10, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(5 + Math.PI * 2.5 * 2), new Vector3(5, 10, 0))).toBeTruthy();
expect(equal(pl.GetPointAtDistance(0), new Vector3(0, 0, 0))).toBeTruthy(); expect(equalv3(pl.GetPointAtDistance(0), new Vector3(0, 0, 0))).toBeTruthy();
}) })
test("多段线距离获取参数", () => test("多段线距离获取参数", () =>
{ {
@ -305,10 +304,10 @@ describe('多段线', () =>
} }
]) ])
pl3.Extend(1.5); pl3.Extend(1.5);
expect(equal(pl3.EndPoint, new Vector3(-2.5, 2.5, 0))).toBeTruthy(); expect(equalv3(pl3.EndPoint, new Vector3(-2.5, 2.5, 0))).toBeTruthy();
pl3.Extend(1 + 1 / 3); pl3.Extend(1 + 1 / 3);
// expect(pl3.EndPoint).toEqual(new Vector3(0, 0, 0)); // expect(pl3.EndPoint).toEqual(new Vector3(0, 0, 0));
expect(equal(pl3.EndPoint /*?*/, new Vector3(0, 0, 0))).toBeTruthy(); expect(equalv3(pl3.EndPoint /*?*/, new Vector3(0, 0, 0))).toBeTruthy();
}) })
test("多段线延伸,闭合", () => test("多段线延伸,闭合", () =>
{ {
@ -408,8 +407,8 @@ describe('多段线', () =>
expect(pl.GetClosestPointTo(new Vector3(), true)).toEqual(new Vector3()); 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(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(pl.GetClosestPointTo(new Vector3(1.5, 3.5), true)).toEqual(new Vector3(0, 3.5, 0));
expect(equal(pl.GetClosestPointTo(new Vector3(1.5, 3.5), true), new Vector3(0, 3.5, 0))).toBeTruthy(); expect(equalv3(pl.GetClosestPointTo(new Vector3(1.5, 3.5), true), new Vector3(0, 3.5, 0))).toBeTruthy();
expect(equal(pl.GetClosestPointTo(new Vector3(-0.5, -1), true), new Vector3(0, -1, 0))).toBeTruthy(); expect(equalv3(pl.GetClosestPointTo(new Vector3(-0.5, -1), true), new Vector3(0, -1, 0))).toBeTruthy();
}) })
test("多段线包围盒", () => test("多段线包围盒", () =>
@ -529,3 +528,30 @@ test('最近点参数刚好在端点上', () =>
expect(equaln(param, 1)).toBeTruthy(); expect(equaln(param, 1)).toBeTruthy();
}); });
function loadFile(data)
{
let file = new CADFile();
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, 4, false, 2, -1, [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();
});

@ -12,6 +12,7 @@
"build": "webpack", "build": "webpack",
"i": "npm i && npm i -dev", "i": "npm i && npm i -dev",
"test": "jest", "test": "jest",
"testu": "jest -u",
"ser": "node ./utils/server.js", "ser": "node ./utils/server.js",
"type": "node ./utils/copy_type.js" "type": "node ./utils/copy_type.js"
}, },

@ -7,7 +7,7 @@ import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline';
import { Polyline } from '../DatabaseServices/Polyline'; import { Polyline } from '../DatabaseServices/Polyline';
import { Count } from '../Geometry/Count'; import { Count } from '../Geometry/Count';
import { CurveMap } from '../Geometry/CurveMap'; import { CurveMap } from '../Geometry/CurveMap';
import { equal, equaln } from '../Geometry/GeUtils'; import { equaln, equalv2, equalv3 } from '../Geometry/GeUtils';
import { Stand } from '../Geometry/RegionParse'; import { Stand } from '../Geometry/RegionParse';
import { FixIndex } from './Utils'; import { FixIndex } from './Utils';
@ -135,14 +135,14 @@ export function curveLinkGroup(cus: Curve[]): Array<Array<Curve>>
if (isEndSeach) if (isEndSeach)
{ {
//保证曲线总是从起点连接到终点 //保证曲线总是从起点连接到终点
if (!equal(cu.StartPoint, stand.position)) if (!equalv3(cu.StartPoint, stand.position))
cu.Reverse(); cu.Reverse();
cus.push(cu); cus.push(cu);
} }
else else
{ {
//保证曲线总是从起点连接到终点 //保证曲线总是从起点连接到终点
if (!equal(cu.EndPoint, stand.position)) if (!equalv3(cu.EndPoint, stand.position))
cu.Reverse(); cu.Reverse();
cus.unshift(cu); cus.unshift(cu);
} }
@ -198,17 +198,17 @@ export function equalCurveAndCurve(cu1: Curve, cu2: Curve)
return ptsAndBuls1.pts.every((pt, i) => return ptsAndBuls1.pts.every((pt, i) =>
{ {
return equal(pt, pts2[i]); return equalv2(pt, pts2[i]);
}) })
} }
else if (cu1 instanceof Circle && cu2 instanceof Circle) else if (cu1 instanceof Circle && cu2 instanceof Circle)
{ {
return equal(cu1.Center, cu2.Center) && equaln(cu1.Radius, cu2.Radius, 1e-6) return equalv3(cu1.Center, cu2.Center) && equaln(cu1.Radius, cu2.Radius, 1e-6)
} }
else if (cu1 instanceof Arc && cu2 instanceof Arc) else if (cu1 instanceof Arc && cu2 instanceof Arc)
{ {
if (!equal(cu1.StartPoint, cu2.EndPoint)) cu1.Reverse(); if (!equalv3(cu1.StartPoint, cu2.EndPoint)) cu1.Reverse();
return equal(cu1.Center, cu2.Center) && equaln(cu1.Radius, cu2.Radius, 1e-6) && equaln(cu1.StartAngle, cu2.StartAngle) && equaln(cu1.EndAngle, cu2.EndAngle) return equalv3(cu1.Center, cu2.Center) && equaln(cu1.Radius, cu2.Radius, 1e-6) && equaln(cu1.StartAngle, cu2.StartAngle) && equaln(cu1.EndAngle, cu2.EndAngle)
} }
return false; return false;
} }
@ -226,6 +226,13 @@ export function GetPointAtCurveDir(cu: Curve, pt: Vector3): boolean
let cp = cu.GetClosestPointTo(pt, false); let cp = cu.GetClosestPointTo(pt, false);
//最近点参数 //最近点参数
let cparam = cu.GetParamAtPoint(cp); let cparam = cu.GetParamAtPoint(cp);
if (isNaN(cparam))
{
//最近点
let cp = cu.GetClosestPointTo(pt, false);
//最近点参数
let cparam = cu.GetParamAtPoint(cp);
}
//归一化最近点参数 //归一化最近点参数
let floorParam = Math.floor(cparam + 0.5); let floorParam = Math.floor(cparam + 0.5);
@ -244,7 +251,7 @@ export function GetPointAtCurveDir(cu: Curve, pt: Vector3): boolean
) )
{ {
let plVerCount = cu.NumberOfVertices; let plVerCount = cu.NumberOfVertices;
if (equal(cu.GetPoint2dAt(0), cu.GetPoint2dAt(plVerCount - 1))) if (equalv2(cu.GetPoint2dAt(0), cu.GetPoint2dAt(plVerCount - 1)))
plVerCount--; plVerCount--;
//分三点,本点,前一个点,后一个点 //分三点,本点,前一个点,后一个点
@ -266,9 +273,9 @@ export function GetPointAtCurveDir(cu: Curve, pt: Vector3): boolean
let cp1 = l1.GetClosestPointTo(pt, true); let cp1 = l1.GetClosestPointTo(pt, true);
let cp2 = l2.GetClosestPointTo(pt, true); let cp2 = l2.GetClosestPointTo(pt, true);
if (equal(fDer, nDer.clone().negate())) if (equalv3(fDer, nDer.clone().negate()))
return true; return true;
if (equal(fDer, nDer)) if (equalv3(fDer, nDer))
return fDer.cross(pt.clone().sub(cp1)).z < 0; return fDer.cross(pt.clone().sub(cp1)).z < 0;
let adir = Math.sign(fDer.clone().cross(nDer).z); let adir = Math.sign(fDer.clone().cross(nDer).z);

@ -3,7 +3,7 @@ import { Box3, Matrix4, Object3D, ShapeGeometry, Vector2, Vector3 } from 'three'
import { ColorMaterial } from '../Common/ColorPalette'; import { ColorMaterial } from '../Common/ColorPalette';
import { Vec2DTo3D, getCircleCenter } from '../Common/CurveUtils'; import { Vec2DTo3D, getCircleCenter } from '../Common/CurveUtils';
import { matrixSetVector } from '../Common/Matrix4Utils'; import { matrixSetVector } from '../Common/Matrix4Utils';
import { angle, angleTo2Pi, equal, equaln, midPoint, polar, MoveMatrix } from '../Geometry/GeUtils'; import { angle, angleTo2Pi, equalv3, equaln, midPoint, polar, MoveMatrix } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum'; import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectArcAndArc, IntersectCircleAndArc, IntersectLineAndArc, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../GraphicsSystem/IntersectWith'; import { IntersectArcAndArc, IntersectCircleAndArc, IntersectLineAndArc, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../GraphicsSystem/IntersectWith';
import { Factory } from './CADFactory'; import { Factory } from './CADFactory';
@ -204,7 +204,7 @@ export class Arc extends Curve
{ {
if (this.m_Radius == 0 || if (this.m_Radius == 0 ||
this.AllAngle == 0 || this.AllAngle == 0 ||
!equaln(pt.distanceToSquared(this.Center), this.m_Radius * this.m_Radius, 1e-4)) !equaln(pt.distanceTo(this.Center), this.m_Radius, 1e-8))
return NaN; return NaN;
let ptTmp = pt.clone().applyMatrix4(this.OCSInv); let ptTmp = pt.clone().applyMatrix4(this.OCSInv);
@ -290,7 +290,7 @@ export class Arc extends Curve
if (cu instanceof Arc) if (cu instanceof Arc)
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
if (equal(cu.Center, this.Center) && equaln(cu.m_Radius, this.m_Radius)) if (equalv3(cu.Center, this.Center) && equaln(cu.m_Radius, this.m_Radius))
{ {
let [sa, ea] = [cu.StartAngle, cu.EndAngle]; let [sa, ea] = [cu.StartAngle, cu.EndAngle];
if (cu.m_Clockwise != this.m_Clockwise) if (cu.m_Clockwise != this.m_Clockwise)

@ -293,7 +293,8 @@ export class Circle extends Curve
} }
GetClosestPointTo(pt: Vector3, extend: boolean): Vector3 GetClosestPointTo(pt: Vector3, extend: boolean): Vector3
{ {
if (pt.distanceToSquared(this.Center) == 0) return this.GetPointAtParam(0); if (equaln(pt.distanceToSquared(this.Center), 0, 1e-10))
return this.GetPointAtParam(0);
let l = new Line(this.Center, pt); let l = new Line(this.Center, pt);
let pts = l.IntersectWith(this, IntersectOption.ExtendBoth); let pts = l.IntersectWith(this, IntersectOption.ExtendBoth);
let ptIns = pt.distanceTo(pts[0]) < pt.distanceTo(pts[1]) ? pts[0] : pts[1]; let ptIns = pt.distanceTo(pts[0]) < pt.distanceTo(pts[1]) ? pts[0] : pts[1];

@ -1,7 +1,7 @@
import { Mesh, Object3D, Vector3 } from 'three'; import { Mesh, Object3D, Vector3 } from 'three';
import { arrayRemoveDuplicateBySort, arraySortByNumber } from '../Common/ArrayExt'; import { arrayRemoveDuplicateBySort, arraySortByNumber } from '../Common/ArrayExt';
import { ColorMaterial } from '../Common/ColorPalette'; import { ColorMaterial } from '../Common/ColorPalette';
import { equal, equaln } from '../Geometry/GeUtils'; import { equalv3, equaln } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum'; import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectOption } from '../GraphicsSystem/IntersectWith'; import { IntersectOption } from '../GraphicsSystem/IntersectWith';
import { Factory } from './CADFactory'; import { Factory } from './CADFactory';
@ -121,7 +121,7 @@ export abstract class Curve extends Entity
//点在曲线上 //点在曲线上
PtOnCurve(pt: Vector3): boolean PtOnCurve(pt: Vector3): boolean
{ {
return equal(this.StartPoint, pt, 1e-12) || equal(this.EndPoint, pt, 1e-12) || this.ParamOnCurve(this.GetParamAtPoint(pt)); return equalv3(this.StartPoint, pt, 1e-12) || equalv3(this.EndPoint, pt, 1e-12) || this.ParamOnCurve(this.GetParamAtPoint(pt));
} }
//参数在曲线上 容差,1e-12 //参数在曲线上 容差,1e-12

@ -2,7 +2,7 @@ import * as THREE from 'three';
import { Box3, Geometry, Object3D, Vector3 } from 'three'; import { Box3, Geometry, Object3D, Vector3 } from 'three';
import { arraySortByNumber } from '../Common/ArrayExt'; import { arraySortByNumber } from '../Common/ArrayExt';
import { ColorMaterial } from '../Common/ColorPalette'; import { ColorMaterial } from '../Common/ColorPalette';
import { MoveMatrix, equal, isParallelTo, polar, equaln } from '../Geometry/GeUtils'; import { equalv3, isParallelTo, MoveMatrix, polar } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum'; import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectLineAndArc, IntersectLineAndCircle, IntersectLineAndLine, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../GraphicsSystem/IntersectWith'; import { IntersectLineAndArc, IntersectLineAndCircle, IntersectLineAndLine, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../GraphicsSystem/IntersectWith';
import { Arc } from './Arc'; import { Arc } from './Arc';
@ -114,28 +114,10 @@ export class Line extends Curve
} }
GetParamAtPoint(pt: Vector3): number GetParamAtPoint(pt: Vector3): number
{ {
let len = this.Length; let { closestPt, param } = this.GetClosestAtPoint(pt, true);
if (len == 0) if (!equalv3(closestPt, pt))
{
if (equal(this.m_StartPoint, pt))
return 0;
else
return NaN;
}
//得到一阶导数
let v = this.GetFistDeriv(0);
let pV = pt.clone().sub(this.StartPoint);//得到指向p点的向量.
v.multiplyScalar(pV.length() / len);
if (equal(v, pV))
{
return pV.length() / len;
}
else if (equal(v.negate(), pV))
{
return -pV.length() / len;
}
return NaN; return NaN;
return param;
} }
GetParamAtDist(d: number): number GetParamAtDist(d: number): number
{ {
@ -171,20 +153,56 @@ export class Line extends Curve
return ret; return ret;
} }
GetClosestAtPoint(pt: Vector3, extend: boolean): { closestPt: Vector3, param: number }
{
let sp = this.StartPoint;
let ep = this.EndPoint;
if (equalv3(pt, sp, 1e-12))
return { closestPt: sp, param: 0 };
else if (equalv3(pt, ep, 1e-12))
return { closestPt: ep, param: 1 };
let direction = this.GetFistDeriv(0);
let length = direction.length();
if (length === 0)
{
let param = NaN;
if (equalv3(pt, this.StartPoint, 1e-7))
param = 0;
return { closestPt: sp, param: param };
}
direction.divideScalar(length);
let diff = pt.clone().sub(sp);
let param = direction.dot(diff);
let closestPt: Vector3;
if (extend)
closestPt = sp.add(direction.multiplyScalar(param))
else
if (param < 0)
{
closestPt = sp;
param = 0;
}
else if (param > length)
{
closestPt = this.EndPoint;
param = 1;
}
else
closestPt = sp.add(direction.multiplyScalar(param))
return {
closestPt: closestPt,
param: param / length
}
}
GetClosestPointTo(pt: Vector3, extend: boolean): Vector3 GetClosestPointTo(pt: Vector3, extend: boolean): Vector3
{ {
let an = this.GetFistDerivAngle(0) + Math.PI * 0.5; return this.GetClosestAtPoint(pt, extend).closestPt;
let line = new Line(pt, polar(pt.clone(), an, 1) as Vector3);
//交点
let pt_int = this.IntersectWith(line, IntersectOption.ExtendBoth)[0];
if (!pt_int) return this.StartPoint;
if (extend) return pt_int;
//参数
let param = this.GetParamAtPoint(pt_int);
if (param >= 0 && param <= 1) return pt_int;
if (param < 0) return this.StartPoint;
if (param > 0) return this.EndPoint;
return this.StartPoint;
} }
Extend(newParam: number) Extend(newParam: number)

@ -1,5 +1,5 @@
import { Vector2, Vector3 } from 'three'; import { Vector2, Vector3 } from 'three';
import { angle, equaln, equal } from '../Geometry/GeUtils'; import { angle, equaln, equalv3 } from '../Geometry/GeUtils';
import { IntersectOption } from '../GraphicsSystem/IntersectWith'; import { IntersectOption } from '../GraphicsSystem/IntersectWith';
import { Arc } from './Arc'; import { Arc } from './Arc';
import { Line } from './Line'; import { Line } from './Line';
@ -144,7 +144,7 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean
for (let pti of arc.IntersectWith(insLine, IntersectOption.ExtendArg)) for (let pti of arc.IntersectWith(insLine, IntersectOption.ExtendArg))
{ {
if (pti.y < pt.y || equal(sp, pti) || equal(ep, pti)) if (pti.y < pt.y || equalv3(sp, pti) || equalv3(ep, pti))
continue; continue;
let der = arc.GetFistDeriv(pti); let der = arc.GetFistDeriv(pti);

@ -6,7 +6,7 @@ import { ColorMaterial } from '../Common/ColorPalette';
import { getDeterminantFor2V, Vec2DTo3D, Vec3DTo2D } from '../Common/CurveUtils'; import { getDeterminantFor2V, Vec2DTo3D, Vec3DTo2D } from '../Common/CurveUtils';
import { matrixAlignCoordSys } from '../Common/Matrix4Utils'; import { matrixAlignCoordSys } from '../Common/Matrix4Utils';
import { FixIndex } from '../Common/Utils'; import { FixIndex } from '../Common/Utils';
import { equal, equaln, updateGeometry } from '../Geometry/GeUtils'; import { equalv3, equaln, updateGeometry } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum'; import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectOption, IntersectPolylineAndCurve } from '../GraphicsSystem/IntersectWith'; import { IntersectOption, IntersectPolylineAndCurve } from '../GraphicsSystem/IntersectWith';
import { PolyOffsetUtil } from '../GraphicsSystem/OffsetPolyline'; import { PolyOffsetUtil } from '../GraphicsSystem/OffsetPolyline';
@ -243,7 +243,7 @@ export class Polyline extends Curve
//曲线是否闭合 //曲线是否闭合
get IsClose(): boolean get IsClose(): boolean
{ {
return this.CloseMark || (equal(this.StartPoint, this.EndPoint, 1e-5)) && this.EndParam > 1; return this.CloseMark || (equalv3(this.StartPoint, this.EndPoint, 1e-4)) && this.EndParam > 1;
} }
set CloseMark(v: boolean) set CloseMark(v: boolean)
{ {
@ -540,7 +540,7 @@ export class Polyline extends Curve
this.Update(); this.Update();
} }
Join(cu: Curve): boolean Join(cu: Curve, fuzz = 1e-5): boolean
{ {
if (this.m_ClosedMark) if (this.m_ClosedMark)
return false; return false;
@ -575,19 +575,19 @@ export class Polyline extends Curve
{ {
if (cu instanceof Line) if (cu instanceof Line)
{ {
if (equal(cuSp, sp)) if (equalv3(cuSp, sp, fuzz))
{ {
this.m_LineData.unshift({ pt: cuEp2, bul: 0 }); this.m_LineData.unshift({ pt: cuEp2, bul: 0 });
} }
else if (equal(cuSp, ep)) else if (equalv3(cuSp, ep, fuzz))
{ {
this.m_LineData.push({ pt: cuEp2, bul: 0 }); this.m_LineData.push({ pt: cuEp2, bul: 0 });
} }
else if (equal(cuEp, sp)) else if (equalv3(cuEp, sp, fuzz))
{ {
this.m_LineData.unshift({ pt: cuSp2, bul: 0 }); this.m_LineData.unshift({ pt: cuSp2, bul: 0 });
} }
else if (equal(cuEp, ep)) else if (equalv3(cuEp, ep, fuzz))
{ {
this.m_LineData.push({ pt: cuSp2, bul: 0 }); this.m_LineData.push({ pt: cuSp2, bul: 0 });
} }
@ -597,20 +597,20 @@ export class Polyline extends Curve
else if (cu instanceof Arc) else if (cu instanceof Arc)
{ {
let bul = Math.tan(cu.AllAngle * 0.25) * (cu.IsClockWise ? -1 : 1); let bul = Math.tan(cu.AllAngle * 0.25) * (cu.IsClockWise ? -1 : 1);
if (equal(cuSp, sp)) if (equalv3(cuSp, sp, fuzz))
{ {
this.m_LineData.unshift({ pt: cuEp2, bul: -bul }); this.m_LineData.unshift({ pt: cuEp2, bul: -bul });
} }
else if (equal(cuSp, ep)) else if (equalv3(cuSp, ep, fuzz))
{ {
arrayLast(this.m_LineData).bul = bul; arrayLast(this.m_LineData).bul = bul;
this.m_LineData.push({ pt: cuEp2, bul: 0 }); this.m_LineData.push({ pt: cuEp2, bul: 0 });
} }
else if (equal(cuEp, sp)) else if (equalv3(cuEp, sp, fuzz))
{ {
this.m_LineData.unshift({ pt: cuSp2, bul: bul }); this.m_LineData.unshift({ pt: cuSp2, bul: bul });
} }
else if (equal(cuEp, ep)) else if (equalv3(cuEp, ep, fuzz))
{ {
arrayLast(this.m_LineData).bul = -bul; arrayLast(this.m_LineData).bul = -bul;
this.m_LineData.push({ pt: cuSp2, bul: 0 }); this.m_LineData.push({ pt: cuSp2, bul: 0 });
@ -633,7 +633,7 @@ export class Polyline extends Curve
p.copy(Vec3DTo2D(Vec2DTo3D(p).applyMatrix4(alMat))); p.copy(Vec3DTo2D(Vec2DTo3D(p).applyMatrix4(alMat)));
} }
if (equal(cuSp, sp)) if (equalv3(cuSp, sp))
{ {
cu.Reverse(); cu.Reverse();
cuPtsBul.pts.pop(); cuPtsBul.pts.pop();
@ -641,7 +641,7 @@ export class Polyline extends Curve
pts = cuPtsBul.pts.concat(pts); pts = cuPtsBul.pts.concat(pts);
buls = cuPtsBul.buls.concat(buls); buls = cuPtsBul.buls.concat(buls);
} }
else if (equal(cuSp, ep)) else if (equalv3(cuSp, ep))
{ {
pts.pop(); pts.pop();
buls.pop(); buls.pop();
@ -649,14 +649,14 @@ export class Polyline extends Curve
pts = pts.concat(cuPtsBul.pts); pts = pts.concat(cuPtsBul.pts);
buls = buls.concat(cuPtsBul.buls); buls = buls.concat(cuPtsBul.buls);
} }
else if (equal(cuEp, sp)) else if (equalv3(cuEp, sp))
{ {
cuPtsBul.pts.pop(); cuPtsBul.pts.pop();
cuPtsBul.buls.pop(); cuPtsBul.buls.pop();
pts = cuPtsBul.pts.concat(pts); pts = cuPtsBul.pts.concat(pts);
buls = cuPtsBul.buls.concat(buls); buls = cuPtsBul.buls.concat(buls);
} }
else if (equal(cuEp, ep)) else if (equalv3(cuEp, ep))
{ {
pts.pop(); pts.pop();
buls.pop(); buls.pop();
@ -705,9 +705,9 @@ export class Polyline extends Curve
if (this.m_ClosedMark) extType = ExtendType.None; if (this.m_ClosedMark) extType = ExtendType.None;
//最近点 //最近点
let ptC = this.StartPoint; let ptC = undefined;
//最近点的距离\ //最近点的距离
let ptCDist = ptC.distanceToSquared(pt); let ptCDist = Infinity;
for (let i = 0; i < this.EndParam; i++) for (let i = 0; i < this.EndParam; i++)
{ {

@ -26,10 +26,15 @@ export function equaln(v1: number, v2: number, fuzz = 1e-5)
{ {
return Math.abs(v1 - v2) < fuzz; return Math.abs(v1 - v2) < fuzz;
} }
export function equal<T extends Vector>(v1: T, v2: T, fuzzSq = 1e-8) export function equalv3(v1: Vector3, v2: Vector3, fuzz = 1e-8)
{ {
return v1.distanceToSquared(v2) < fuzzSq; return equaln(v1.x, v2.x, fuzz) && equaln(v1.y, v2.y, fuzz) && equaln(v1.z, v2.z, fuzz);
} }
export function equalv2(v1: Vector2, v2: Vector2, fuzz = 1e-8)
{
return equaln(v1.x, v2.x, fuzz) && equaln(v1.y, v2.y, fuzz);
}
export function less(v1, v2, fuzz = 0) export function less(v1, v2, fuzz = 0)
{ {
return v1 - v2 < fuzz; return v1 - v2 < fuzz;

@ -3,7 +3,7 @@ import { Arc } from '../DatabaseServices/Arc';
import { Curve } from '../DatabaseServices/Curve'; import { Curve } from '../DatabaseServices/Curve';
import { Count } from './Count'; import { Count } from './Count';
import { CurveMap } from './CurveMap'; import { CurveMap } from './CurveMap';
import { angle, equal } from './GeUtils'; import { angle, equalv3 } from './GeUtils';
//路线 //路线
export interface Route export interface Route
@ -195,12 +195,12 @@ export class RegionParse
s.routes.sort((r1, r2) => s.routes.sort((r1, r2) =>
{ {
let a1: number, a2: number; let a1: number, a2: number;
if (equal(r1.curve.StartPoint, s.position)) if (equalv3(r1.curve.StartPoint, s.position))
a1 = angle(r1.curve.GetFistDeriv(0)); a1 = angle(r1.curve.GetFistDeriv(0));
else else
a1 = angle(r1.curve.GetFistDeriv(r1.curve.EndParam).negate()); a1 = angle(r1.curve.GetFistDeriv(r1.curve.EndParam).negate());
if (equal(r2.curve.StartPoint, s.position)) if (equalv3(r2.curve.StartPoint, s.position))
a2 = angle(r2.curve.GetFistDeriv(0)); a2 = angle(r2.curve.GetFistDeriv(0));
else else
a2 = angle(r2.curve.GetFistDeriv(r1.curve.EndParam).negate()); a2 = angle(r2.curve.GetFistDeriv(r1.curve.EndParam).negate());

@ -6,7 +6,7 @@ import { Circle } from '../DatabaseServices/Circle';
import { Curve } from '../DatabaseServices/Curve'; import { Curve } from '../DatabaseServices/Curve';
import { Line } from '../DatabaseServices/Line'; import { Line } from '../DatabaseServices/Line';
import { Polyline } from '../DatabaseServices/Polyline'; import { Polyline } from '../DatabaseServices/Polyline';
import { comparePoint, equal, equaln, midPoint } from '../Geometry/GeUtils'; import { comparePoint, equalv3, equaln, midPoint } from '../Geometry/GeUtils';
/** /**
@ -106,7 +106,7 @@ export function IntersectCircleAndCircle(cu1: Circle | Arc, cu2: Circle | Arc)
p2.applyMatrix4(c1Ocs); p2.applyMatrix4(c1Ocs);
pts.push(p1); pts.push(p1);
if (!equal(p1, p2))//防止点重复 if (!equalv3(p1, p2))//防止点重复
pts.push(p2); pts.push(p2);
return pts; return pts;
@ -235,7 +235,7 @@ export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: V
let v2 = p4.clone().sub(p3).normalize(); let v2 = p4.clone().sub(p3).normalize();
let w = p3.clone().sub(p1).normalize(); let w = p3.clone().sub(p1).normalize();
if (equaln(Math.abs(v1.dot(v2)), 1, 1e-6) && (equal(w, new Vector3()) || equaln(Math.abs(v1.dot(w)), 1, 1e-6))) //平行共线 if (equaln(Math.abs(v1.dot(v2)), 1, 1e-6) && (equalv3(w, new Vector3()) || equaln(Math.abs(v1.dot(w)), 1, 1e-6))) //平行共线
{ {
let pts = [p1, p2, p3, p4]; let pts = [p1, p2, p3, p4];
pts.sort(comparePoint('xyz')); pts.sort(comparePoint('xyz'));
@ -286,7 +286,7 @@ export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4:
{ {
let tmpPts = [p1, p2, p3, p4]; let tmpPts = [p1, p2, p3, p4];
tmpPts.sort(comparePoint('xyz')); tmpPts.sort(comparePoint('xyz'));
if (equal(tmpPts[1], p3) || equal(tmpPts[1], p4)) if (equalv3(tmpPts[1], p3) || equalv3(tmpPts[1], p4))
{ {
pts = [tmpPts[1], tmpPts[2]]; pts = [tmpPts[1], tmpPts[2]];
} }
@ -358,7 +358,7 @@ export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: Inte
if ((cu instanceof Polyline && cu.CloseMark) || !(isStart2 || isEnd2)) if ((cu instanceof Polyline && cu.CloseMark) || !(isStart2 || isEnd2))
ext = ext & ~IntersectOption.ExtendArg; ext = ext & ~IntersectOption.ExtendArg;
let ipts = cu1.IntersectWith(cu2, ext).filter(p1 => pts.every(p2 => !equal(p1, p2))); let ipts = cu1.IntersectWith(cu2, ext).filter(p1 => pts.every(p2 => !equalv3(p1, p2)));
//校验延伸 //校验延伸
if (IntersectOption.ExtendThis & ext) if (IntersectOption.ExtendThis & ext)
@ -396,6 +396,6 @@ export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: Inte
} }
} }
pts.sort(comparePoint("xyz")); pts.sort(comparePoint("xyz"));
arrayRemoveDuplicateBySort(pts, equal); arrayRemoveDuplicateBySort(pts, equalv3);
return pts; return pts;
} }

@ -2,7 +2,7 @@ import { Vector3 } from "three";
import { Curve } from "../DatabaseServices/Curve"; import { Curve } from "../DatabaseServices/Curve";
import { CurveIntersection } from "../Geometry/CurveIntersection"; import { CurveIntersection } from "../Geometry/CurveIntersection";
import { CurveMap } from "../Geometry/CurveMap"; import { CurveMap } from "../Geometry/CurveMap";
import { equal, equaln } from "../Geometry/GeUtils"; import { equalv3, equaln } from "../Geometry/GeUtils";
import { Stand } from "../Geometry/RegionParse"; import { Stand } from "../Geometry/RegionParse";
export class LinkSelf export class LinkSelf
@ -95,7 +95,7 @@ export class LinkSelf
let ways: Stand[] = []; let ways: Stand[] = [];
ways.push(cuMap.GetStand(cu.StartPoint)); ways.push(cuMap.GetStand(cu.StartPoint));
if (equal(route.curve.EndPoint, stand.position)) if (equalv3(route.curve.EndPoint, stand.position))
continue; //如果方向相反,那么退出计算 (不符合) continue; //如果方向相反,那么退出计算 (不符合)
let routeIndex = this.GetCurveIndex(route.curve); let routeIndex = this.GetCurveIndex(route.curve);
@ -167,7 +167,7 @@ export class LinkSelf
if (this.GetCurveUse(cu2)) continue; if (this.GetCurveUse(cu2)) continue;
//能够连接 //能够连接
let isLink = isInv ? equal(cu2.EndPoint, originCu.StartPoint) : equal(cu2.StartPoint, originCu.EndPoint); let isLink = isInv ? equalv3(cu2.EndPoint, originCu.StartPoint) : equalv3(cu2.StartPoint, originCu.EndPoint);
if (isLink) if (isLink)
{ {
this.SetCurveUse(cu2); this.SetCurveUse(cu2);
@ -196,7 +196,7 @@ export class LinkSelf
let cu = nowStand.routes[j].curve; let cu = nowStand.routes[j].curve;
let cuIndex = this.GetCurveIndex(cu); let cuIndex = this.GetCurveIndex(cu);
if (this.GetCurveUse(cu)) continue; if (this.GetCurveUse(cu)) continue;
if (!equal(cu.StartPoint, nowStand.position)) continue; if (!equalv3(cu.StartPoint, nowStand.position)) continue;
if (nowIndex === cuIndex) if (nowIndex === cuIndex)
{ {
let routes2 = routes.concat();//复制数组保证函数有唯一结果 let routes2 = routes.concat();//复制数组保证函数有唯一结果
@ -242,7 +242,7 @@ export class LinkSelf
{ {
for (let route of nowStand.routes) for (let route of nowStand.routes)
{ {
if (equal(route.curve.EndPoint, nowStand.position)) if (equalv3(route.curve.EndPoint, nowStand.position))
continue; //如果方向相反,那么退出计算 (不符合) continue; //如果方向相反,那么退出计算 (不符合)
if (this.GetCurveUse(route.curve)) continue; if (this.GetCurveUse(route.curve)) continue;

@ -8,7 +8,7 @@ import { Contour } from '../DatabaseServices/Contour';
import { Curve } from "../DatabaseServices/Curve"; import { Curve } from "../DatabaseServices/Curve";
import { Line } from "../DatabaseServices/Line"; import { Line } from "../DatabaseServices/Line";
import { Polyline } from '../DatabaseServices/Polyline'; import { Polyline } from '../DatabaseServices/Polyline';
import { equal, equaln } from "../Geometry/GeUtils"; import { equaln, equalv2, equalv3 } from "../Geometry/GeUtils";
import { EBox, SortEntityByBox } from "../Geometry/SortEntityByBox"; import { EBox, SortEntityByBox } from "../Geometry/SortEntityByBox";
import { IsPtsAllOutOrOnReg } from "./BoolOperateUtils"; import { IsPtsAllOutOrOnReg } from "./BoolOperateUtils";
import { IntersectOption } from "./IntersectWith"; import { IntersectOption } from "./IntersectWith";
@ -75,7 +75,6 @@ export class PolyOffsetUtil
// 如果源线段闭合只保留闭合的部分 // 如果源线段闭合只保留闭合的部分
if (this.m_Polyline.IsClose) if (this.m_Polyline.IsClose)
return this.m_RetCurves.filter(c => c.IsClose); return this.m_RetCurves.filter(c => c.IsClose);
return this.m_RetCurves; return this.m_RetCurves;
} }
private CheckPointDir(pt: Vector3) private CheckPointDir(pt: Vector3)
@ -141,7 +140,7 @@ export class PolyOffsetUtil
let c2EndPt = c2.EndPoint; let c2EndPt = c2.EndPoint;
//同心圆弧 //同心圆弧
let equalArc = c1 instanceof Arc && c2 instanceof Arc && equal(c1.Center, c2.Center); let equalArc = c1 instanceof Arc && c2 instanceof Arc && equalv3(c1.Center, c2.Center);
//被包含的直线删掉 //被包含的直线删掉
if ((c1 instanceof Line && c2 instanceof Line) || equalArc) if ((c1 instanceof Line && c2 instanceof Line) || equalArc)
@ -163,7 +162,7 @@ export class PolyOffsetUtil
} }
//如果线段端点相连,跳过 //如果线段端点相连,跳过
let isLink = [c1StartPt, c1EndPt].some(p => equal(p, c2StartPt) || equal(p, c2EndPt)); let isLink = [c1StartPt, c1EndPt].some(p => equalv3(p, c2StartPt) || equalv3(p, c2EndPt));
if (isLink) continue; if (isLink) continue;
if (equalArc || c1.IntersectWith(c2, IntersectOption.OnBothOperands).length > 0) if (equalArc || c1.IntersectWith(c2, IntersectOption.OnBothOperands).length > 0)
@ -316,7 +315,7 @@ export class PolyOffsetUtil
//#region 1.中间丢失线段的情况下且循环到尾部,补圆弧. //#region 1.中间丢失线段的情况下且循环到尾部,补圆弧.
let isFillArc = !equal( let isFillArc = !equalv2(
this.m_Polyline.GetPoint2dAt(FixIndex(startIndex + 1, this.m_PtCount)), this.m_Polyline.GetPoint2dAt(FixIndex(startIndex + 1, this.m_PtCount)),
this.m_Polyline.GetPoint2dAt(endIndex) this.m_Polyline.GetPoint2dAt(endIndex)
); );
@ -343,7 +342,7 @@ export class PolyOffsetUtil
let iPts: Vector3[]; //延伸交点 let iPts: Vector3[]; //延伸交点
let tPts: Vector3[]; //都在两条线上的为真交点 let tPts: Vector3[]; //都在两条线上的为真交点
if (equal(frontLine.EndPoint, laterLine.StartPoint)) if (equalv3(frontLine.EndPoint, laterLine.StartPoint))
tPts = [frontLine.EndPoint]; tPts = [frontLine.EndPoint];
else else
{ {
@ -593,9 +592,9 @@ export class PolyOffsetUtil
let lastCu = arrayLast(this.m_RetCurves); let lastCu = arrayLast(this.m_RetCurves);
//让圆弧保持和最后一段首尾相连 //让圆弧保持和最后一段首尾相连
if (!equal(arc1.StartPoint, lastCu.EndPoint)) if (!equalv3(arc1.StartPoint, lastCu.EndPoint))
arc1.Reverse(); arc1.Reverse();
if (!equal(arc2.StartPoint, lastCu.EndPoint)) if (!equalv3(arc2.StartPoint, lastCu.EndPoint))
arc2.Reverse(); arc2.Reverse();
//优先选择和源线段不想交的圆弧,如果都相交或者都不相交,选择和最后一段切线接近的圆弧 //优先选择和源线段不想交的圆弧,如果都相交或者都不相交,选择和最后一段切线接近的圆弧
@ -697,9 +696,7 @@ export class PolyOffsetUtil
{ {
let pl = new Polyline(); let pl = new Polyline();
for (let cu of g) for (let cu of g)
{
pl.Join(cu); pl.Join(cu);
}
resultPls.push(pl) resultPls.push(pl)
} }
return resultPls; return resultPls;

Loading…
Cancel
Save