fix #IKIA9 处理共线时相交部分

pull/68/head
Zoe 6 years ago
parent 1a7fdab582
commit 85849bd601

@ -85,7 +85,7 @@ export abstract class Curve extends Entity
* @memberof Curve
*/
GetSplitCurves(param: number[] | number): Array<Curve> { return; }
GetSplitCurvesByPt(pt: Vector3[] | Vector3): Array<Curve>
GetSplitCurvesByPts(pt: Vector3[] | Vector3): Array<Curve>
{
let pts = Array.isArray(pt) ? pt : [pt];
let pars = pts.map(p => this.GetParamAtPoint(p))

@ -12,7 +12,6 @@ import { equal, equaln } from "../Geometry/GeUtils";
import { SortEntityByBox } from "../Geometry/SortEntityByBox";
import { IsPtsAllOutOrOnReg } from "./BoolOperateUtils";
import { IntersectOption } from "./IntersectWith";
import { testCurve } from "../Add-on/testEntity/TestCurve";
interface offestRes
{
@ -23,7 +22,6 @@ interface offestRes
//FIXME:1.当轮廓自交时,会丢失自交的线段
//FIXME:2.往内偏移到极限位置,会有多余线段,
// 与偏移方向问题应该一样,方向若和偏移距离相反,则删除
//FIXME:3.线段共线时,有时造成线段不连续
export class PolyOffestUtil
{
private m_Polyline: Polyline;
@ -46,11 +44,6 @@ export class PolyOffestUtil
let expCus = this.m_Polyline.Explode();
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)
{
@ -65,21 +58,12 @@ export class PolyOffestUtil
// testContours(contours);
//裁剪
let cus = this.trimByContours(this.m_RetCurves);
let { boxCurves, outputCus } = this.trimByContours(this.m_RetCurves);
//过滤掉无效的线段
cus = cus.filter(c =>
{
//与源线段自交
if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0)
return false;
// 优化裁剪后的曲线
outputCus = this.optimizeCus(boxCurves, outputCus);
//起点终点离源线段的距离必须大于偏移距离
return this.CheckPoint(c.StartPoint) && this.CheckPoint(c.EndPoint);
});
//先打断?
// return this.linkCurves(cus);
return cus;
return this.linkCurves(outputCus);
}
/**
@ -97,7 +81,63 @@ export class PolyOffestUtil
.distanceToSquared(pt);
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[]
{
@ -418,7 +458,7 @@ export class PolyOffestUtil
}
}
// 通过构建的轮廓对偏移曲线进行裁剪
private trimByContours(needCutCus: Curve[]): Curve[]
private trimByContours(needCutCus: Curve[])
{
let boxContours = SortEntityByBox(this.m_Contours, false);
let boxCurves = SortEntityByBox(needCutCus, true);
@ -472,46 +512,7 @@ export class PolyOffestUtil
needCutCus = tmpCus;
})
// let count = needCutCus.length
// 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;
return { boxCurves, outputCus: needCutCus };
}
/**

Loading…
Cancel
Save