|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
import { Vector3 } from 'three';
|
|
|
|
|
import { arrayRemoveDuplicateBySort, arrayRemoveIf } from '../Common/ArrayExt';
|
|
|
|
|
import { Arc } from '../DatabaseServices/Arc';
|
|
|
|
|
import { Curve } from '../DatabaseServices/Curve';
|
|
|
|
|
import { Polyline } from '../DatabaseServices/Polyline';
|
|
|
|
|
import { Count } from './Count';
|
|
|
|
|
import { CurveMap } from './CurveMap';
|
|
|
|
|
import { angle, equalv3 } from './GeUtils';
|
|
|
|
@ -36,6 +38,9 @@ export class RegionParse
|
|
|
|
|
//区域列表 通常是内轮廓
|
|
|
|
|
m_RegionsInternal: RegionRouteS = [];
|
|
|
|
|
|
|
|
|
|
//碎线 曲线进入到这里会被炸开.
|
|
|
|
|
m_ExpLineMap: Map<Curve, Curve[]> = new Map();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates an instance of RegionParse.
|
|
|
|
|
* @param {Curve[]} cuList 请不要传递圆和椭圆.
|
|
|
|
@ -70,6 +75,24 @@ export class RegionParse
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 曲线是否已经被算法使用
|
|
|
|
|
* @param cu
|
|
|
|
|
* @returns true if cueve used
|
|
|
|
|
*/
|
|
|
|
|
GetCueveUsed(cu: Curve): boolean
|
|
|
|
|
{
|
|
|
|
|
if (this.m_ExpLineMap.has(cu))
|
|
|
|
|
{
|
|
|
|
|
let use = this.m_ExpLineMap.get(cu).some(c => this.m_CountCu.GetCount(c) > 0);
|
|
|
|
|
if (!use)
|
|
|
|
|
this.m_ExpLineMap.delete(cu);
|
|
|
|
|
return use;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return this.m_CountCu.GetCount(cu) > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 使用类似涨潮的方式,从最低的地方,采用顺时针填充.
|
|
|
|
|
* 算法允许搜索到的区域在外轮廓外.
|
|
|
|
@ -172,17 +195,51 @@ export class RegionParse
|
|
|
|
|
private GenerateNodeMap(cuList: Curve[]): Set<Stand>
|
|
|
|
|
{
|
|
|
|
|
let curveMap = new CurveMap();
|
|
|
|
|
|
|
|
|
|
//将多段线炸开
|
|
|
|
|
let plcus: Curve[] = [];
|
|
|
|
|
arrayRemoveIf(cuList, c =>
|
|
|
|
|
{
|
|
|
|
|
if (c instanceof Polyline)
|
|
|
|
|
{
|
|
|
|
|
let cus = c.Explode();
|
|
|
|
|
|
|
|
|
|
//如果为圆弧,提前打断
|
|
|
|
|
let arcs: Arc[] = [];
|
|
|
|
|
arrayRemoveIf(cus, c =>
|
|
|
|
|
{
|
|
|
|
|
if (c instanceof Arc)
|
|
|
|
|
{
|
|
|
|
|
let arcBrs = this.BreakArc(c);
|
|
|
|
|
if (arcBrs.length > 1)
|
|
|
|
|
{
|
|
|
|
|
arcs.push(...arcBrs);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
//加入到计算
|
|
|
|
|
cus.push(...arcs);
|
|
|
|
|
|
|
|
|
|
this.m_ExpLineMap.set(c, cus);
|
|
|
|
|
plcus.push(...cus);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
cuList.push(...plcus);
|
|
|
|
|
|
|
|
|
|
for (let cu of cuList)
|
|
|
|
|
{
|
|
|
|
|
//由于圆弧可能导致最低点计算错误的问题.
|
|
|
|
|
if (cu instanceof Arc)
|
|
|
|
|
{
|
|
|
|
|
let underPt = cu.Center.add(new Vector3(0, -cu.Radius));
|
|
|
|
|
let param = cu.GetParamAtPoint(underPt);
|
|
|
|
|
if (param > 0.01 && param < 0.99)
|
|
|
|
|
let arcs = this.BreakArc(cu);
|
|
|
|
|
if (arcs.length > 1)
|
|
|
|
|
{
|
|
|
|
|
let arcs = cu.GetSplitCurves(param);
|
|
|
|
|
arcs.forEach(a => curveMap.addCurveToMap(a));
|
|
|
|
|
this.m_ExpLineMap.set(cu, arcs);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -206,12 +263,28 @@ export class RegionParse
|
|
|
|
|
a2 = angle(r2.curve.GetFistDeriv(r1.curve.EndParam).negate());
|
|
|
|
|
|
|
|
|
|
return a1 - a2;
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//移除重复的线
|
|
|
|
|
arrayRemoveDuplicateBySort(s.routes, (r1, r2) =>
|
|
|
|
|
{
|
|
|
|
|
return r1.to === r2.to && r1.curve.constructor.name === r2.curve.constructor.name;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return new Set(curveMap.Stands);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BreakArc(arc: Arc)
|
|
|
|
|
{
|
|
|
|
|
let underPt = arc.Center.add(new Vector3(0, -arc.Radius));
|
|
|
|
|
let param = arc.GetParamAtPoint(underPt);
|
|
|
|
|
if (param > 0.01 && param < 0.99)
|
|
|
|
|
return arc.GetSplitCurves(param);
|
|
|
|
|
else
|
|
|
|
|
return [arc];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//寻找闭合轮廓,下一站总是使用逆时针规划.
|
|
|
|
|
private FindRegion(firstS: Stand, //起点
|
|
|
|
|
nowStand: Stand, //当前站
|
|
|
|
|