diff --git a/__test__/Geometry/__snapshots__/intersect.test.ts.snap b/__test__/Geometry/__snapshots__/intersect.test.ts.snap index 5fdbadd8f..d845fd6a5 100644 --- a/__test__/Geometry/__snapshots__/intersect.test.ts.snap +++ b/__test__/Geometry/__snapshots__/intersect.test.ts.snap @@ -65,12 +65,12 @@ exports[`三维空间圆圆相交测试 5`] = `Array []`; exports[`三维空间直线和圆相交测试 1`] = ` Array [ Vector3 { - "x": 7.265045456946408, + "x": 7.265045456946406, "y": 0, - "z": 1.514708484572001, + "z": 1.5147084845720027, }, Vector3 { - "x": 3.93574588263578, + "x": 3.9357458826357803, "y": 0, "z": 4.789429377336553, }, @@ -86,7 +86,7 @@ Array [ }, Vector3 { "x": -3.622627029705464, - "y": 3.4462404738566006, + "y": 3.446240473856601, "z": 0, }, ] @@ -101,7 +101,7 @@ Array [ }, Vector3 { "x": 9.796270630192113, - "y": -6.270573611488618, + "y": -6.270573611488619, "z": 4.841809080303142, }, ] @@ -111,12 +111,12 @@ exports[`三维空间直线和圆相交测试 4`] = ` Array [ Vector3 { "x": 12.384261138056765, - "y": -13.163054559201814, + "y": -13.16305455920182, "z": 6.346016491847222, }, Vector3 { "x": 12.384261138056765, - "y": -6.270573611488626, + "y": -6.27057361148862, "z": 6.346016491847221, }, ] diff --git a/__test__/Polyline/Intersect.test.ts b/__test__/Polyline/Intersect.test.ts index 7ccc0c2fa..d564f75b0 100644 --- a/__test__/Polyline/Intersect.test.ts +++ b/__test__/Polyline/Intersect.test.ts @@ -105,7 +105,7 @@ describe("相交", () => let pts3 = pl.IntersectWith(p2, IntersectOption.ExtendArg); expect(pts3.length).toBe(1); let pts4 = pl.IntersectWith(p3, IntersectOption.OnBothOperands); - expect(pts4[1]).toEqual(new Vector3(2.5, 2.5, 0)) + expect(pts).toMatchSnapshot(); expect(pts4.length).toBe(2); let pts5 = pl.IntersectWith(p4, IntersectOption.OnBothOperands); expect(pts5.length).toBe(1); diff --git a/__test__/Polyline/__snapshots__/Intersect.test.ts.snap b/__test__/Polyline/__snapshots__/Intersect.test.ts.snap new file mode 100644 index 000000000..7f956c01e --- /dev/null +++ b/__test__/Polyline/__snapshots__/Intersect.test.ts.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`相交 相交曲线 1`] = ` +Array [ + Vector3 { + "x": 2.4915763650480898, + "y": 2.294945819028854, + "z": 0, + }, +] +`; diff --git a/__test__/Polyline/__snapshots__/offset.test.ts.snap b/__test__/Polyline/__snapshots__/offset.test.ts.snap index 03661d405..46a71b6dc 100644 --- a/__test__/Polyline/__snapshots__/offset.test.ts.snap +++ b/__test__/Polyline/__snapshots__/offset.test.ts.snap @@ -2,19 +2,19 @@ exports[`IKKGK圆与直线补圆弧 1`] = `1`; -exports[`IKKGK圆与直线补圆弧 2`] = `44.998097679646904`; +exports[`IKKGK圆与直线补圆弧 2`] = `44.99809767964709`; exports[`IKKGK圆与直线补圆弧 3`] = `1`; -exports[`IKKGK圆与直线补圆弧 4`] = `44.998097679647046`; +exports[`IKKGK圆与直线补圆弧 4`] = `44.99809767964709`; exports[`IKKGK圆与直线补圆弧 5`] = `1`; -exports[`IKKGK圆与直线补圆弧 6`] = `52.52605376818708`; +exports[`IKKGK圆与直线补圆弧 6`] = `52.52605376818707`; exports[`中间区域需要圆裁剪 1`] = `1`; -exports[`中间区域需要圆裁剪 2`] = `24.711300177428036`; +exports[`中间区域需要圆裁剪 2`] = `24.711300177432392`; exports[`圆求交错误导致的线丢失 1`] = `4148.643109243218`; @@ -30,7 +30,15 @@ exports[`圆求交错误导致的线丢失 6`] = `4757.455448859379`; exports[`圆求交错误导致的线丢失 7`] = `3783.7370117939813`; -exports[`圆求交错误导致的线丢失 8`] = `4971.999047743294`; +exports[`圆求交错误导致的线丢失 8`] = `4971.999047743349`; + +exports[`多段线存在0长度线段导致偏移错误 1`] = `1`; + +exports[`多段线存在0长度线段导致偏移错误 2`] = `81933.49238918608`; + +exports[`多段线存在0长度线段导致偏移错误 3`] = `1`; + +exports[`多段线存在0长度线段导致偏移错误 4`] = `86143.95799639553`; exports[`拱门偏移 1`] = `1`; @@ -48,13 +56,13 @@ exports[`简单图形因为点在线内算法错误导致的丢失 3`] = `6.8025 exports[`简单图形因为点在线内算法错误导致的丢失 4`] = `6.045525633131274`; -exports[`补充bug测试 1`] = `7385.097729437721`; +exports[`补充bug测试 1`] = `7385.097729441212`; -exports[`补充bug测试 2`] = `7455.833952762051`; +exports[`补充bug测试 2`] = `7455.833952762297`; exports[`补圆弧测试 补圆弧测试1 1`] = `1`; -exports[`补圆弧测试 补圆弧测试1 2`] = `202.39234999237357`; +exports[`补圆弧测试 补圆弧测试1 2`] = `202.39234999237365`; exports[`补圆弧测试 补圆弧测试1 3`] = `1`; @@ -62,7 +70,7 @@ exports[`补圆弧测试 补圆弧测试1 4`] = `202.97100463130596`; exports[`补圆弧测试 补圆弧测试1 5`] = `1`; -exports[`补圆弧测试 补圆弧测试1 6`] = `203.6334701054305`; +exports[`补圆弧测试 补圆弧测试1 6`] = `203.63347010543052`; exports[`补圆弧测试 补圆弧测试1 7`] = `1`; @@ -70,11 +78,11 @@ exports[`补圆弧测试 补圆弧测试1 8`] = `204.40220678622498`; exports[`补圆弧测试 补圆弧测试1 9`] = `1`; -exports[`补圆弧测试 补圆弧测试1 10`] = `205.30911616294793`; +exports[`补圆弧测试 补圆弧测试1 10`] = `205.30911616294782`; exports[`补圆弧测试 补圆弧测试1 11`] = `1`; -exports[`补圆弧测试 补圆弧测试1 12`] = `206.4013429179738`; +exports[`补圆弧测试 补圆弧测试1 12`] = `206.40134291797384`; exports[`补圆弧测试 补圆弧测试1 13`] = `1`; @@ -82,11 +90,11 @@ exports[`补圆弧测试 补圆弧测试1 14`] = `207.75214121305123`; exports[`补圆弧测试 补圆弧测试1 15`] = `1`; -exports[`补圆弧测试 补圆弧测试1 16`] = `209.48307101962268`; +exports[`补圆弧测试 补圆弧测试1 16`] = `209.48307101962263`; exports[`补圆弧测试 补圆弧测试1 17`] = `1`; -exports[`补圆弧测试 补圆弧测试1 18`] = `211.81505991717293`; +exports[`补圆弧测试 补圆弧测试1 18`] = `211.8150599171729`; exports[`补圆弧测试 补圆弧测试1 19`] = `1`; @@ -98,7 +106,7 @@ exports[`补圆弧测试 补圆弧测试1 22`] = `220.89085248936073`; exports[`补圆弧测试 补圆弧测试1 23`] = `1`; -exports[`补圆弧测试 补圆弧测试1 24`] = `243.05075247271324`; +exports[`补圆弧测试 补圆弧测试1 24`] = `243.05075247271327`; exports[`补圆弧测试 补圆弧测试1 25`] = `1`; diff --git a/__test__/Polyline/offset.test.ts b/__test__/Polyline/offset.test.ts index 147d2b346..8e796e83f 100644 --- a/__test__/Polyline/offset.test.ts +++ b/__test__/Polyline/offset.test.ts @@ -26,6 +26,12 @@ function EntityToMatchSnapshot(ens: Curve[]) } } +function testOffset(pl: Curve, dis) +{ + let cus = pl.GetOffsetCurves(dis); + EntityToMatchSnapshot(cus); +} + test('IKKGK圆与直线补圆弧', () => { let f = new CADFile(); @@ -847,5 +853,14 @@ test('补充bug测试', () => cus = pl.GetOffsetCurves(-10); expect(cus.length).toBe(1); expect(cus[0].Length).toMatchSnapshot(); +}) + +test('多段线存在0长度线段导致偏移错误', () => +{ + let pl = loadFile( + [1, ["Polyline", 1, 1, 199, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 9, [18464.40681262459, -261.95809608907166], 0, [23818.6302458671, 7299.349805818285], 0, [34567.94904695702, 3988.7231028210094], 0, [34567.94904695702, 3988.7231028210094], 0, [42946.69564096247, 8484.635909360519], -0.7515576999403787, [50221.90000063549, 1045.9438112678758], -0.43729267560971036, [41557.04986439571, -997.652918977356], -0.5825417553875781, [27905.82370635756, -6760.5956982689095], 0, [19404.461308537397, -2591.658368568635], 0, true]] + )[0]; + testOffset(pl, 400); + testOffset(pl, -400); }); diff --git a/src/Add-on/test/testIntersect.ts b/src/Add-on/test/testIntersect.ts index 7093d40ea..af378e65d 100644 --- a/src/Add-on/test/testIntersect.ts +++ b/src/Add-on/test/testIntersect.ts @@ -15,7 +15,7 @@ export class TestIntersect implements Command // this.testLineAndLine(); // this.testLineAndCirOrArc(); // this.testCirAndCir() - this.testInter(); + // this.testInter(); app.m_Editor.UpdateScreen(); } diff --git a/src/GraphicsSystem/IntersectWith.ts b/src/GraphicsSystem/IntersectWith.ts index 890e2bff4..307f0b9db 100644 --- a/src/GraphicsSystem/IntersectWith.ts +++ b/src/GraphicsSystem/IntersectWith.ts @@ -151,40 +151,28 @@ export function IntersectArcAndArc(arc1: Arc, arc2: Arc, extType: IntersectOptio */ function IntersectLineAndCircleOrArc(line: Line, circle: Circle | Arc) { - let startPoint = line.StartPoint; - let endPoint = line.EndPoint; - let center = circle.Center; - let radius = circle.Radius; - - let a = endPoint.distanceToSquared(startPoint); - if (a == 0) - return []; - - let lineV = endPoint.clone().sub(startPoint); - let lineToCir = startPoint.clone().sub(center); - let b = 2 * lineV.dot(lineToCir); - - let c = center.lengthSq() + startPoint.lengthSq() - 2 * center.dot(startPoint) - radius * radius; - let det = b * b - 4 * a * c; - - if (equaln(det, 0, 1e-4)) + let lineOrg = line.StartPoint; + let lineDirection = line.EndPoint.sub(lineOrg); + let dirLen = lineDirection.length(); + if (dirLen === 0) return []; + lineDirection.divideScalar(dirLen); + + let diff = lineOrg.clone().sub(circle.Center); + let a0 = diff.dot(diff) - circle.Radius ** 2; + let a1 = lineDirection.dot(diff); + let discr = a1 ** 2 - a0; + + if (equaln(discr, 0, 1e-7)) { - let delta = -b / (2 * a); - return [startPoint.add(lineV.multiplyScalar(delta))]; + return [lineOrg.add(lineDirection.multiplyScalar(-a1))]; } - else if (det > 0) + else if (discr > 0) { - let sqrt_det = Math.sqrt(det); - let delta = (-b + sqrt_det) / (2 * a); - let p2 = startPoint.clone().add(lineV.clone().multiplyScalar(delta)); - - delta = (-b - sqrt_det) / (2 * a); - let p3 = startPoint.clone().add(lineV.multiplyScalar(delta)); - - if (!equal(p2, p3, 1e-5)) - return [p2, p3]; - else - return [p2]; + let root = Math.sqrt(discr); + return [ + lineOrg.clone().add(lineDirection.clone().multiplyScalar(-a1 + root)), + lineOrg.add(lineDirection.multiplyScalar(-a1 - root)) + ]; } return []; }