diff --git a/__test__/Polyline/__snapshots__/offset3.test.ts.snap b/__test__/Polyline/__snapshots__/offset3.test.ts.snap new file mode 100644 index 000000000..05b5ac47e --- /dev/null +++ b/__test__/Polyline/__snapshots__/offset3.test.ts.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`圆弧被压扁时 1`] = `1`; + +exports[`圆弧被压扁时 2`] = `"1260.08305"`; diff --git a/__test__/Polyline/offset.test.ts b/__test__/Polyline/offset.test.ts index 73603cc57..f8cdf25e5 100644 --- a/__test__/Polyline/offset.test.ts +++ b/__test__/Polyline/offset.test.ts @@ -21,7 +21,7 @@ function EntityToMatchSnapshot(ens: Curve[]) } } -function testOffset(pl: Curve, dis) +function testOffset(pl: Curve, dis: number) { let cus = pl.GetOffsetCurves(dis); EntityToMatchSnapshot(cus); diff --git a/__test__/Polyline/offset3.test.ts b/__test__/Polyline/offset3.test.ts new file mode 100644 index 000000000..7d384d99e --- /dev/null +++ b/__test__/Polyline/offset3.test.ts @@ -0,0 +1,36 @@ +import { Factory } from "../../src/DatabaseServices/CADFactory"; +import { Curve } from "../../src/DatabaseServices/Entity/Curve"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; +import "../Utils/jest.util"; +import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; + +Factory(Polyline); + +function loadFile(data) +{ + return LoadEntityFromFileData(data) as Curve[]; +} + +function EntityToMatchSnapshot(ens: Curve[]) +{ + expect(ens.length).toMatchSnapshot(); + for (let c of ens) + { + expect(c.Length).toMatchNumberSnapshot(); + } +} + +function testOffset(pl: Curve, dis: number) +{ + let cus = pl.GetOffsetCurves(dis); + EntityToMatchSnapshot(cus); +} + +test('圆弧被压扁时', () => +{ + let pl = loadFile( + { "file": [1, "Polyline", 8, 2, 154, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 377.4539113436276, 1247.0593462341237, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 6, [0, 0], 0, [19.763395114298646, 0], 0, [19.763395114298646, -77.16333081989751], 0, [620.8495708336222, 2], 0, [12.422828246409608, 2], 0.07998201834820468, [0, 0], 0, false], "basePt": { "x": 377.4539113436276, "y": 1169.8960154142262, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] } + )[0] as Polyline; + + testOffset(pl, -1); +}); diff --git a/src/GraphicsSystem/OffsetPolyline.ts b/src/GraphicsSystem/OffsetPolyline.ts index de7e0ca59..8963b5065 100644 --- a/src/GraphicsSystem/OffsetPolyline.ts +++ b/src/GraphicsSystem/OffsetPolyline.ts @@ -10,7 +10,7 @@ import { Curve } from "../DatabaseServices/Entity/Curve"; import { Line } from "../DatabaseServices/Entity/Line"; import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { IntersectsBox } from "../Geometry/Box"; -import { CurveMap, Vertice, Route } from "../Geometry/CurveMap"; +import { CurveMap, Route, Vertice } from "../Geometry/CurveMap"; import { angle, equaln, equalv2, equalv3, IdentityMtx4, SelectNearP } from "../Geometry/GeUtils"; import { SortEntityByBox } from "../Geometry/SortEntityByBox"; import { IntersectOption } from "../GraphicsSystem/IntersectWith"; @@ -388,6 +388,19 @@ export class OffsetPolyline } if (d.sp) cu2.StartPoint = d.sp; if (d.ep) cu2.EndPoint = d.ep; + + //这是极端情况,圆弧被压缩成0长度圆弧,本质是空圆弧(我们会在下面判断它)(因为精度的问题) + //因为精度的问题,这种0圆心角的圆弧会被当成全圆,但是偏移算法中,应该不可能出现全圆弧的圆弧,所以我们压扁它 + if (cu2 instanceof Arc + && equaln(cu2.StartAngle, cu2.EndAngle, 1e-6) + // && !equaln((this._SubCurves[d.index]).AllAngle, Math.PI * 2, 1e-3) 应该不会出现 + ) + { + if (cu2.IsClockWise) + cu2.StartAngle = cu2.EndAngle + 1e-6; + else + cu2.EndAngle = cu2.StartAngle + 1e-6; + } } for (let d of this._SubOffsetedCurves) { @@ -456,7 +469,7 @@ export class OffsetPolyline if (l1Intact && d.preArc && d.preArc instanceof Arc) { let a = d.preArc; - if (Math.sign(a.Bul) !== this._OffsetDistSign) + if (Math.sign(a.Bul) !== this._OffsetDistSign && a.AllAngle > 1e-6) { let ipts = a.IntersectWith(l1, IntersectOption.OnBothOperands); if (ipts.length === 2) @@ -471,7 +484,7 @@ export class OffsetPolyline if (l2Intact && d.nextArc && d.nextArc instanceof Arc) { let a = d.nextArc; - if (Math.sign(a.Bul) !== this._OffsetDistSign) + if (Math.sign(a.Bul) !== this._OffsetDistSign && a.AllAngle > 1e-6) { let ipts = a.IntersectWith(l2, IntersectOption.OnBothOperands); if (ipts.length === 2)