修复:偏移算法,在圆弧被压成0长度圆弧时,精度问题导致的圆弧变成全圆,从而导致偏移错误

pull/1218/MERGE
ChenX 4 years ago
parent a661b57c2e
commit f4136f846c

@ -0,0 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`圆弧被压扁时 1`] = `1`;
exports[`圆弧被压扁时 2`] = `"1260.08305"`;

@ -21,7 +21,7 @@ function EntityToMatchSnapshot(ens: Curve[])
} }
} }
function testOffset(pl: Curve, dis) function testOffset(pl: Curve, dis: number)
{ {
let cus = pl.GetOffsetCurves(dis); let cus = pl.GetOffsetCurves(dis);
EntityToMatchSnapshot(cus); EntityToMatchSnapshot(cus);

@ -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);
});

@ -10,7 +10,7 @@ import { Curve } from "../DatabaseServices/Entity/Curve";
import { Line } from "../DatabaseServices/Entity/Line"; import { Line } from "../DatabaseServices/Entity/Line";
import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { IntersectsBox } from "../Geometry/Box"; 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 { angle, equaln, equalv2, equalv3, IdentityMtx4, SelectNearP } from "../Geometry/GeUtils";
import { SortEntityByBox } from "../Geometry/SortEntityByBox"; import { SortEntityByBox } from "../Geometry/SortEntityByBox";
import { IntersectOption } from "../GraphicsSystem/IntersectWith"; import { IntersectOption } from "../GraphicsSystem/IntersectWith";
@ -388,6 +388,19 @@ export class OffsetPolyline
} }
if (d.sp) cu2.StartPoint = d.sp; if (d.sp) cu2.StartPoint = d.sp;
if (d.ep) cu2.EndPoint = d.ep; if (d.ep) cu2.EndPoint = d.ep;
//这是极端情况,圆弧被压缩成0长度圆弧,本质是空圆弧(我们会在下面判断它)(因为精度的问题)
//因为精度的问题,这种0圆心角的圆弧会被当成全圆,但是偏移算法中,应该不可能出现全圆弧的圆弧,所以我们压扁它
if (cu2 instanceof Arc
&& equaln(cu2.StartAngle, cu2.EndAngle, 1e-6)
// && !equaln((<Arc>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) for (let d of this._SubOffsetedCurves)
{ {
@ -456,7 +469,7 @@ export class OffsetPolyline
if (l1Intact && d.preArc && d.preArc instanceof Arc) if (l1Intact && d.preArc && d.preArc instanceof Arc)
{ {
let a = d.preArc; 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); let ipts = a.IntersectWith(l1, IntersectOption.OnBothOperands);
if (ipts.length === 2) if (ipts.length === 2)
@ -471,7 +484,7 @@ export class OffsetPolyline
if (l2Intact && d.nextArc && d.nextArc instanceof Arc) if (l2Intact && d.nextArc && d.nextArc instanceof Arc)
{ {
let a = d.nextArc; 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); let ipts = a.IntersectWith(l2, IntersectOption.OnBothOperands);
if (ipts.length === 2) if (ipts.length === 2)

Loading…
Cancel
Save