|
|
|
@ -1,6 +1,6 @@
|
|
|
|
|
import { Box3, Vector3 } from "three";
|
|
|
|
|
import { arrayLast, arrayRemoveIf, arraySortByNumber } from "../Common/ArrayExt";
|
|
|
|
|
import { curveLinkGroup } from "../Common/CurveUtils";
|
|
|
|
|
import { curveLinkGroup, cuOffestDir } from "../Common/CurveUtils";
|
|
|
|
|
import { FixIndex } from "../Common/Utils";
|
|
|
|
|
import { Arc } from "../DatabaseServices/Arc";
|
|
|
|
|
import { Circle } from "../DatabaseServices/Circle";
|
|
|
|
@ -84,21 +84,7 @@ export class PolyOffestUtil
|
|
|
|
|
}
|
|
|
|
|
private CheckPoint1(pt: Vector3)
|
|
|
|
|
{
|
|
|
|
|
let ptClose = this.m_Polyline.GetClosestPointTo(pt, false);
|
|
|
|
|
let toPtVec = pt.clone().sub(ptClose); //点击处向量
|
|
|
|
|
let d = this.m_Polyline.GetFistDeriv(ptClose);//切线。
|
|
|
|
|
let dir = Math.sign(toPtVec.clone().cross(d).z);
|
|
|
|
|
|
|
|
|
|
let par = this.m_Polyline.GetParamAtPoint(ptClose);
|
|
|
|
|
if (par === Math.floor(par) && par)
|
|
|
|
|
{
|
|
|
|
|
let fd = this.m_Polyline.GetFistDeriv(par - 0.1);
|
|
|
|
|
let fc = toPtVec.cross(fd);
|
|
|
|
|
let tmpDir = Math.sign(fd.clone().cross(d).z);
|
|
|
|
|
if (dir * fc.z < 0)
|
|
|
|
|
dir = tmpDir;
|
|
|
|
|
}
|
|
|
|
|
console.log(dir, Math.sign(this.m_OffestDist), this.offDir);
|
|
|
|
|
let dir = cuOffestDir(this.m_Polyline, pt)
|
|
|
|
|
return dir === this.offDir;
|
|
|
|
|
}
|
|
|
|
|
private optimizeCus(boxCurves: Map<EBox, Box3>, outputCus: Curve[])
|
|
|
|
@ -109,9 +95,9 @@ export class PolyOffestUtil
|
|
|
|
|
//与源线段自交
|
|
|
|
|
if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0)
|
|
|
|
|
return false;
|
|
|
|
|
// return this.CheckPoint1(c.StartPoint);
|
|
|
|
|
return this.CheckPoint1(c.StartPoint);
|
|
|
|
|
//起点终点离源线段的距离必须大于偏移距离
|
|
|
|
|
return this.CheckPoint(c.StartPoint) && this.CheckPoint(c.EndPoint);
|
|
|
|
|
// return this.CheckPoint(c.StartPoint) && this.CheckPoint(c.EndPoint);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//处理在偏移反方向的曲线
|
|
|
|
@ -489,32 +475,34 @@ export class PolyOffestUtil
|
|
|
|
|
|
|
|
|
|
if (splitCus.length === 2) //2圆相交应该有2段,否则相切
|
|
|
|
|
{
|
|
|
|
|
let arc1 = splitCus[0];
|
|
|
|
|
let arc2 = splitCus[1];
|
|
|
|
|
let tmpPts = cir.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands);
|
|
|
|
|
let onCu0Pts = tmpPts.filter(p => splitCus[0].PtOnCurve(p));
|
|
|
|
|
let onCu1Pts = tmpPts.filter(p => splitCus[1].PtOnCurve(p));
|
|
|
|
|
//选择和源线段不相交的那段圆弧
|
|
|
|
|
let onCu0Pts = tmpPts.filter(p => arc1.PtOnCurve(p));
|
|
|
|
|
let onCu1Pts = tmpPts.filter(p => arc2.PtOnCurve(p));
|
|
|
|
|
let lastCu = arrayLast(this.m_RetCurves);
|
|
|
|
|
|
|
|
|
|
if (!equal(arc1.StartPoint, lastCu.EndPoint))
|
|
|
|
|
arc1.Reverse();
|
|
|
|
|
if (!equal(arc2.StartPoint, lastCu.EndPoint))
|
|
|
|
|
arc2.Reverse();
|
|
|
|
|
//优先选择和源线段不想交的圆弧,如果都相交或者都不相交,选择和最后一段切线接近的圆弧
|
|
|
|
|
let cu: Arc;
|
|
|
|
|
if (onCu0Pts.length === 0)
|
|
|
|
|
{
|
|
|
|
|
cu = splitCus[0];
|
|
|
|
|
}
|
|
|
|
|
else if (onCu1Pts.length === 0)
|
|
|
|
|
if (onCu0Pts.length === onCu1Pts.length)
|
|
|
|
|
{
|
|
|
|
|
cu = splitCus[1]
|
|
|
|
|
let derv = lastCu.GetFistDeriv(1);
|
|
|
|
|
let derv1 = arc1.GetFistDeriv(0);
|
|
|
|
|
let derv2 = arc2.GetFistDeriv(0);
|
|
|
|
|
cu = derv.angleTo(derv1) < derv.angleTo(derv2) ? arc1 : arc2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//TODO:先用第一段
|
|
|
|
|
cu = splitCus[0];
|
|
|
|
|
cu = onCu0Pts.length < onCu1Pts.length ? arc1 : arc2;
|
|
|
|
|
}
|
|
|
|
|
//防止加入0长度圆弧
|
|
|
|
|
if (equaln(cu.Length, 0, 1e-6))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
let lastCu = arrayLast(this.m_RetCurves);
|
|
|
|
|
//如果不是首尾相连,就反转后在存入数组
|
|
|
|
|
if (!equal(cu.StartPoint, lastCu.EndPoint))
|
|
|
|
|
cu.Reverse();
|
|
|
|
|
this.m_RetCurves.push(cu);
|
|
|
|
|
this.m_Contours.push(this.BuildContour(cu));
|
|
|
|
|
}
|
|
|
|
|