diff --git a/__test__/Booloperate/__snapshots__/bool3.test.ts.snap b/__test__/Booloperate/__snapshots__/bool3.test.ts.snap index 6c3c1013a..8fee0db28 100644 --- a/__test__/Booloperate/__snapshots__/bool3.test.ts.snap +++ b/__test__/Booloperate/__snapshots__/bool3.test.ts.snap @@ -2,4 +2,4 @@ exports[`布尔_误差共线_误差交点 1`] = `739590.0297771678`; -exports[`布尔_误差共线_误差交点 2`] = `739582.752529773`; +exports[`布尔_误差共线_误差交点 2`] = `739582.7655079779`; diff --git a/__test__/Booloperate/bool2.test.ts b/__test__/Booloperate/bool2.test.ts index 360a70a5a..5fcbccf9e 100644 --- a/__test__/Booloperate/bool2.test.ts +++ b/__test__/Booloperate/bool2.test.ts @@ -57,7 +57,7 @@ test("包含差集的对象,差一点就可以切断", () => let regs: Region[] = LoadRegionsFromFileData(data); regs[0].BooleanOper(regs[1], BoolOpeartionType.Subtract); - expect(regs[0].ShapeManager.ShapeCount).toBe(1); + expect(regs[0].ShapeManager.ShapeCount).toBe(2); expect(regs[0].ShapeManager.ShapeList[0].Holes.length).toBe(0); }); diff --git a/__test__/Booloperate/bool3.test.ts b/__test__/Booloperate/bool3.test.ts index 7afc31a93..fa0fafae5 100644 --- a/__test__/Booloperate/bool3.test.ts +++ b/__test__/Booloperate/bool3.test.ts @@ -18,3 +18,11 @@ test('布尔_误差共线_误差交点', () => expect(regs[0].Area).toMatchSnapshot(); }); + +test('误差打断', () => +{ + let d = [2, "Region", 3, 2, 780, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1270.0801901174855, 251.0534593864627, 0, 1], 1, 1, 1, 1, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1270.0801901174855, 251.0534593864627, 0, 1], 2, 7, [337.0932869688667, -418.03134104109404], 0, [482, -246.84009191289078], 0, [482, -146.84009191289078], 0, [582, -146.84009191289078], 0, [582, 573.0000000000002], 0, [0, 573.0000000000002], 0, [0, -418.03134104109404], 0, true, 0, "Region", 3, 2, 779, false, 1, 7, 0, [-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, -872.726286511064, -95.7866325264281, 0, 1], 1, 1, 1, 1, "Polyline", 3, 2, 0, false, 0, 7, 0, [-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, -872.726286511064, -95.7866325264281, 0, 1], 2, 4, [0, 0], 0, [397.3539036064214, 0], 0, [397.3539036064214, 18], 0, [0, 18], 0, true, 0] + let regs = LoadRegionsFromFileData(d); + regs[0].BooleanOper(regs[1], BoolOpeartionType.Subtract); + expect(regs[0].ShapeManager.ShapeList.length).toBe(2); +}); diff --git a/package.json b/package.json index 85f833140..c9aedd65f 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "@types/blueimp-md5": "^2.7.0", "@types/html-webpack-plugin": "^3.2.0", "@types/jest": "^24.0.13", - "@types/node": "^12.0.1", + "@types/node": "^12.0.2", "@types/react": "^16.8.17", "@types/react-color": "^3.0.0", "@types/react-dom": "^16.8.4", @@ -44,11 +44,11 @@ "gitlog": "^3.1.2", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", - "jest": "^24.7.1", + "jest": "^23.6.0", "less": "^3.9.0", "less-loader": "^5.0.0", "mobx-react-devtools": "^6.0.3", - "react-hot-loader": "^4.8.4", + "react-hot-loader": "^4.8.6", "request": "^2.88.0", "request-promise-native": "^1.0.7", "required-loader": "^1.3.16", @@ -58,7 +58,7 @@ "style-loader": "^0.23.1", "terser-webpack-plugin": "^1.2.2", "ts-jest": "^24.0.2", - "ts-loader": "^6.0.0", + "ts-loader": "^6.0.1", "ts-node": "^8.1.0", "tsconfig-paths": "^3.8.0", "typescript": "^3.3.4000", @@ -66,7 +66,7 @@ "wallaby-webpack": "^3.9.15", "webpack": "^4.31.0", "webpack-cli": "^3.3.2", - "webpack-dev-server": "^3.3.1", + "webpack-dev-server": "^3.4.1", "webpack-merge": "^4.2.1" }, "dependencies": { @@ -74,7 +74,7 @@ "blueimp-md5": "^2.10.0", "golden-layout": "^1.5.9", "mobx": "^5.9.4", - "mobx-react": "^5.4.3", + "mobx-react": "^5.4.4", "react": "^16.8.2", "react-color": "^2.17.3", "react-dom": "^16.8.2", diff --git a/src/Add-on/DrawRegion.ts b/src/Add-on/DrawRegion.ts index e0bdcf1c0..f5c3cddbb 100644 --- a/src/Add-on/DrawRegion.ts +++ b/src/Add-on/DrawRegion.ts @@ -31,7 +31,7 @@ export class DrawRegion implements Command } if (lines.length > 0) { - let reg = new RegionParse(lines); + let reg = new RegionParse(lines, 3); for (let routes of reg.m_RegionsOutline) this.DrawRegion(routes); diff --git a/src/Common/CurveUtils.ts b/src/Common/CurveUtils.ts index 79e291e5f..327d5c31e 100644 --- a/src/Common/CurveUtils.ts +++ b/src/Common/CurveUtils.ts @@ -178,7 +178,7 @@ export function curveLinkGroup(cus: Curve[]): Array> return groupCus; } -export function equalCurve(cu1: Curve, cu2: Curve) +export function equalCurve(cu1: Curve, cu2: Curve, tolerance = 1e-4) { if ((cu1 instanceof Polyline) && (cu2 instanceof Polyline)) { @@ -219,12 +219,12 @@ export function equalCurve(cu1: Curve, cu2: Curve) buls2.push(buls2.shift()); } - if (cu1.IsClose && equalv2(pts1[0], arrayLast(pts1), 1e-6)) + if (cu1.IsClose && equalv2(pts1[0], arrayLast(pts1), tolerance)) { pts1.pop(); buls1.pop(); } - if (cu2.IsClose && equalv2(pts2[0], arrayLast(pts2), 1e-6)) + if (cu2.IsClose && equalv2(pts2[0], arrayLast(pts2), tolerance)) { pts2.pop(); buls2.pop(); @@ -232,7 +232,7 @@ export function equalCurve(cu1: Curve, cu2: Curve) let cu1Sp = Vec3DTo2D(cu1.StartPoint.applyMatrix4(cu2.OCSInv)); - let index = pts2.findIndex(p => equalv2(cu1Sp, p, 1e-5)); + let index = pts2.findIndex(p => equalv2(cu1Sp, p, tolerance)); changeArrayStartIndex(buls2, index); changeArrayStartIndex(pts2, index); @@ -241,7 +241,7 @@ export function equalCurve(cu1: Curve, cu2: Curve) equalv3( Vec2DTo3D(p1).applyMatrix4(cu1.OCS), Vec2DTo3D(p2).applyMatrix4(cu2.OCS), - 1e-4 + tolerance ) ); } diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index e0b1f7e4c..d9cef712c 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -1,10 +1,10 @@ import * as THREE from "three"; import { Vector3 } from "three"; -import { arrayRemoveDuplicateBySort, arrayRemoveIf } from "../Common/ArrayExt"; -import { curveLinkGroup, equalCurve, Vec3DTo2D, getCirAngleByChordAndTangent } from "../Common/CurveUtils"; +import { arrayRemoveDuplicateBySort, arrayRemoveIf, arrayLast } from "../Common/ArrayExt"; +import { curveLinkGroup, equalCurve } from "../Common/CurveUtils"; import { Status } from "../Common/Status"; import { FixIndex } from "../Common/Utils"; -import { equaln, rotatePoint } from "../Geometry/GeUtils"; +import { equaln, rotatePoint, equalv3, equalv2 } from "../Geometry/GeUtils"; import { RegionParse, Route } from "../Geometry/RegionParse"; import { isTargetCurInOrOnSourceCur } from "../GraphicsSystem/BoolOperateUtils"; import { IntersectOption } from "../GraphicsSystem/IntersectWith"; @@ -138,7 +138,7 @@ export class Contour if (subtractList.every(c => c.IsClose)) return Contour.GetAllContour(subtractList); - let regParse = new RegionParse(subtractList); + let regParse = new RegionParse(subtractList, 2); let contours: Contour[] = []; //分析封闭包围区域 @@ -264,62 +264,55 @@ export class Contour } GetSubtractList(target: Contour) { - let sourceOutline = this.m_Curve; - let targetOutline = target.Curve; - - if (target.CuInOutline(sourceOutline)) - return []; - - let interPts = sourceOutline.IntersectWith(targetOutline, IntersectOption.OnBothOperands); + let sourceOutline = this.m_Curve as Polyline; + let targetOutline = target.Curve as Polyline; - let sourceContainerTarget = this.CuInOutline(targetOutline); + let interPts = sourceOutline.IntersectWith(targetOutline, IntersectOption.OnBothOperands, 1e-3); - //包含.相交.分离(三种状态) - if (sourceContainerTarget && interPts.length <= 1)//源包含目标 - { - return [sourceOutline, targetOutline]; - } - else if (interPts.length <= 1)//分离 + if (interPts.length <= 1) { - return [sourceOutline]; + //反包含 + if (fastCurveInCurve2(targetOutline, sourceOutline)) + return []; + //包含 + if (fastCurveInCurve2(sourceOutline, targetOutline)) + return [sourceOutline, targetOutline]; + else//分离 + return [sourceOutline]; } - else//相交 interPts.length > 0 - { - let subtractList: Curve[] = []; - let sourceCus = sourceOutline.GetSplitCurvesByPts(interPts); - let targetCus = targetOutline.GetSplitCurvesByPts(interPts); + //相交 + let subtractList: Curve[] = []; + let sourceCus = sourceOutline.GetSplitCurvesByPts(interPts) as Polyline[]; + let targetCus = targetOutline.GetSplitCurvesByPts(interPts) as Polyline[]; - for (let pl of sourceCus) + for (let pl of sourceCus) + { + let hasEqualCus = false; + arrayRemoveIf(targetCus, cu => { - let hasEqualCus = false; - arrayRemoveIf(targetCus, cu => - { - if (hasEqualCus) return false; - hasEqualCus = equalCurve(cu, pl); - return hasEqualCus; - }); - if (hasEqualCus) - continue; - - if (!target.CuInOutline(pl)) - subtractList.push(pl); - } + if (hasEqualCus) return false; + hasEqualCus = fastEqualCurve(cu, pl); + return hasEqualCus; + }); + if (hasEqualCus) + continue; + + if (!fastCurveInCurve(targetOutline, pl)) + subtractList.push(pl); + } - //源对象没有被破坏 - let sourceNotBreak = subtractList.length === sourceCus.length; + //源对象没有被破坏 + let sourceNotBreak = subtractList.length === sourceCus.length; - for (let pl of targetCus) - { - if (this.CuInOutline(pl)) - subtractList.push(pl); - } + for (let pl of targetCus) + if (fastCurveInCurve(sourceOutline, pl)) + subtractList.push(pl); - if (sourceNotBreak && subtractList.length === sourceCus.length) - return [sourceOutline]; + if (sourceNotBreak && subtractList.length === sourceCus.length) + return [sourceOutline]; - return subtractList; - } + return subtractList; } /** * 获得全部闭合曲线 @@ -348,7 +341,7 @@ export class Contour * @param [needLink=true] 需要解析成首尾连接状态 * @returns 单一曲线,如果返回超过1个,其他的将被遗弃. */ - static Combine(cus: Curve[], needLink = true): Curve + static Combine(cus: Curve[], needLink = true, tolerance = 1e-3): Curve { if (cus.length === 0) return undefined; @@ -369,7 +362,15 @@ export class Contour arrayRemoveDuplicateBySort(gclone, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True); for (let cu of gclone) - pl.Join(cu); + pl.Join(cu, false, tolerance); + + let d = pl.LineData; + if (d.length > 1) + { + let ld = arrayLast(d).pt; + if (equalv2(d[0].pt, ld, tolerance)) + ld.copy(d[0].pt); + } cache.set(g, pl); @@ -390,3 +391,35 @@ export class Contour return equalCurve(this.m_Curve, tar.m_Curve); } } + +/** + * 对于轮廓切割后的曲线判断相同,使用这个函数进行快速判断 + */ +function fastEqualCurve(c1: Polyline, c2: Polyline, tolerance = 1e-3) +{ + let sp1 = c1.StartPoint; + let ep1 = c1.EndPoint; + let sp2 = c2.StartPoint; + let ep2 = c2.EndPoint; + + if (!( + (equalv3(sp1, sp2, tolerance) && equalv3(ep1, ep2, tolerance)) + || (equalv3(sp1, ep2, tolerance) && equalv3(ep1, sp2, tolerance)) + )) + return false; + + return equalv3(c1.GetPointAtParam(c1.EndParam * 0.5), c2.GetPointAtParam(c2.EndParam * 0.5), tolerance); +} + + +//对于双多段线互相切割后的结果,快速判断曲线是否在另一条曲线内部 +function fastCurveInCurve(sourceCu: Polyline, targetCu: Polyline) +{ + return sourceCu.PtInCurve(targetCu.GetPointAtParam(targetCu.EndParam * 0.5)); +} + +function fastCurveInCurve2(sourceCu: Polyline, targetCu: Polyline) +{ + return sourceCu.PtInCurve(targetCu.StartPoint) && + sourceCu.PtInCurve(targetCu.GetPointAtParam(targetCu.EndParam * 0.5)); +} diff --git a/src/DatabaseServices/Curve.ts b/src/DatabaseServices/Curve.ts index bd561116d..81c5750cd 100644 --- a/src/DatabaseServices/Curve.ts +++ b/src/DatabaseServices/Curve.ts @@ -126,7 +126,7 @@ export abstract class Curve extends Entity * @returns {boolean} 连接成功 * @memberof Curve */ - Join(cu: Curve): Status { return Status.False; } + Join(cu: Curve, allowGap = false, tolerance = 1e-4): Status { return Status.False; } //翻转曲线.首尾调换. Reverse(): this { return this; } @@ -155,7 +155,7 @@ export abstract class Curve extends Entity * @returns {Vector3[]} * @memberof Curve */ - IntersectWith(curve: Curve, intType: IntersectOption): Vector3[] { return []; } + IntersectWith(curve: Curve, intType: IntersectOption, tolerance = 1e-6): Vector3[] { return []; } //------------------绘制相关------------------ GetDrawObjectFromRenderType(renderType: RenderType = RenderType.Wireframe): Object3D diff --git a/src/DatabaseServices/Line.ts b/src/DatabaseServices/Line.ts index c9e1d7654..8f2b61c5a 100644 --- a/src/DatabaseServices/Line.ts +++ b/src/DatabaseServices/Line.ts @@ -157,27 +157,27 @@ export class Line extends Curve return this.EndPoint.sub(this.StartPoint); } - IntersectWith(curve: Curve, intType: IntersectOption): Vector3[] + IntersectWith(curve: Curve, intType: IntersectOption, tolerance = 1e-6): Vector3[] { if (curve instanceof Line) { - return IntersectLineAndLine(this, curve, intType); + return IntersectLineAndLine(this, curve, intType, tolerance); } if (curve instanceof Arc) { - return IntersectLineAndArc(this, curve, intType); + return IntersectLineAndArc(this, curve, intType, tolerance); } if (curve instanceof Circle) { - return IntersectLineAndCircle(this, curve, intType); + return IntersectLineAndCircle(this, curve, intType, tolerance); } if (curve instanceof Polyline) { - return IntersectPolylineAndCurve(curve, this, reverseIntersectOption(intType)); + return IntersectPolylineAndCurve(curve, this, reverseIntersectOption(intType), tolerance); } if (curve instanceof Ellipse) - return IntersectEllipseAndLine(this, curve, intType); + return IntersectEllipseAndLine(this, curve, intType, tolerance); //其他的尚未实现. return []; @@ -294,7 +294,7 @@ export class Line extends Curve } } - Join(cu: Curve, allowGap = false, fuzz = 1e-5): Status + Join(cu: Curve, allowGap = false, tolerance = 1e-5): Status { if (cu instanceof Line) { @@ -304,18 +304,18 @@ export class Line extends Curve let sp = cu.StartPoint; let { closestPt: cp1, param: param1 } = this.GetClosestAtPoint(sp, true); - if (!equalv3(sp, cp1, fuzz))//点在曲线上,允许较低的精度 + if (!equalv3(sp, cp1, tolerance))//点在曲线上,允许较低的精度 return Status.False; let ep = cu.EndPoint; let { closestPt: cp2, param: param2 } = this.GetClosestAtPoint(ep, true); - if (!equalv3(ep, cp2, fuzz)) + if (!equalv3(ep, cp2, tolerance)) return Status.False; if (param1 > param2) [param1, param2] = [param2, param1]; - if (allowGap || Math.max(0, param1) < Math.min(1, param2) + fuzz) + if (allowGap || Math.max(0, param1) < Math.min(1, param2) + tolerance) { if (param1 < 0) this.Extend(param1); diff --git a/src/DatabaseServices/Polyline.ts b/src/DatabaseServices/Polyline.ts index 0f83ad79f..4d657baf6 100644 --- a/src/DatabaseServices/Polyline.ts +++ b/src/DatabaseServices/Polyline.ts @@ -688,7 +688,7 @@ export class Polyline extends Curve } } - Join(cu: Curve, fuzz = 1e-4) + Join(cu: Curve, allowGap = false, tolerance = 1e-4) { this.WriteAllObjectRecord(); if (this.m_ClosedMark) @@ -727,19 +727,19 @@ export class Polyline extends Curve if (cu instanceof Line) { - if (equalv3(cuSp, sp, fuzz)) + if (equalv3(cuSp, sp, tolerance)) { this.m_LineData.unshift({ pt: cuEp2, bul: 0 }); } - else if (equalv3(cuSp, ep, fuzz)) + else if (equalv3(cuSp, ep, tolerance)) { this.m_LineData.push({ pt: cuEp2, bul: 0 }); } - else if (equalv3(cuEp, sp, fuzz)) + else if (equalv3(cuEp, sp, tolerance)) { this.m_LineData.unshift({ pt: cuSp2, bul: 0 }); } - else if (equalv3(cuEp, ep, fuzz)) + else if (equalv3(cuEp, ep, tolerance)) { this.m_LineData.push({ pt: cuSp2, bul: 0 }); } @@ -750,20 +750,20 @@ export class Polyline extends Curve { let dir = equalv3(this.Normal, cu.Normal.negate()) ? -1 : 1; let bul = cu.Bul * dir; - if (equalv3(cuSp, sp, fuzz)) + if (equalv3(cuSp, sp, tolerance)) { this.m_LineData.unshift({ pt: cuEp2, bul: -bul }); } - else if (equalv3(cuSp, ep, fuzz)) + else if (equalv3(cuSp, ep, tolerance)) { arrayLast(this.m_LineData).bul = bul; this.m_LineData.push({ pt: cuEp2, bul: 0 }); } - else if (equalv3(cuEp, sp, fuzz)) + else if (equalv3(cuEp, sp, tolerance)) { this.m_LineData.unshift({ pt: cuSp2, bul: bul }); } - else if (equalv3(cuEp, ep, fuzz)) + else if (equalv3(cuEp, ep, tolerance)) { arrayLast(this.m_LineData).bul = -bul; this.m_LineData.push({ pt: cuSp2, bul: 0 }); @@ -779,7 +779,7 @@ export class Polyline extends Curve let { pts, buls } = this.PtsBuls; - if (equalv3(cuSp, sp, fuzz)) + if (equalv3(cuSp, sp, tolerance)) { cu.Reverse(); let cuPtsBul = cu.PtsBuls; @@ -788,7 +788,7 @@ export class Polyline extends Curve pts = cuPtsBul.pts.concat(pts); buls = cuPtsBul.buls.concat(buls); } - else if (equalv3(cuSp, ep, fuzz)) + else if (equalv3(cuSp, ep, tolerance)) { pts.pop(); buls.pop(); @@ -797,7 +797,7 @@ export class Polyline extends Curve pts = pts.concat(cuPtsBul.pts); buls = buls.concat(cuPtsBul.buls); } - else if (equalv3(cuEp, sp, fuzz)) + else if (equalv3(cuEp, sp, tolerance)) { let cuPtsBul = cu.PtsBuls; cuPtsBul.pts.pop(); @@ -805,7 +805,7 @@ export class Polyline extends Curve pts = cuPtsBul.pts.concat(pts); buls = cuPtsBul.buls.concat(buls); } - else if (equalv3(cuEp, ep, fuzz)) + else if (equalv3(cuEp, ep, tolerance)) { pts.pop(); buls.pop(); @@ -987,9 +987,9 @@ export class Polyline extends Curve } } - IntersectWith(curve: Curve, intType: IntersectOption): Vector3[] + IntersectWith(curve: Curve, intType: IntersectOption, tolerance = 1e-6): Vector3[] { - return IntersectPolylineAndCurve(this, curve, intType); + return IntersectPolylineAndCurve(this, curve, intType, tolerance); } //计算自交点. diff --git a/src/Geometry/RegionParse.ts b/src/Geometry/RegionParse.ts index c2c3024cc..66cdec7c9 100644 --- a/src/Geometry/RegionParse.ts +++ b/src/Geometry/RegionParse.ts @@ -46,7 +46,7 @@ export class RegionParse * @param {Curve[]} cuList 请不要传递圆和椭圆. * @memberof RegionParse */ - constructor(cuList: Curve[], public fractionDigits?) + constructor(cuList: Curve[], public fractionDigits = 3) { //需要搜索的站 let needFinds = this.GenerateNodeMap(cuList); diff --git a/src/GraphicsSystem/IntersectWith.ts b/src/GraphicsSystem/IntersectWith.ts index e3a457ee8..eaba04725 100644 --- a/src/GraphicsSystem/IntersectWith.ts +++ b/src/GraphicsSystem/IntersectWith.ts @@ -52,11 +52,11 @@ export function reverseIntersectOption(intType: IntersectOption) * @param {Intersect} extType 延伸选项. * @returns {Array} 校验完成后的点表 */ -function CheckPointOnCurve(intPts: Vector3[], c1: Curve, c2: Curve, extType: IntersectOption, fuzz = 1e-4): Array +function CheckPointOnCurve(intPts: Vector3[], c1: Curve, c2: Curve, extType: IntersectOption, tolerance = 1e-6): Array { return intPts.filter(p => { - return (extType & IntersectOption.ExtendThis || c1.PtOnCurve(p, fuzz)) && (extType & IntersectOption.ExtendArg || c2.PtOnCurve(p, fuzz)) + return (extType & IntersectOption.ExtendThis || c1.PtOnCurve(p, tolerance)) && (extType & IntersectOption.ExtendArg || c2.PtOnCurve(p, tolerance)) }); } @@ -119,10 +119,10 @@ export function IntersectCircleAndCircle(cu1: Circle | Arc, cu2: Circle | Arc) * @param {IntersectOption} extType 延伸选项 * @returns 交点集合 */ -export function IntersectCircleAndArc(circle: Circle, arc: Arc, extType: IntersectOption) +export function IntersectCircleAndArc(circle: Circle, arc: Arc, extType: IntersectOption, tolerance = 1e-6) { let pts = IntersectCircleAndCircle(circle, arc); - return CheckPointOnCurve(pts, circle, arc, extType | IntersectOption.ExtendThis); + return CheckPointOnCurve(pts, circle, arc, extType | IntersectOption.ExtendThis, tolerance); } /** @@ -134,16 +134,16 @@ export function IntersectCircleAndArc(circle: Circle, arc: Arc, extType: Interse * @param {IntersectOption} extType 延伸选项 * @returns 交点集合 */ -export function IntersectArcAndArc(arc1: Arc, arc2: Arc, extType: IntersectOption) +export function IntersectArcAndArc(arc1: Arc, arc2: Arc, extType: IntersectOption, tolerance = 1e-6) { let pts = IntersectCircleAndCircle(arc1, arc2); - return CheckPointOnCurve(pts, arc1, arc2, extType); + return CheckPointOnCurve(pts, arc1, arc2, extType, tolerance); } -export function IntersectEllipseAndLine(l: Line, el: Ellipse, extType: IntersectOption) +export function IntersectEllipseAndLine(l: Line, el: Ellipse, extType: IntersectOption, tolerance = 1e-6) { let pts = IntersectLineAndEllipseFor2D(l, el); - return CheckPointOnCurve(pts, l, el, extType); + return CheckPointOnCurve(pts, l, el, extType, tolerance); } /** @@ -183,19 +183,19 @@ function IntersectLineAndCircleOrArc(line: Line, circle: Circle | Arc) } //直线和圆 -export function IntersectLineAndCircle(line: Line, circle: Circle, extType: IntersectOption) +export function IntersectLineAndCircle(line: Line, circle: Circle, extType: IntersectOption, tolerance = 1e-6) { let ptArr = IntersectLineAndCircleOrArc(line, circle); return CheckPointOnCurve(ptArr, line, circle, extType | IntersectOption.ExtendArg); } //直线和圆弧 -export function IntersectLineAndArc(line: Line, arc: Arc, extType: IntersectOption) +export function IntersectLineAndArc(line: Line, arc: Arc, extType: IntersectOption, tolerance = 1e-6) { let ptArr = IntersectLineAndCircleOrArc(line, arc); return CheckPointOnCurve(ptArr, line, arc, extType); } //直线和直线 -export function IntersectLAndLFor2D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3): Vector3 +export function IntersectLAndLFor2D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3, tolerance = 1e-6): Vector3 { let dx1 = p1.x - p2.x; let dx2 = p3.x - p4.x; @@ -317,7 +317,7 @@ export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOptio return [pt]; } -export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: IntersectOption): Vector3[] +export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: IntersectOption, tolerance = 1e-6): Vector3[] { let cus: Curve[] = pl.Explode(); let cus2: Curve[]; @@ -349,7 +349,7 @@ export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: Inte if ((cu instanceof Polyline && cu.CloseMark) || !(isStart2 || isEnd2)) ext = ext & ~IntersectOption.ExtendArg; - let ipts = cu1.IntersectWith(cu2, ext).filter(p1 => pts.every(p2 => !equalv3(p1, p2))); + let ipts = cu1.IntersectWith(cu2, ext, tolerance).filter(p1 => pts.every(p2 => !equalv3(p1, p2))); //校验延伸 if (IntersectOption.ExtendThis & ext) diff --git a/utils/testBoolPerformance.ts b/utils/testBoolPerformance.ts new file mode 100644 index 000000000..e75e4c768 --- /dev/null +++ b/utils/testBoolPerformance.ts @@ -0,0 +1,70 @@ + +import * as fs from "fs"; +import * as path from "path"; +import { LoadRegionsFromFileData } from "../__test__/Utils/LoadEntity.util"; +import { Region } from "../src/DatabaseServices/Region"; +import { BoolOpeartionType } from "../src/GraphicsSystem/BoolOperateUtils"; + +function a(testfile: string) +{ + testfile = path.resolve(__dirname, testfile); + let stream = fs.createReadStream(testfile); + + let remaining = ""; + stream.on("data", function (data: string) + { + remaining += data; + let index = remaining.indexOf('\n'); + while (index > -1) + { + let line = remaining.substring(0, index); + remaining = remaining.substring(index + 1); + gg(line); + index = remaining.indexOf('\n'); + } + + + }); + + stream.on('end', function () + { + console.log(JSON.stringify(datas)); + stream.close(); + }); +} + + +function testBool(regs: Region[]) +{ + console.time(); + regs[0].Clone().BooleanOper(regs[1].Clone(), BoolOpeartionType.Intersection); + regs[0].Clone().BooleanOper(regs[1].Clone(), BoolOpeartionType.Subtract); + regs[0].Clone().BooleanOper(regs[1].Clone(), BoolOpeartionType.Union); + console.timeEnd(); +} + +let datas = []; + +function gg(d: string) +{ + d = d.trimLeft(); + try + { + if (d[0] === "[") + { + + let data = JSON.parse(d); + let regs = LoadRegionsFromFileData(data); + // testBool(regs); + + datas.push(d); + } + } + catch (error) + { + + } +} + + +a("../__test__/Booloperate/bool2.test.ts");