|
|
|
@ -519,9 +519,9 @@ export class Polyline extends Curve
|
|
|
|
|
let newPlList: Array<Polyline> = this.linkPolylineGroup(plList, offsetDist);
|
|
|
|
|
// //分离出自交的线
|
|
|
|
|
let outputPls = this.removeSelfIntersect(newPlList, offsetDist);
|
|
|
|
|
newPlList = this.cuttingPolyLine(newPlList, offsetDist);
|
|
|
|
|
this.linkPLine(newPlList, offsetDist);
|
|
|
|
|
this.cuttingPolyLine(newPlList, offsetDist);
|
|
|
|
|
outputPls.push(...this.arrangePlineList(newPlList));
|
|
|
|
|
|
|
|
|
|
return outputPls;
|
|
|
|
|
}
|
|
|
|
|
//偏移曲线
|
|
|
|
@ -556,7 +556,32 @@ export class Polyline extends Curve
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return this.copyPolyline([startV, endV]);
|
|
|
|
|
let pl = this.copyPolyline([startV, endV]);
|
|
|
|
|
pl.CloseMark = false;
|
|
|
|
|
return pl;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 尝试相邻多段线段收尾相连
|
|
|
|
|
* @private
|
|
|
|
|
* @param {Polyline[]} pls
|
|
|
|
|
* @memberof Polyline
|
|
|
|
|
*/
|
|
|
|
|
private linkPLine(pls: Polyline[], offset: number)
|
|
|
|
|
{
|
|
|
|
|
for (let i = 0; i < pls.length - 1; i++)
|
|
|
|
|
{
|
|
|
|
|
let frontLine = pls[i];
|
|
|
|
|
let laterLine = pls[i + 1];
|
|
|
|
|
let interPts = frontLine.IntersectWith(laterLine, IntersectOption.ExtendBoth);
|
|
|
|
|
if (interPts.length > 0)
|
|
|
|
|
{
|
|
|
|
|
let pt = this.selectPlInterPt(interPts, laterLine.StartPoint);
|
|
|
|
|
//调整前后两条多段线的首尾线
|
|
|
|
|
this.adjustFrontLine(frontLine.LineData[1], pt, frontLine.LineData[0]);
|
|
|
|
|
frontLine.LineData[1].pt = Vec3DTo2D(pt);
|
|
|
|
|
this.adjustLaterLine(laterLine.LineData[1], pt, laterLine.LineData[0]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 删除自交多段线
|
|
|
|
@ -789,7 +814,7 @@ export class Polyline extends Curve
|
|
|
|
|
//整理多段线数组,把相连的组合成多段线,返回多段线数组
|
|
|
|
|
private arrangePlineList(pls: Array<Polyline>)
|
|
|
|
|
{
|
|
|
|
|
if (pls.length === 0) return;
|
|
|
|
|
if (pls.length === 0) return [];
|
|
|
|
|
let plDataList: PolylineProps[] = [];
|
|
|
|
|
let plList: Polyline[] = [];
|
|
|
|
|
plDataList.push(pls[0].LineData[0]);
|
|
|
|
@ -844,6 +869,7 @@ export class Polyline extends Curve
|
|
|
|
|
oldSlope = frontLine.GetFistDeriv(0);
|
|
|
|
|
//后面线
|
|
|
|
|
let laterLine = plList[i + 1];
|
|
|
|
|
|
|
|
|
|
if (i === plList.length - 1)
|
|
|
|
|
{
|
|
|
|
|
if (this.IsClose)
|
|
|
|
@ -860,9 +886,8 @@ export class Polyline extends Curve
|
|
|
|
|
// 多段线交点数组
|
|
|
|
|
let interPts = frontLine.IntersectWith(laterLine, IntersectOption.ExtendBoth);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//如果没有交点,则用圆弧连接
|
|
|
|
|
if (interPts.length === 0 && offsetDist)
|
|
|
|
|
if (interPts.length === 0)
|
|
|
|
|
{
|
|
|
|
|
let centerPt;
|
|
|
|
|
//取圆心,圆心离后面线start点距离等于偏移距离
|
|
|
|
@ -890,34 +915,26 @@ export class Polyline extends Curve
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//半径矢量radLine,求交线段insertLine,半径线段
|
|
|
|
|
let [radLine, insertLine] = startLine.lengthSq() > endLine.lengthSq() ? [startLine, laterLine] : [endLine, frontLine];
|
|
|
|
|
|
|
|
|
|
// 以centerPt为圆心,偏移距离为为半径画圆
|
|
|
|
|
let tmpPlLine = new Circle(centerPt, Math.abs(offsetDist));
|
|
|
|
|
|
|
|
|
|
let pts = tmpPlLine.IntersectWith(insertLine, IntersectOption.OnBothOperands);
|
|
|
|
|
|
|
|
|
|
// //此处为测试代码
|
|
|
|
|
// if (pts.length === 0)
|
|
|
|
|
// {
|
|
|
|
|
// app.m_Database.ModelSpace.Append(insertLine);
|
|
|
|
|
// app.m_Database.ModelSpace.Append(tmpPlLine);
|
|
|
|
|
|
|
|
|
|
// pts.push(centerPt);
|
|
|
|
|
// }
|
|
|
|
|
intPt = pts[0];
|
|
|
|
|
let insLine = intPt.clone().sub(centerPt);
|
|
|
|
|
circleAngle = angleTo(insLine, radLine);
|
|
|
|
|
// 如果前面矢量小于后面的则交点在前面线,调整前面线凸度
|
|
|
|
|
if (startLine.lengthSq() <= endLine.lengthSq())
|
|
|
|
|
let tmpCir = new Circle(centerPt, Math.abs(offsetDist));
|
|
|
|
|
//只会和前面线相交,因为圆心选取是根据后面线startPoint偏移距离处的点,只会与后面线相切,允许前面线延伸
|
|
|
|
|
let pts = tmpCir.IntersectWith(frontLine, IntersectOption.OnBothOperands);
|
|
|
|
|
if (pts.length > 0)
|
|
|
|
|
{
|
|
|
|
|
//选取交点,如果有多个选离前面线start点近的
|
|
|
|
|
intPt = this.selectPlInterPt(pts, frontLine.StartPoint);
|
|
|
|
|
let insLine = intPt.clone().sub(centerPt);
|
|
|
|
|
circleAngle = angleTo(insLine, endLine);
|
|
|
|
|
this.adjustFrontLine(frontLine.LineData[1], intPt, startV);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//补圆弧交点在后面线,调整后面线点和凸度
|
|
|
|
|
this.adjustLaterLine(laterLine.LineData[1], intPt, endV);
|
|
|
|
|
// 与补线圆无交点,放弃补圆弧
|
|
|
|
|
newPlList.push(new Polyline([
|
|
|
|
|
startV, this.clonePlData(frontLine.LineData[1])
|
|
|
|
|
]))
|
|
|
|
|
startV = this.clonePlData(laterLine.LineData[0]);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let tmpPlData = {
|
|
|
|
@ -931,7 +948,6 @@ export class Polyline extends Curve
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//是否存在同时存在2线上的交点
|
|
|
|
|
let pts = frontLine.IntersectWith(laterLine, IntersectOption.OnBothOperands);
|
|
|
|
|
|
|
|
|
|
interPt = pts.length > 0 ? pts[0] : this.selectPlInterPt(interPts, laterLine.StartPoint)
|
|
|
|
@ -960,8 +976,8 @@ export class Polyline extends Curve
|
|
|
|
|
let endV = this.clonePlData(frontLine.LineData[1]);
|
|
|
|
|
if (plList.length >= 3)
|
|
|
|
|
{
|
|
|
|
|
let laterLine = plList[0];
|
|
|
|
|
let pts = frontLine.IntersectWith(laterLine, 0);
|
|
|
|
|
let laterLine = newPlList[0];
|
|
|
|
|
let pts = frontLine.IntersectWith(laterLine, IntersectOption.OnBothOperands);
|
|
|
|
|
if (pts.length === 1)
|
|
|
|
|
{
|
|
|
|
|
this.adjustFrontLine(frontLine.LineData[1], pts[0], startV);
|
|
|
|
@ -972,14 +988,14 @@ export class Polyline extends Curve
|
|
|
|
|
}
|
|
|
|
|
let pl = new Polyline([startV, endV]);
|
|
|
|
|
newSlope = pl.GetFistDeriv(0);
|
|
|
|
|
if (!equaln(newSlope.angleTo(oldSlope), Math.PI, 1e-7))
|
|
|
|
|
if (pl.LineData[0].bul !== 0 || !equaln(newSlope.angleTo(oldSlope), Math.PI, 1e-7))
|
|
|
|
|
newPlList.push(pl);
|
|
|
|
|
}
|
|
|
|
|
return newPlList;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 优化连接多段数组,去除无用线
|
|
|
|
|
* //ToDo:保留优化算法
|
|
|
|
|
* //TODO:暂保留,待优化
|
|
|
|
|
* @private
|
|
|
|
|
* @param {Array<Polyline>} plList
|
|
|
|
|
* @returns
|
|
|
|
@ -1048,7 +1064,15 @@ export class Polyline extends Curve
|
|
|
|
|
}
|
|
|
|
|
return plList.length > 1 ? plList : [];
|
|
|
|
|
}
|
|
|
|
|
//选取合适交点
|
|
|
|
|
/**
|
|
|
|
|
* 选取离spt近的点作为交点
|
|
|
|
|
*
|
|
|
|
|
* @private
|
|
|
|
|
* @param {Vector3[]} pts
|
|
|
|
|
* @param {Vector3} spt
|
|
|
|
|
* @returns
|
|
|
|
|
* @memberof Polyline
|
|
|
|
|
*/
|
|
|
|
|
private selectPlInterPt(pts: Vector3[], spt: Vector3)
|
|
|
|
|
{
|
|
|
|
|
let pt: Vector3;
|
|
|
|
@ -1077,9 +1101,7 @@ export class Polyline extends Curve
|
|
|
|
|
*/
|
|
|
|
|
private cuttingPolyLine(plList: Polyline[], rad: number)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
rad = Math.abs(rad);
|
|
|
|
|
|
|
|
|
|
// 每个原线段点画圆分割多段线
|
|
|
|
|
for (let i = 0; i < this.LineData.length; i++)
|
|
|
|
|
{
|
|
|
|
@ -1092,7 +1114,7 @@ export class Polyline extends Curve
|
|
|
|
|
let sDist = pl.StartPoint.distanceTo(centerPt);
|
|
|
|
|
let eDist = pl.EndPoint.distanceTo(centerPt);
|
|
|
|
|
// 如果线段在圆内,则为无效线
|
|
|
|
|
if (sDist <= rad && eDist <= rad)
|
|
|
|
|
if (sDist - rad <= 1e-7 && eDist - rad <= 1e-7)
|
|
|
|
|
{
|
|
|
|
|
//该段多段线和切割圆弧是否重合
|
|
|
|
|
if (pl.LineData[0].bul !== 0)
|
|
|
|
@ -1128,8 +1150,11 @@ export class Polyline extends Curve
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//有可能误差错误漏掉切点
|
|
|
|
|
if (pts[0].distanceToSquared(pts[1]) <= 1e-8) continue;
|
|
|
|
|
let dist = pl.StartPoint.distanceTo(pts[0]);
|
|
|
|
|
let dist1 = pl.StartPoint.distanceTo(pts[1]);
|
|
|
|
|
//区分到pl的startPT近的和远的交点
|
|
|
|
|
let [pt, pt1] = dist < dist1 ? [pts[0], pts[1]] : [pts[1], pts[0]]
|
|
|
|
|
let clonePl = pl.Clone() as Polyline;
|
|
|
|
|
|
|
|
|
@ -1138,11 +1163,9 @@ export class Polyline extends Curve
|
|
|
|
|
this.adjustLaterLine(clonePl.LineData[1], pt1, clonePl.LineData[0]);
|
|
|
|
|
plList.splice(j + 1, 0, clonePl);
|
|
|
|
|
j++;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return plList;
|
|
|
|
|
}
|
|
|
|
|
private clonePlData(pl: PolylineProps)
|
|
|
|
|
{
|
|
|
|
@ -1228,7 +1251,7 @@ export class Polyline extends Curve
|
|
|
|
|
GetSnapPoints(): Array<THREE.Vector3>
|
|
|
|
|
{
|
|
|
|
|
let plList: Vector3[] = [];
|
|
|
|
|
for (let i = 0; i < this.EndParam; i += 0.5)
|
|
|
|
|
for (let i = 0; i < this.EndParam + 0.5; i += 0.5)
|
|
|
|
|
{
|
|
|
|
|
let p = this.GetPointAtParam(i);
|
|
|
|
|
plList.push(p);
|
|
|
|
@ -1261,7 +1284,7 @@ export class Polyline extends Curve
|
|
|
|
|
GetStretchPoints(): Array<Vector3>
|
|
|
|
|
{
|
|
|
|
|
let plList: Vector3[] = [];
|
|
|
|
|
for (let i = 0; i < this.m_LineData.length; i++)
|
|
|
|
|
for (let i = 0; i < this.EndParam + 1; i++)
|
|
|
|
|
{
|
|
|
|
|
let p = this.GetPointAtParam(i);
|
|
|
|
|
plList.push(p);
|
|
|
|
@ -1340,7 +1363,6 @@ export class Polyline extends Curve
|
|
|
|
|
{
|
|
|
|
|
super.ReadFile(file);
|
|
|
|
|
let ver = file.Read();
|
|
|
|
|
this.m_ClosedMark = file.Read();
|
|
|
|
|
this.m_LineData.length = 0;
|
|
|
|
|
let cout = file.Read();
|
|
|
|
|
for (let i = 0; i < cout; i++)
|
|
|
|
@ -1350,14 +1372,15 @@ export class Polyline extends Curve
|
|
|
|
|
|
|
|
|
|
this.m_LineData.push({ pt: v, bul: bul });
|
|
|
|
|
}
|
|
|
|
|
if (ver > 1)
|
|
|
|
|
this.m_ClosedMark = file.Read();
|
|
|
|
|
this.Update();
|
|
|
|
|
}
|
|
|
|
|
//对象将自身数据写入到文件.
|
|
|
|
|
WriteFile(file: CADFile)
|
|
|
|
|
{
|
|
|
|
|
super.WriteFile(file);
|
|
|
|
|
file.Write(1);
|
|
|
|
|
file.Write(this.m_ClosedMark);
|
|
|
|
|
file.Write(2);
|
|
|
|
|
file.Write(this.m_LineData.length);
|
|
|
|
|
|
|
|
|
|
for (let l of this.m_LineData)
|
|
|
|
@ -1365,5 +1388,6 @@ export class Polyline extends Curve
|
|
|
|
|
file.Write(l.pt.toArray());
|
|
|
|
|
file.Write(l.bul);
|
|
|
|
|
}
|
|
|
|
|
file.Write(this.m_ClosedMark);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|