!224 修复差集bug

Merge pull request !224 from ZoeLeeFZ/fixSub2
pull/224/MERGE
ZoeLeeFZ 6 years ago committed by ChenX
parent 61befa3f3a
commit 7699ec767b

@ -114,6 +114,13 @@ test("多都有洞面域,互不相交", () =>
expect(regs.length).toBe(3); expect(regs.length).toBe(3);
testRegionsBool(regs, 3, 3, 0, 0, 1, 1); testRegionsBool(regs, 3, 3, 0, 0, 1, 1);
}) })
test("有问题面域测试", () =>
{
let data =
[2, "Region", 1, 1, 7, false, 7, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 995.4564695921745, 866.7576945200351, 0, 1], 1, 1, 1, 1, "Polyline", 1, 1, 0, false, 7, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 995.4564695921745, 866.7576945200351, 0, 1], 2, 12, [1151.784316715255, 505.6870652512325], 0, [-48.215683284744955, 505.6870652512325], 0, [-48.215683284744955, 436.3728364140229], 0, [-322.28257444753535, 436.3728364140229], 0, [-322.28257444753535, 255.1386559489065], 0, [-48.215683284744955, 255.13865594890694], 0, [-48.215683284744955, 160.58169222797642], 0, [-310.4629539824191, 160.58169222797642], 0, [-310.4629539824191, -12.772741260395605], 0, [-48.215683284744955, -12.772741260395605], 0, [-48.215683284744955, -94.31293474876725], 0, [1151.784316715255, -94.31293474876725], 0, true, 0, "Region", 1, 1, 6, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -983.721937321937, -229.2831908831909, 0, 1], 1, 1, 1, 1, "Polyline", 1, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -983.721937321937, -229.2831908831909, 0, 1], 2, 5, [1966.4056656537157, 1219.4025937658553], 0, [2139.7600991420877, 1219.4025937658553], 0, [2139.7600991420877, 1275.3802040368082], 0, [1966.4056656537157, 1275.3802040368082], 0, [1966.4056656537157, 1219.4025937658553], 0, true, 0]
let regs = LoadRegionsFromFileData(data);
testRegionsBool(regs, 1, 0, 1, 0, 2, 0);
})
function testRegion(reg) function testRegion(reg)
{ {
if (reg) if (reg)

@ -178,8 +178,7 @@ export function curveLinkGroup(cus: Curve[]): Array<Array<Curve>>
export function equalCurveAndCurve(cu1: Curve, cu2: Curve) export function equalCurveAndCurve(cu1: Curve, cu2: Curve)
{ {
if (cu1.EndParam !== cu2.EndParam || !equaln(cu1.Length, cu2.Length)) return false;
if (cu1.EndParam !== cu2.EndParam || !equaln(cu1.Area, cu2.Area)) return false;
let parAtPl2 = cu2.GetParamAtPoint(cu1.StartPoint); let parAtPl2 = cu2.GetParamAtPoint(cu1.StartPoint);
if ((cu1 instanceof Polyline) && (cu2 instanceof Polyline)) if ((cu1 instanceof Polyline) && (cu2 instanceof Polyline))
@ -200,7 +199,9 @@ export function equalCurveAndCurve(cu1: Curve, cu2: Curve)
return ptsAndBuls1.pts.every((pt, i) => return ptsAndBuls1.pts.every((pt, i) =>
{ {
return equalv2(pt, pts2[i]); return equalv3(
Vec2DTo3D(pt).applyMatrix4(cu1.OCS),
Vec2DTo3D(pts2[i]).applyMatrix4(cu2.OCS));
}) })
} }
else if (cu1 instanceof Circle && cu2 instanceof Circle) else if (cu1 instanceof Circle && cu2 instanceof Circle)

@ -76,13 +76,13 @@ export class Contour
//交集:结果数组为空则失败 //交集:结果数组为空则失败
IntersectionBoolOperation(target: Contour): Contour[] IntersectionBoolOperation(target: Contour): Contour[]
{ {
let resultCus = this.getOperatedCurves(target); let resultCus = this.getIntersetAndUnionList(target);
return Contour.GetAllContour(resultCus.intersectionList); return Contour.GetAllContour(resultCus.intersectionList);
} }
//并集:结果数组长度大于2,则失败.等于1则成功. //并集:结果数组长度大于2,则失败.等于1则成功.
UnionBoolOperation(target: Contour): Contour[] UnionBoolOperation(target: Contour): Contour[]
{ {
let resultCus = this.getOperatedCurves(target); let resultCus = this.getIntersetAndUnionList(target);
//并集后的线段表如果有共线的直接合并起来 //并集后的线段表如果有共线的直接合并起来
let cus: Curve[] = []; let cus: Curve[] = [];
for (let pl of resultCus.unionList) for (let pl of resultCus.unionList)
@ -112,22 +112,21 @@ export class Contour
//差集:等于0完全被减去 //差集:等于0完全被减去
SubstactBoolOperation(target: Contour): Contour[] SubstactBoolOperation(target: Contour): Contour[]
{ {
let resultCus = this.getOperatedCurves(target); let subtractList = this.getSubtractList(target);
return Contour.GetAllContour(resultCus.subtractList); return Contour.GetAllContour(subtractList);
} }
/** /**
* 线. * 线.
* *
* @private * @private
* @param {Contour} target * @param {Contour} target
* @returns {intersectionList //交集曲线表, unionList //并集曲线表, subtractList 差集曲线表} * @returns {intersectionList //交集曲线表, unionList //并集曲线表}
* @memberof Contour * @memberof Contour
*/ */
getOperatedCurves(target: Contour) getIntersetAndUnionList(target: Contour)
{ {
let intersectionList: Curve[] = []; let intersectionList: Curve[] = [];
let unionList: Curve[] = []; let unionList: Curve[] = [];
let subtractList: Curve[] = [];
let sourceOutline = this.m_Curve; let sourceOutline = this.m_Curve;
let targetOutline = target.Curve; let targetOutline = target.Curve;
@ -140,7 +139,6 @@ export class Contour
if (sourceContainerTarget)//源包含目标 if (sourceContainerTarget)//源包含目标
{ {
intersectionList.push(targetOutline); intersectionList.push(targetOutline);
subtractList.push(sourceOutline, targetOutline);
unionList.push(sourceOutline); unionList.push(sourceOutline);
} }
else if (targetContainerSource)//目标包含源 else if (targetContainerSource)//目标包含源
@ -151,7 +149,6 @@ export class Contour
else if (interPts.length === 0)//分离 else if (interPts.length === 0)//分离
{ {
unionList.push(sourceOutline, targetOutline); unionList.push(sourceOutline, targetOutline);
subtractList.push(sourceOutline);
} }
else//相交 interPts.length > 0 else//相交 interPts.length > 0
{ {
@ -192,7 +189,6 @@ export class Contour
} }
else else
{ {
subtractList.push(pl);
unionList.push(pl); unionList.push(pl);
} }
} }
@ -207,7 +203,6 @@ export class Contour
if (this.CuInOutline(pl)) if (this.CuInOutline(pl))
{ {
intersectionList.push(pl); intersectionList.push(pl);
subtractList.push(pl);
} }
else else
{ {
@ -215,9 +210,78 @@ export class Contour
} }
} }
} }
return { intersectionList, unionList, subtractList }; return { intersectionList, unionList };
} }
getSubtractList(target: Contour)
{
let subtractList: Curve[] = [];
let sourceOutline = this.m_Curve;
let targetOutline = target.Curve;
let interPts = sourceOutline.IntersectWith(targetOutline, IntersectOption.OnBothOperands);
let sourceContainerTarget = this.CuInOutline(targetOutline);
let targetContainerSource = target.CuInOutline(sourceOutline);
//包含.相交.分离(三种状态)
if (sourceContainerTarget && interPts.length === 0)//源包含目标
{
subtractList.push(sourceOutline, targetOutline);
}
else if (targetContainerSource)//目标包含源
{
return [];
}
else if (interPts.length === 0)//分离
{
subtractList.push(sourceOutline);
}
else//相交 interPts.length > 0
{
let pars1 = interPts.map(p => sourceOutline.GetParamAtPoint(p));
let pars2 = interPts.map(p => targetOutline.GetParamAtPoint(p));
let sourceCus: Array<Polyline | Arc> = sourceOutline.GetSplitCurves(pars1);
let targetCus: Array<Polyline | Arc> = targetOutline.GetSplitCurves(pars2);
//是否有相等的曲线
let hasEqualCus = false;
let equalCus: WeakSet<Curve> = new WeakSet();
for (let pl of sourceCus)
{
//有一样的曲线直接跳过
hasEqualCus = targetCus.some(l =>
{
if (equalCurveAndCurve(pl, l))
{
equalCus.add(l);
return true;
}
return false;
});
if (hasEqualCus)
continue;
if (!target.CuInOutline(pl))
{
subtractList.push(pl);
}
}
for (let pl of targetCus)
{
if (equalCus.has(pl))
continue;
if (this.CuInOutline(pl))
{
subtractList.push(pl);
}
}
}
return subtractList;
}
/** /**
* 线 * 线
* @线,线 * @线,线

Loading…
Cancel
Save