!2774 优化:封闭多段线分割成矩形,使用轮廓切割api

other_split_method
林三 4 months ago committed by ChenX
parent b09df3ffd9
commit 2143b16b93

@ -91,7 +91,18 @@ describe("封闭多段线分割矩形测试", () =>
expect(c.Area).toMatchSnapshot();
});
test("轮廓7", () =>
{
let data = { "file": [1, "Polyline", 10, 2, 102, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 8, [163.99999999999997, 0], 0, [182, 0], 0, [181.99999999999997, 132], 0, [169.00000000000003, 132], 0, [169.00000000000003, 332], 0, [182, 332], 0, [182.00000000000009, 464], 0, [164, 464], 0, true], "basePt": { "x": 163.99999999999997, "y": 0, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadCurvesFromFileData(data) as Polyline[];
let cons = PolylineSpliteRect(pl[0]);
expect(cons.length).toBe(3);
for (let c of cons)
expect(c.Area).toMatchSnapshot();
});
test('交点参数为负数?', () =>
{
let d =

@ -8,38 +8,44 @@ exports[`封闭多段线分割矩形测试 轮廓1 2`] = `595357.6812453549`;
exports[`封闭多段线分割矩形测试 轮廓1 3`] = `251503.5221472336`;
exports[`封闭多段线分割矩形测试 轮廓2 1`] = `1855875.3072621506`;
exports[`封闭多段线分割矩形测试 轮廓2 1`] = `1855875.3072621487`;
exports[`封闭多段线分割矩形测试 轮廓2 2`] = `868579.4324262962`;
exports[`封闭多段线分割矩形测试 轮廓2 2`] = `857299.1800571308`;
exports[`封闭多段线分割矩形测试 轮廓2 3`] = `2003832.7922209054`;
exports[`封闭多段线分割矩形测试 轮廓2 3`] = `429306.6921083182`;
exports[`封闭多段线分割矩形测试 轮廓2 4`] = `1150366.7076290324`;
exports[`封闭多段线分割矩形测试 轮廓2 4`] = `2003832.7922209073`;
exports[`封闭多段线分割矩形测试 轮廓2 5`] = `857299.1800571308`;
exports[`封闭多段线分割矩形测试 轮廓2 5`] = `1963968.5993822813`;
exports[`封闭多段线分割矩形测试 轮廓2 6`] = `429306.6921083182`;
exports[`封闭多段线分割矩形测试 轮廓2 6`] = `1150366.7076290324`;
exports[`封闭多段线分割矩形测试 轮廓2 7`] = `1963968.5993822813`;
exports[`封闭多段线分割矩形测试 轮廓2 7`] = `868579.4324262962`;
exports[`封闭多段线分割矩形测试 轮廓3 1`] = `447800.4779338776`;
exports[`封闭多段线分割矩形测试 轮廓3 2`] = `145204.1154134143`;
exports[`封闭多段线分割矩形测试 轮廓3 3`] = `341919.1493761451`;
exports[`封闭多段线分割矩形测试 轮廓3 3`] = `103826.90503283963`;
exports[`封闭多段线分割矩形测试 轮廓3 4`] = `103826.90503283963`;
exports[`封闭多段线分割矩形测试 轮廓3 4`] = `466962.1139759575`;
exports[`封闭多段线分割矩形测试 轮廓3 5`] = `466962.1139759575`;
exports[`封闭多段线分割矩形测试 轮廓3 5`] = `341919.1493761451`;
exports[`封闭多段线分割矩形测试 轮廓4 1`] = `1492707.6629829132`;
exports[`封闭多段线分割矩形测试 轮廓4 1`] = `1492707.6629829137`;
exports[`封闭多段线分割矩形测试 轮廓4 2`] = `603373.0545650794`;
exports[`封闭多段线分割矩形测试 轮廓4 2`] = `603373.0545650786`;
exports[`封闭多段线分割矩形测试 轮廓5 1`] = `10638`;
exports[`封闭多段线分割矩形测试 轮廓5 1`] = `10637.999999999884`;
exports[`封闭多段线分割矩形测试 轮廓5 2`] = `3494.5113962781616`;
exports[`封闭多段线分割矩形测试 轮廓5 2`] = `3494.5113962782198`;
exports[`封闭多段线分割矩形测试 轮廓6 1`] = `5238`;
exports[`封闭多段线分割矩形测试 轮廓6 1`] = `5238.000000000931`;
exports[`封闭多段线分割矩形测试 轮廓6 2`] = `1733.4165836796165`;
exports[`封闭多段线分割矩形测试 轮廓6 2`] = `1733.4165836516768`;
exports[`封闭多段线分割矩形测试 轮廓7 1`] = `2320.0000000000146`;
exports[`封闭多段线分割矩形测试 轮廓7 2`] = `1715.9999999999945`;
exports[`封闭多段线分割矩形测试 轮廓7 3`] = `1716`;

@ -7,13 +7,10 @@ import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
/**
* 线线
*
* @export
* @param {Polyline} meatPl 线
* @param {Polyline[]} knifePls 线
* @return {*}
* @return
*/
export function SplitPolyline(meatPl: Polyline, knifePls: Polyline[]): Polyline[]
{
let allSplitPls: Polyline[] = [];
@ -30,8 +27,6 @@ export function SplitPolyline(meatPl: Polyline, knifePls: Polyline[]): Polyline[
pl.StartPoint = ipts[0];
pl.EndPoint = ipts[1];
}
else
{
ipts.sort(ComparePointFnGenerate("xy"));
@ -39,8 +34,6 @@ export function SplitPolyline(meatPl: Polyline, knifePls: Polyline[]): Polyline[
pl.EndPoint = arrayLast(ipts);
}
}
else
{
let iptsNotExt = ipts.filter(p => pl.PtOnCurve(p));

@ -1,4 +1,5 @@
import { Box2, Box3, Line3, Matrix3, Matrix4, Vec2, Vector2, Vector3 } from 'three';
import { SplitPolyline } from '../Add-on/BoardCutting/SplitPolyline';
import { Arc } from '../DatabaseServices/Entity/Arc';
import { Circle } from '../DatabaseServices/Entity/Circle';
import { Curve } from '../DatabaseServices/Entity/Curve';
@ -9,7 +10,7 @@ import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline';
import { Spline } from '../DatabaseServices/Spline';
import { Count } from '../Geometry/Count';
import { CurveMap, Vertice } from '../Geometry/CurveMap';
import { AsVector2, AsVector3, XAxis, YAxis, ZAxis, ZeroVec, equaln, equalv2, equalv3, isIntersect, isParallelTo } from '../Geometry/GeUtils';
import { AsVector2, AsVector3, XAxis, YAxis, ZAxis, ZeroVec, equaln, equalv2, equalv3, isParallelTo } from '../Geometry/GeUtils';
import { Vec3 } from '../Geometry/IVec3';
import { Matrix2 } from '../Geometry/Matrix2';
import { Orbit } from '../Geometry/Orbit';
@ -790,94 +791,39 @@ export function Pts2Polyline(pts: (Vec3 | Vec2)[], isClose: boolean): Polyline
return pl;
}
const PolylineSpliteRectFuzz = 1e-3;
/**封闭多段线 分割成矩形 */
export function PolylineSpliteRect(outline: Polyline): Polyline[]
/**
* 线,y线,
* @param outline ,
* @param polylineParalleXYFuzz xy
* @returns
*/
export function PolylineSpliteRect(outline: Polyline, polylineParalleXYFuzz = 1e-3): Polyline[]
{
if (!outline.IsClose || IsRect(outline))
return [outline];
let firstDerv = outline.GetFirstDeriv(0).normalize();
if (!isParallelTo(firstDerv, XAxis, PolylineSpliteRectFuzz) && !isParallelTo(firstDerv, YAxis, PolylineSpliteRectFuzz))
return [outline];
let cus = outline.Explode();
let yCus: Curve[] = [];
let xSet: Set<number> = new Set();
for (let c of cus)
{
if (c instanceof Arc) return [outline];
let derv = c.GetFirstDeriv(0).normalize();
if (isParallelTo(derv, YAxis, PolylineSpliteRectFuzz))
yCus.push(c);
else
if (!isParallelTo(derv, XAxis, PolylineSpliteRectFuzz))
{
return [outline];
}
if (isParallelTo(derv, YAxis, polylineParalleXYFuzz))
xSet.add(c.StartPoint.x);
else if (!isParallelTo(derv, XAxis, polylineParalleXYFuzz))
return [outline];
}
yCus.sort((c1, c2) => c1.StartPoint.x - c2.StartPoint.x);
let rects: Polyline[] = [];
let endParam = outline.EndParam;
for (let i = 0; i < yCus.length - 1; i++)
{
let c1 = yCus[i];
let c2 = yCus[i + 1];
let x1 = c1.StartPoint.x;
let x2 = c2.StartPoint.x;
if (equaln(x1, x2))
continue;
let y1: number;
let y2: number;
let res = c1.IntersectWith2(outline, IntersectOption.ExtendThis);
let res2 = c2.IntersectWith2(outline, IntersectOption.ExtendThis);
let pars: number[] = [];
for (let i of res) pars.push(i.argParam);
for (let i of res2) pars.push(i.argParam);
for (let i = 0; i < pars.length; i++)
{
let p = pars[i];
if (p < 0) p = 0;//请参照测试用例
else if (p > endParam) p = endParam;//请参照测试用例
else p = Math.floor(p);
pars[i] = p;
}
pars.sort((a, b) => a - b);
arrayRemoveDuplicateBySort(pars);
//轮廓的每条线段都平行于X或Y轴 可直接按端点切割
const knifePls: Polyline[] = [];
const xList = Array.from(xSet).sort((a, b) => a - b);
let ys: number[] = [];
for (let par of pars)
{
let c = outline.GetCurveAtParam(par);
let derv = c.GetFirstDeriv(0).normalize();
if (isParallelTo(derv, XAxis, PolylineSpliteRectFuzz))
{
let x3 = c.StartPoint.x;
let x4 = c.EndPoint.x;
if (x3 > x4)
[x3, x4] = [x4, x3];
if (isIntersect(x1, x2, x3, x4, -PolylineSpliteRectFuzz))
ys.push(c.StartPoint.y);
}
}
for (let x of xList)
knifePls.push(new Polyline([{ pt: AsVector2({ x, y: 0 }), bul: 0 }, { pt: AsVector2({ x, y: 1 }), bul: 0 }]));
if (ys.length < 2) return [outline];
ys.sort((a, b) => a - b);
y1 = ys[0];
y2 = arrayLast(ys);
rects.push(new Polyline().RectangleFrom2Pt(new Vector3(x1, y1), new Vector3(x2, y2)));
}
//裁剪结果
let rects = SplitPolyline(outline, knifePls).filter(pl => pl.IsClose);
return rects;
}

Loading…
Cancel
Save