|
|
|
@ -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 平行x或y的容差
|
|
|
|
|
* @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;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|