diff --git a/__test__/Polyline/offset.test.ts b/__test__/Polyline/offset.test.ts index 69421a258..d95040cab 100644 --- a/__test__/Polyline/offset.test.ts +++ b/__test__/Polyline/offset.test.ts @@ -447,4 +447,152 @@ describe("闭合多段线", () => expect(cus[0].GetOffsetCurves(i).length).toBe(0); } }) + +}) +describe("补圆弧测试", () => +{ + test("补圆弧测试1", () => + { + let data = + [1, ["Polyline", 1, 1, 8815, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 5, [-99.60068327971061, 80.69599512140186], 0, [-48.362234971168355, 80.69599512140186], -0.9874208089640422, [-14.972250883848176, 88.46675505445091], -1.1745224194600496, [18.29631507951812, 78.51046889023182], 0, [89.44733571649859, 78.5104688902318], 0, false]]; + let cus = loadFile(data); + // 向上- + // 向下+ + expect(cus[0].GetOffsetCurves(17.45).length).toBe(2); + for (let i = -55; i <= 55; i++) + { + if (i === 0) continue; + expect(cus[0].GetOffsetCurves(i).length).toBe(1); + } + }) + test("补圆弧测试2", () => + { + let data = + [1, ["Polyline", 1, 1, 12266, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 5, [-869.4193524531552, -50.92359793870933], 0, [-609.861025770732, -50.92359793870939], -0.8167984427288847, [-480.7149315189898, -23.068558002059024], -1.4042575072434897, [-317.9835774160859, -50.92359793870939], 0, [-92.77019349218811, -50.92359793870939], 0, false]]; + let cus = loadFile(data); + // 向上- + // 向下+ + expect(cus[0].GetOffsetCurves(83.24).length).toBe(2); + expect(cus[0].GetOffsetCurves(86.46).length).toBe(2); + for (let i = 364; i <= 395; i++) + { + expect(cus[0].GetOffsetCurves(i).length).toBe(1); + } + }) + test("补圆弧测试3", () => + { + let data = + [1, ["Polyline", 1, 1, 12272, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [-894.3165541673695, -331.80629190023], 0, [-671.3300245231958, -331.80629190023], -1.0058680701224356, [-535.7124860261546, -329.1982623137485], 0, [-214.92484688892245, -329.1982623137485], 0, false]]; + let cus = loadFile(data); + // 向上- + // 向下+ + expect(cus[0].GetOffsetCurves(-1200).length).toBe(1); + for (let i = 63; i <= 94; i++) + { + expect(cus[0].GetOffsetCurves(i).length).toBe(1); + } + }) + test("补圆弧测试3", () => + { + let data = + [1, ["Polyline", 1, 1, 195, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 23, [-25.572010711696727, -62.383195892823124], 0, [-10.312959798454724, -40.55427583637971], 0, [0.28360333574111785, -55.81332674962171], 0, [9.820510156517361, -48.18380129300071], 0, [18.721623189241864, -65.13830230771404], 0, [29.530117586121616, -60.47581452866788], 0, [39.06702440689787, -79.97349069558823], 0, [51.78290016793288, -70.64851513749588], -0.6227891115113805, [70.85671380948538, -80.60928448363998], 0.3759603135798005, [86.75155851077912, -99.68309812519247], -1.1383492019405204, [81.45327694368122, -117.6972554533254], 0.6271394112393051, [57.2931129977147, -138.2545879336653], -1.2933960333754264, [21.68866086681669, -138.2545879336653], -0.8106183277649434, [-17.73055399239181, -132.9563063665674], 0, [-43.37423677714574, -105.82910474302606], 0, [-51.003762233766736, -83.5763221612148], 0, [-48.67251834424364, -64.07864599429448], 0, [-62.65998168138215, -50.09118265715597], 0, [-86.39628310198083, -65.35023357039795], 0, [-86.39628310198083, -33.13668164244262], 0, [-73.68040734094582, -13.639005475522275], 0, [-43.16230551446182, -13.639005475522275], 0, [-33.62539869368556, -11.307761585999202], 0, false]]; + let cus = loadFile(data); + // 向外- + // 向内+ + expect(cus[0].GetOffsetCurves(18).length).toBe(3); + for (let i = 50; i <= 80; i += 5) + { + expect(cus[0].GetOffsetCurves(-i).length).toBe(1); + } + //FIXME:没清理干净 + // expect(cus[0].GetOffsetCurves(27.3).length).toBe(1); + }) + test("补圆弧测试3", () => + { + let data = + [1, ["Polyline", 1, 1, 3, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 10, [-5.637393767705383, -1.586402266288952], 0, [-0.84985835694051, 1.954674220963173], -0.5207626681247078, [1.728045325779038, 1.0906515580736542], -1.2136457904456304, [4.060938624362605, 1.3838754084985838], -1.0694858869096764, [6.891142200566573, -0.047681051558073895], -1.4716493502287318, [9.178341602266286, -2.976612659490083], -1.5003222663355726, [8.09233325325779, -7.040916632294616], -0.9628743606456998, [4.53257790368272, -7.478753541076488], -1.076087427994497, [2.3229461756373926, -7.478753541076488], 0, [-5.39660056657224, -7.478753541076487], 0, false]]; + let cus = loadFile(data); + // 向外- + // 向内+ + expect(cus[0].GetOffsetCurves(1.88).length).toBe(2); + expect(cus[0].GetOffsetCurves(2.12).length).toBe(2); + expect(cus[0].GetOffsetCurves(3.2).length).toBe(1); + for (let i = 0.5; i <= 3.5; i += 0.5) + { + expect(cus[0].GetOffsetCurves(-i).length).toBe(1); + } + for (let i = 3.3; i <= 5.3; i += 0.5) + { + expect(cus[0].GetOffsetCurves(i).length).toBe(0); + } + for (let i = 2.33; i <= 3.2; i += 0.2) + { + expect(cus[0].GetOffsetCurves(i).length).toBe(1); + } + }) +}) + +describe("不规则不闭合多段线测试", () => +{ + test("test1", () => + { + let data = + [1, ["Polyline", 1, 1, 3135, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 6, [16.034190840579708, -16.545186318840567], 0, [36.985943188405784, -16.545186318840567], 0, [31.311510260869554, -12.507609043478254], 0, [48.334809043478245, -12.507609043478254], 0, [43.969860637681144, -16.6543100289855], 0, [56.84645843478259, -16.654310028985503], 0, false]]; + let cus = loadFile(data); + for (let i = 1.27; i <= 2.96; i += 0.2) + { + expect(cus[0].GetOffsetCurves(i).length).toBe(2); + } + expect(cus[0].GetOffsetCurves(9.16).length).toBe(2); + for (let i = 0.5; i <= 7.5; i++) + { + expect(cus[0].GetOffsetCurves(-i).length).toBe(1); + } + + }) + test("test2", () => + { + let data = + [1, ["Polyline", 1, 1, 8814, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 7, [15.642409533480423, -31.01626057276902], 0, [38.129771973149346, -31.016260572769028], 0, [32.85929640135194, -26.50707591689791], 0, [47.440945483324754, -26.50707591689791], 0, [45.33685543194063, -31.016260572769028], 0, [61.52187596164093, -31.016260572769035], 0, [70.31099992504923, -35.88209931313313], 0, false]]; + let cus = loadFile(data); + for (let i = 1.82; i <= 3.37; i += 0.3) + { + expect(cus[0].GetOffsetCurves(i).length).toBe(2); + } + expect(cus[0].GetOffsetCurves(18).length).toBe(2); + for (let i = 1; i <= 27; i += 5) + { + expect(cus[0].GetOffsetCurves(-i).length).toBe(1); + } + + }) + test("test3", () => + { + let data = + [1, ["Polyline", 1, 1, 4308, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 5, [-41.52354973772388, -163.989590203395], 0, [-41.5235497377239, -231.3399374277236], 0, [21.016058399152634, -231.3399374277236], 0, [21.016058399152623, -294.68133541250876], 1.378670046466899, [261.5530127717545, -216.10593031745873], 0, false]]; + let cus = loadFile(data); + for (let i = -100; i <= 181; i += 30) + { + expect(cus[0].GetOffsetCurves(i).length).toBe(1); + } + expect(cus[0].GetOffsetCurves(-122.6).length).toBe(2); + }) + test("test4", () => + { + let data = + [1, ["Polyline", 1, 1, 14565, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -131.50093441946296, -806.1569163328921, 0, 1], 2, 24, [256.5228611988947, -38.705370748164505], 0, [372.1955588024039, 31.844231195771492], 0, [372.1955588024039, -31.54297461172431], 0, [450.9819163032461, 37.57414810492366], 0, [423.0485713711294, -54.10452244151095], 0, [589.216161736542, 52.97329979827009], 0, [611.0614699526845, -2.177150452319474], 0, [672.6580767260702, 61.21005535517633], 0, [678.0298738284004, 13.938240854670997], 0, [735.329042919922, 21.100636991111184], 0, [684.1179105443746, -21.515620020708024], 0, [730.6734854312358, -32.61733403219032], 0, [815.1897598412304, 38.29038771856768], 0, [835.6025888300849, -8.981426781937659], 0, [862.1034545349137, 74.4604882075907], 0, [943.4539498526012, 74.46048820759069], 0, [986.972668777612, -29.064785548515978], 0, [924.5022496755805, -66.26627108118637], 0, [1001.0109652050348, -106.27541589934134], 0, [965.9152241364777, -128.73669018321777], 0, [1006.6262837760039, -176.46689803645526], 0, [904.1467198558175, -189.8032796425069], 0, [981.3573502066429, -242.44689124534239], 0, [1004.5205393118904, -256.48518767276516], 0, false]]; + let cus = loadFile(data); + for (let i = 50; i <= 250; i += 50) + { + expect(cus[0].GetOffsetCurves(-i).length).toBe(1); + } + expect(cus[0].GetOffsetCurves(46.8).length).toBe(2); + expect(cus[0].GetOffsetCurves(49.6).length).toBe(3); + expect(cus[0].GetOffsetCurves(86.6).length).toBe(2); + expect(cus[0].GetOffsetCurves(102.3).length).toBe(2); + for (let i = 110; i <= 200; i += 30) + { + expect(cus[0].GetOffsetCurves(i).length).toBe(1); + } + }) }) diff --git a/src/DatabaseServices/Circle.ts b/src/DatabaseServices/Circle.ts index c55b4d7ae..8a5ada845 100644 --- a/src/DatabaseServices/Circle.ts +++ b/src/DatabaseServices/Circle.ts @@ -134,7 +134,7 @@ export class Circle extends Curve { let sa = anglelist[i]; let ea = anglelist[i + 1]; - if (!equaln(sa, ea)) + if (!equaln(sa, ea, 1e-6)) { let arc = new Arc(new Vector3(), this.m_Radius, sa, ea); arc.ApplyMatrix(this.OCS); diff --git a/src/GraphicsSystem/OffestPolyline.ts b/src/GraphicsSystem/OffestPolyline.ts index 428b22a9e..22d108009 100644 --- a/src/GraphicsSystem/OffestPolyline.ts +++ b/src/GraphicsSystem/OffestPolyline.ts @@ -46,7 +46,7 @@ export class PolyOffestUtil // console.time("join") this.TrimAndBuildContour(offres); - for (let i = 0, count = this.m_Polyline.EndParam; i < count; i++) + for (let i = 0, count = this.m_Polyline.EndParam; i <= count; i++) { if (i === count && this.m_Polyline.IsClose) { @@ -73,22 +73,6 @@ export class PolyOffestUtil // this.m_RetCurves.push(...this.m_Contours.map(c => c.Outline)) return this.m_RetCurves; } - - /** - * 校验点是合法的偏移后曲线的点. - * - * 判断依据是:点距离源线段的距离必须大于偏移距离. - * - * @private - * @param {Vector3} pt - * @memberof PolyOffestUtil - */ - private CheckPointDist(pt: Vector3): boolean - { - let closePt = this.m_Polyline.GetClosestPointTo(pt, false); - let dis = closePt.distanceToSquared(pt); - return dis + 1e-2 > this.m_dist2; - } private CheckPointDir(pt: Vector3) { let dir = GetPointAtCurveDir(this.m_Polyline, pt) ? 1 : -1; @@ -104,10 +88,23 @@ export class PolyOffestUtil if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0) return false; //删除在反方向的无效线段 - return this.CheckPointDir(c.GetPointAtParam(0.5)); + return this.CheckPointDir(c.StartPoint) || this.CheckPointDir(c.EndPoint); }); - //处理自交的线段 + + //处理自交的线段,先根据包围盒排序 + outputCus.sort((e1, e2) => + { + let b1 = boxCurves.get(e1); + let b2 = boxCurves.get(e2); + if (!equaln(b1.min.x, b2.min.x)) + return b1.min.x - b2.min.x; + else + { + return b2.min.y - b1.min.y; + } + }) + let count = outputCus.length; for (let i = 0; i < count; i++) { @@ -126,9 +123,30 @@ export class PolyOffestUtil if (c2b.min.y > c1b.max.y) continue; - //如果线段端点相连,不计算 + //如果线段端点相连,且交点不是端点,那就是2条共线的直线,删掉短的被包含的那条 let isLink = [c1.StartPoint, c1.EndPoint].some(p => equal(p, c2.StartPoint) || equal(p, c2.EndPoint)); - if (isLink) continue; + if (isLink) + { + if (c1 instanceof Arc || c2 instanceof Arc) continue; + let pts = c1.IntersectWith(c2, IntersectOption.OnBothOperands); + if (pts.length === 1 && !(equal(pts[0], c2.StartPoint) || equal(pts[0], c2.EndPoint))) + { + if (c1.Length > c2.Length) + { + outputCus.splice(j, 1); + j--; + count--; + } + else + { + outputCus.splice(i, 1); + i--; + count--; + break; + } + } + continue; + } let pts = c1.IntersectWith(c2, IntersectOption.OnBothOperands); if (pts.length > 0) @@ -548,7 +566,7 @@ export class PolyOffestUtil private trimByContours(needCutCus: Curve[]) { let boxContours = SortEntityByBox(this.m_Contours, false); - let boxCurves = SortEntityByBox(needCutCus, true); + let boxCurves = SortEntityByBox(needCutCus, false); this.m_Contours.forEach(c => { let tmpCus: Curve[] = []; diff --git a/wallaby.conf.js b/wallaby.conf.js index fee567cba..a34327f6e 100644 --- a/wallaby.conf.js +++ b/wallaby.conf.js @@ -1,5 +1,4 @@ - -export default function (wallaby) +module.exports = function (wallaby) { return { delays: {