diff --git a/__test__/Polyline/__snapshots__/offset.test.ts.snap b/__test__/Polyline/__snapshots__/offset.test.ts.snap index 1379bcec8..22b0c818b 100644 --- a/__test__/Polyline/__snapshots__/offset.test.ts.snap +++ b/__test__/Polyline/__snapshots__/offset.test.ts.snap @@ -310,3 +310,21 @@ Array [ ], ] `; + +exports[`简单图形因为点在线内算法错误导致的丢失 1`] = `8.675026988029915`; + +exports[`简单图形因为点在线内算法错误导致的丢失 2`] = `8.252659494518674`; + +exports[`简单图形因为点在线内算法错误导致的丢失 3`] = `6.802593049888034`; + +exports[`简单图形因为点在线内算法错误导致的丢失 4`] = `6.045525633131274`; + +exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 1`] = `54789.14760701891`; + +exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 2`] = `54907.17933624483`; + +exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 3`] = `55497.39792073307`; + +exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 4`] = `56678.13326318633`; + +exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 5`] = `57859.26303559798`; diff --git a/__test__/Polyline/offset.test.ts b/__test__/Polyline/offset.test.ts index 9cff50ee8..e18f0d4cc 100644 --- a/__test__/Polyline/offset.test.ts +++ b/__test__/Polyline/offset.test.ts @@ -777,3 +777,40 @@ test('土偏移因为点在圆弧切线上错误导致的丢失', () => cus = pl.GetOffsetCurves(801); expect(cus.length).toBe(1); }); + +//ISSUE #IKSMH +test('闭合多段线判断精度和重复交点参数导致偏移丢失', () => +{ + let f = new CADFile(); + f.Data = + [1, ["Polyline", 1, 1, 3, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.042016806722689815, 0.028011204481792618, 0, 1], 2, 11, [15758.920914649752, -1642.832074394305], 1.1432358165627696, [15758.920914649756, -3551.5797508523133], 0.010240353549940432, [20850.68748853413, -2761.478041111637], 0.39873042440013945, [23564.17781148077, 901.7338948663096], 0.029927117999965277, [22452.27083112051, 6973.8467189556395], 0, [31778.947378692996, 6973.846718955635], 0, [31327.636369627562, 7575.594679533537], 0, [31646.066893308867, 7787.881806674935], 0, [20955.832135358123, 7787.881806674936], 0, [21703.795934364476, 5637.485884531684], -0.559029831351755, [15758.920914649752, -1642.832074394304], 0, false]] + + f.Read(); + let pl = f.ReadObject() as Polyline; + + for (let d of [40, 50, 100, 200, 300]) + { + let cus = pl.GetOffsetCurves(d); + + expect(cus.length).toBe(1); + expect(cus[0].Length).toMatchSnapshot(); + } +}); +//ISSUE #IKSMH +test('简单图形因为点在线内算法错误导致的丢失', () => +{ + let f = new CADFile(); + f.Data = + [1, ["Polyline", 1, 1, 3, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01400560224089542, 0.37815126050420145, 0, 1], 2, 7, [2.075848303393214, 0.09193367302761479], -3.109533447960064, [2.8332320619106284, 1.1077844311377247], 0, [3.542914171656688, 1.1077844311377247], 0, [3.542914171656688, -0.4890219560878247], 0, [2.0758483033932134, -0.4890219560878247], 0, [2.0758483033932134, -0.4890219560878247], 0, [2.0758483033932134, 0.09193367302761501], 0, false]] + + f.Read(); + let pl = f.ReadObject() as Polyline; + + for (let d of [0.2, 0.3, 0.4, 0.5]) + { + let cus = pl.GetOffsetCurves(d); + + expect(cus.length).toBe(1); + expect(cus[0].Length).toMatchSnapshot(); + } +}); diff --git a/src/DatabaseServices/PointInPolyline.ts b/src/DatabaseServices/PointInPolyline.ts index b3e4bf2a7..3db858a96 100644 --- a/src/DatabaseServices/PointInPolyline.ts +++ b/src/DatabaseServices/PointInPolyline.ts @@ -1,5 +1,5 @@ import { Vector2, Vector3 } from 'three'; -import { angle, equaln } from '../Geometry/GeUtils'; +import { angle, equaln, equal } from '../Geometry/GeUtils'; import { IntersectOption } from '../GraphicsSystem/IntersectWith'; import { Arc } from './Arc'; import { Line } from './Line'; @@ -108,33 +108,45 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean } else //圆弧 { - let arc = pl.GetCurveAtIndex(i); + let arc = pl.GetCurveAtIndex(i) as Arc; let sp = arc.StartPoint; let ep = arc.EndPoint; - //当点和起点或者终点和点相切时 - if (equaln(sp.x, pt.x) && sp.y > pt.y) + //如果相切 + if (equaln(Math.abs(pt.x - arc.Center.x), arc.Radius)) { - let der = arc.GetFistDeriv(0); - if (equaln(der.x, 0)) + //当点和起点或者终点和点相切时 + if (equaln(sp.x, pt.x) && sp.y > pt.y) { - if (ep.x - sp.x < 0) crossings++; - continue; + if (ep.x - sp.x < -1e-5) + crossings++; + } + else if (equaln(ep.x, pt.x) && ep.y > pt.y) + { + if (ep.x - sp.x > 1e-5) + crossings++; } + continue; + } + + if (equaln(sp.x, pt.x) && sp.y > pt.y) + { + let der = arc.GetFistDeriv(0); + if (der.x < -1e-5) + crossings++; } if (equaln(ep.x, pt.x) && ep.y > pt.y) { let der = arc.GetFistDeriv(1); - if (equaln(der.x, 0)) - { - if (ep.x - sp.x > 0) crossings++; - continue; - } + if (der.x > 1e-5) + crossings++; } + for (let pti of arc.IntersectWith(insLine, IntersectOption.ExtendArg)) { - if (pti.y < pt.y) + if (pti.y < pt.y || equal(sp, pti) || equal(ep, pti)) continue; + let der = arc.GetFistDeriv(pti); if (!equaln(der.x, 0)) //相切. crossings++; diff --git a/src/DatabaseServices/Polyline.ts b/src/DatabaseServices/Polyline.ts index a3f022fb9..78b8cd86d 100644 --- a/src/DatabaseServices/Polyline.ts +++ b/src/DatabaseServices/Polyline.ts @@ -243,7 +243,7 @@ export class Polyline extends Curve //曲线是否闭合 get IsClose(): boolean { - return this.CloseMark || equal(this.StartPoint, this.EndPoint); + return this.CloseMark || equal(this.StartPoint, this.EndPoint, 1e-5); } set CloseMark(v: boolean) { diff --git a/src/Geometry/CurveMap.ts b/src/Geometry/CurveMap.ts index 71a9c8bda..6c43cb2ea 100644 --- a/src/Geometry/CurveMap.ts +++ b/src/Geometry/CurveMap.ts @@ -72,7 +72,7 @@ export class CurveMap */ private GenerateP(v: Vector3): Vector3 { - let str = v.toArray().map(v => v.toFixed(4)).join(","); + let str = v.toArray().map(v => v.toFixed(3)).join(","); if (this.m_vecMap.has(str)) return this.m_vecMap.get(str); this.m_vecMap.set(str, v); diff --git a/src/GraphicsSystem/OffsetPolyline.ts b/src/GraphicsSystem/OffsetPolyline.ts index ba4c768d2..3355babc4 100644 --- a/src/GraphicsSystem/OffsetPolyline.ts +++ b/src/GraphicsSystem/OffsetPolyline.ts @@ -1,5 +1,5 @@ import { Box3, Vector3 } from "three"; -import { arrayLast, arrayRemoveIf, arraySortByNumber } from "../Common/ArrayExt"; +import { arrayLast, arrayRemoveDuplicateBySort, arrayRemoveIf, arraySortByNumber } from "../Common/ArrayExt"; import { curveLinkGroup, GetPointAtCurveDir } from "../Common/CurveUtils"; import { FixIndex } from "../Common/Utils"; import { Arc } from "../DatabaseServices/Arc"; @@ -638,6 +638,7 @@ export class PolyOffsetUtil let iParams = l.IntersectWith(outline, IntersectOption.OnBothOperands) .map(p => l.GetParamAtPoint(p)); arraySortByNumber(iParams); + arrayRemoveDuplicateBySort(iParams, equaln); //需要计算的点列表 let needCaclPts: Vector3[] = [];