|
|
@ -12,7 +12,6 @@ import { equal, equaln } from "../Geometry/GeUtils";
|
|
|
|
import { SortEntityByBox } from "../Geometry/SortEntityByBox";
|
|
|
|
import { SortEntityByBox } from "../Geometry/SortEntityByBox";
|
|
|
|
import { IsPtsAllOutOrOnReg } from "./BoolOperateUtils";
|
|
|
|
import { IsPtsAllOutOrOnReg } from "./BoolOperateUtils";
|
|
|
|
import { IntersectOption } from "./IntersectWith";
|
|
|
|
import { IntersectOption } from "./IntersectWith";
|
|
|
|
import { testCurve } from "../Add-on/testEntity/TestCurve";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface offestRes
|
|
|
|
interface offestRes
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -23,7 +22,6 @@ interface offestRes
|
|
|
|
//FIXME:1.当轮廓自交时,会丢失自交的线段
|
|
|
|
//FIXME:1.当轮廓自交时,会丢失自交的线段
|
|
|
|
//FIXME:2.往内偏移到极限位置,会有多余线段,
|
|
|
|
//FIXME:2.往内偏移到极限位置,会有多余线段,
|
|
|
|
// 与偏移方向问题应该一样,方向若和偏移距离相反,则删除
|
|
|
|
// 与偏移方向问题应该一样,方向若和偏移距离相反,则删除
|
|
|
|
//FIXME:3.线段共线时,有时造成线段不连续
|
|
|
|
|
|
|
|
export class PolyOffestUtil
|
|
|
|
export class PolyOffestUtil
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private m_Polyline: Polyline;
|
|
|
|
private m_Polyline: Polyline;
|
|
|
@ -46,11 +44,6 @@ export class PolyOffestUtil
|
|
|
|
let expCus = this.m_Polyline.Explode();
|
|
|
|
let expCus = this.m_Polyline.Explode();
|
|
|
|
let offres = this.OffestCurve(expCus, this.m_OffestDist);
|
|
|
|
let offres = this.OffestCurve(expCus, this.m_OffestDist);
|
|
|
|
|
|
|
|
|
|
|
|
// this.m_Polyline.PtsBuls.pts.forEach(p =>
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// let cir = new Circle(Vec2DTo3D(p).applyMatrix4(this.m_Polyline.OCS), rad);
|
|
|
|
|
|
|
|
// contours.push(Contour.CreateContour([cir]))
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
//暂只传入首尾点的圆做轮廓
|
|
|
|
//暂只传入首尾点的圆做轮廓
|
|
|
|
if (!this.m_Polyline.IsClose)
|
|
|
|
if (!this.m_Polyline.IsClose)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -65,21 +58,12 @@ export class PolyOffestUtil
|
|
|
|
// testContours(contours);
|
|
|
|
// testContours(contours);
|
|
|
|
|
|
|
|
|
|
|
|
//裁剪
|
|
|
|
//裁剪
|
|
|
|
let cus = this.trimByContours(this.m_RetCurves);
|
|
|
|
let { boxCurves, outputCus } = this.trimByContours(this.m_RetCurves);
|
|
|
|
|
|
|
|
|
|
|
|
//过滤掉无效的线段
|
|
|
|
// 优化裁剪后的曲线
|
|
|
|
cus = cus.filter(c =>
|
|
|
|
outputCus = this.optimizeCus(boxCurves, outputCus);
|
|
|
|
{
|
|
|
|
|
|
|
|
//与源线段自交
|
|
|
|
|
|
|
|
if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//起点终点离源线段的距离必须大于偏移距离
|
|
|
|
return this.linkCurves(outputCus);
|
|
|
|
return this.CheckPoint(c.StartPoint) && this.CheckPoint(c.EndPoint);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
//先打断?
|
|
|
|
|
|
|
|
// return this.linkCurves(cus);
|
|
|
|
|
|
|
|
return cus;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -97,7 +81,63 @@ export class PolyOffestUtil
|
|
|
|
.distanceToSquared(pt);
|
|
|
|
.distanceToSquared(pt);
|
|
|
|
return dis + 1e-2 > this.m_dist2;
|
|
|
|
return dis + 1e-2 > this.m_dist2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private optimizeCus(boxCurves, outputCus)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//过滤掉无效的线段
|
|
|
|
|
|
|
|
outputCus = outputCus.filter(c =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//与源线段自交
|
|
|
|
|
|
|
|
if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//起点终点离源线段的距离必须大于偏移距离
|
|
|
|
|
|
|
|
return this.CheckPoint(c.StartPoint) && this.CheckPoint(c.EndPoint);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//处理自交的线段
|
|
|
|
|
|
|
|
let count = outputCus.length;
|
|
|
|
|
|
|
|
for (let i = 0; i < count; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let c1 = outputCus[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let c1b = boxCurves.get(c1);
|
|
|
|
|
|
|
|
for (let j = i + 1; j < count; j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let c2 = outputCus[j];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//过滤掉不需要计算的曲线
|
|
|
|
|
|
|
|
let c2b = boxCurves.get(c2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (c2b.min.x > c1b.max.x)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (c2b.min.y > c1b.max.y)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//如果线段端点相连,不计算
|
|
|
|
|
|
|
|
let isLink = [c1.StartPoint, c1.EndPoint].some(p => equal(p, c2.StartPoint) || equal(p, c2.EndPoint));
|
|
|
|
|
|
|
|
if (isLink) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let pts = c1.IntersectWith(c2, IntersectOption.OnBothOperands);
|
|
|
|
|
|
|
|
if (pts.length > 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//按照从左到右,从上到下,分别取前后部分
|
|
|
|
|
|
|
|
let c1s = c1.GetSplitCurvesByPts(pts);
|
|
|
|
|
|
|
|
if (c1s.length === 2)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
outputCus[i] = c1s[0];
|
|
|
|
|
|
|
|
boxCurves.set(c1s[0], c1s[0].BoundingBox);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let c2s = c2.GetSplitCurvesByPts(pts);
|
|
|
|
|
|
|
|
if (c2s.length === 2)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
outputCus[j] = c2s[1];
|
|
|
|
|
|
|
|
boxCurves.set(c2s[1], c2s[1].BoundingBox);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return outputCus;
|
|
|
|
|
|
|
|
}
|
|
|
|
//偏移曲线
|
|
|
|
//偏移曲线
|
|
|
|
private OffestCurve(pls: Curve[], dis: number): offestRes[]
|
|
|
|
private OffestCurve(pls: Curve[], dis: number): offestRes[]
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -418,7 +458,7 @@ export class PolyOffestUtil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 通过构建的轮廓对偏移曲线进行裁剪
|
|
|
|
// 通过构建的轮廓对偏移曲线进行裁剪
|
|
|
|
private trimByContours(needCutCus: Curve[]): Curve[]
|
|
|
|
private trimByContours(needCutCus: Curve[])
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let boxContours = SortEntityByBox(this.m_Contours, false);
|
|
|
|
let boxContours = SortEntityByBox(this.m_Contours, false);
|
|
|
|
let boxCurves = SortEntityByBox(needCutCus, true);
|
|
|
|
let boxCurves = SortEntityByBox(needCutCus, true);
|
|
|
@ -472,46 +512,7 @@ export class PolyOffestUtil
|
|
|
|
needCutCus = tmpCus;
|
|
|
|
needCutCus = tmpCus;
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// let count = needCutCus.length
|
|
|
|
return { boxCurves, outputCus: needCutCus };
|
|
|
|
|
|
|
|
|
|
|
|
// for (let i = 0; i < count; i++)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// let c1 = needCutCus[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// let c1b = boxCurves.get(c1);
|
|
|
|
|
|
|
|
// for (let j = i + 1; j < count; j++)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// let c2 = needCutCus[j];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// //过滤掉不需要计算的曲线
|
|
|
|
|
|
|
|
// let c2b = boxCurves.get(c2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (c2b.min.x > c1b.max.x)
|
|
|
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
// if (c2b.min.y > c1b.max.y)
|
|
|
|
|
|
|
|
// continue;
|
|
|
|
|
|
|
|
// let isLink = [c1.StartPoint, c1.EndPoint].some(p => equal(p, c2.StartPoint) || equal(p, c2.EndPoint));
|
|
|
|
|
|
|
|
// if (isLink) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// let pts = c1.IntersectWith(c2, IntersectOption.OnBothOperands);
|
|
|
|
|
|
|
|
// if (pts.length > 0)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// let iPt = this.selectFitInterPt(pts, c1.EndPoint);
|
|
|
|
|
|
|
|
// let cus = c1.GetSplitCurvesByPt(iPt);
|
|
|
|
|
|
|
|
// if (cus.length === 2)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// c1 = cus[0];
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// cus = c2.GetSplitCurvesByPt(iPt);
|
|
|
|
|
|
|
|
// if (cus.length === 2)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// c2 = cus[1];
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return needCutCus;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|