From 2c70166f3c03331a180500dbdc2fdd9851c0cc95 Mon Sep 17 00:00:00 2001 From: ZoeLeeFZ Date: Wed, 30 Oct 2019 09:45:30 +0800 Subject: [PATCH] =?UTF-8?q?!540=20=E5=88=A4=E6=96=AD=E5=A4=9A=E6=AE=B5?= =?UTF-8?q?=E7=BA=BF=E4=B8=BA=E5=87=B8=E8=BE=B9=E5=BD=A2,=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=B5=B0=E5=88=80=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FeedingToolPath.test.ts.snap | 34 ++++---- __test__/Polyline/PolylineBulge.test.ts | 83 +++++++++++++++++++ src/DatabaseServices/Entity/Polyline.ts | 49 +++++++++++ .../ToolPath/FeedingToolPath.ts | 24 ++++-- 4 files changed, 167 insertions(+), 23 deletions(-) create mode 100644 __test__/Polyline/PolylineBulge.test.ts diff --git a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap index 26f45c223..6517d2b06 100644 --- a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap +++ b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap @@ -26,13 +26,13 @@ exports[`刀切到外轮廓情况: 曲线长度 4`] = `1478.9393851461323`; exports[`刀切到外轮廓情况: 曲线长度 5`] = `729.5688477133849`; -exports[`刀切到外轮廓情况: 曲线长度 6`] = `14681.465974109033`; +exports[`刀切到外轮廓情况: 曲线长度 6`] = `7687.426120259669`; -exports[`刀切到外轮廓情况: 曲线长度 7`] = `14658.277022001026`; +exports[`刀切到外轮廓情况: 曲线长度 7`] = `7785.184372611363`; -exports[`刀切到外轮廓情况: 曲线长度 8`] = `14681.465974109033`; +exports[`刀切到外轮廓情况: 曲线长度 8`] = `7687.426120259668`; -exports[`刀切到外轮廓情况: 曲线长度 9`] = `14658.277022000973`; +exports[`刀切到外轮廓情况: 曲线长度 9`] = `7785.184372611338`; exports[`刀切到外轮廓情况: 曲线长度 10`] = `3600`; @@ -52,7 +52,7 @@ exports[`复杂极限刀半径: 曲线长度 3`] = `31170.805670163638`; exports[`复杂极限刀半径: 曲线长度 4`] = `2917.48021978714`; -exports[`复杂极限刀半径: 曲线长度 5`] = `4434.591784188829`; +exports[`复杂极限刀半径: 曲线长度 5`] = `4147.455051522354`; exports[`复杂极限刀半径: 曲线长度 6`] = `4356.840832388074`; @@ -102,23 +102,23 @@ exports[`复杂造型01: 曲线长度 19`] = `1463.6056529693449`; exports[`复杂造型01: 走刀数量 1`] = `12`; -exports[`复杂造型测试: 曲线长度 1`] = `24373.250750763476`; +exports[`复杂造型测试: 曲线长度 1`] = `13653.90128815112`; -exports[`复杂造型测试: 曲线长度 2`] = `4285.071854430756`; +exports[`复杂造型测试: 曲线长度 2`] = `2368.4150990997623`; -exports[`复杂造型测试: 曲线长度 3`] = `2418.1434517838115`; +exports[`复杂造型测试: 曲线长度 3`] = `1335.5629222865505`; -exports[`复杂造型测试: 曲线长度 4`] = `2293.0762218537734`; +exports[`复杂造型测试: 曲线长度 4`] = `1265.9777684790147`; -exports[`复杂造型测试: 曲线长度 5`] = `4096.105045378748`; +exports[`复杂造型测试: 曲线长度 5`] = `2261.915055343594`; exports[`复杂造型测试: 曲线长度 6`] = `8.0486334855557`; exports[`复杂造型测试: 曲线长度 7`] = `875.5142132396979`; -exports[`复杂造型测试: 曲线长度 8`] = `2841.1337227520225`; +exports[`复杂造型测试: 曲线长度 8`] = `1565.1472656712765`; -exports[`复杂造型测试: 曲线长度 9`] = `1079.273647743498`; +exports[`复杂造型测试: 曲线长度 9`] = `692.0908822142659`; exports[`复杂造型测试: 曲线长度 10`] = `227.8342135021163`; @@ -154,7 +154,7 @@ exports[`复杂造型测试: 曲线长度 25`] = `169.22283273433305`; exports[`复杂造型测试: 曲线长度 26`] = `162.171881370416`; -exports[`复杂造型测试: 曲线长度 27`] = `104483.03471871806`; +exports[`复杂造型测试: 曲线长度 27`] = `66231.52634930135`; exports[`复杂造型测试: 曲线长度 28`] = `2279.1571138841996`; @@ -172,9 +172,9 @@ exports[`复杂造型测试: 走刀数量 1`] = `13`; exports[`复杂造型测试: 走刀数量 2`] = `3`; -exports[`带孔造型板件: 曲线长度 1`] = `54662.04598627183`; +exports[`带孔造型板件: 曲线长度 1`] = `31091.461443717064`; -exports[`带孔造型板件: 曲线长度 2`] = `4678.35714568232`; +exports[`带孔造型板件: 曲线长度 2`] = `2808.760562622602`; exports[`带孔造型板件: 曲线长度 3`] = `3600`; @@ -182,9 +182,9 @@ exports[`带孔造型板件: 曲线长度 4`] = `2195.9741153279983`; exports[`带孔造型板件: 曲线长度 5`] = `1209.6929369796912`; -exports[`带孔造型板件: 曲线长度 6`] = `54662.04598627183`; +exports[`带孔造型板件: 曲线长度 6`] = `31091.461443717064`; -exports[`带孔造型板件: 曲线长度 7`] = `4678.35714568232`; +exports[`带孔造型板件: 曲线长度 7`] = `2808.760562622602`; exports[`带孔造型板件: 曲线长度 8`] = `3600`; diff --git a/__test__/Polyline/PolylineBulge.test.ts b/__test__/Polyline/PolylineBulge.test.ts new file mode 100644 index 000000000..d929b0c21 --- /dev/null +++ b/__test__/Polyline/PolylineBulge.test.ts @@ -0,0 +1,83 @@ +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; +import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util"; + + +describe("多段线凸度测试", () => +{ + test("多段线1", () => + { + let f = + [1, "Polyline", 5, 2, 102, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 6, [50.84745762711873, 77.48184019370457], 0, [247.57869249394577, 274.2130750605336], 0, [582.3244552058112, 87.1670702179177], 0, [346.2469733656175, -92.00968523002416], 0, [119.85472154963692, -3.631961259079941], 0, [50.84745762711873, 77.48184019370457], 0, false] + + let pl = LoadCurvesFromFileData(f)[0] as Polyline; + + expect(pl.IsBulge).toBeTruthy(); + expect(pl.Reverse().IsBulge).toBeTruthy(); + }) + test("多段线2", () => + { + let f = + [1, "Polyline", 5, 2, 101, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 4, [-645.278450363196, 10.895883777239712], 0, [-267.5544794188862, 10.895883777239712], 0, [-267.5544794188862, 248.18401937046002], 0, [-645.278450363196, 248.18401937046002], 0, true] + + let pl = LoadCurvesFromFileData(f)[0] as Polyline; + + expect(pl.IsBulge).toBeTruthy(); + expect(pl.Reverse().IsBulge).toBeTruthy(); + }) + test("多段线3", () => + { + let f = + [1, "Polyline", 5, 2, 103, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 7, [964.6004842615014, 91.52542372881355], 0, [1180.5326876513318, 381.0169491525423], 0, [1384.6004842615012, 89.15254237288131], 0, [1545.956416464891, 369.15254237288127], 0, [1643.2445520581118, -231.18644067796595], 0, [1061.8886198547216, -330.8474576271187], 0, [964.6004842615014, 91.52542372881355], 0, false] + let pl = LoadCurvesFromFileData(f)[0] as Polyline; + + expect(pl.IsBulge).toBeFalsy(); + expect(pl.Reverse().IsBulge).toBeFalsy(); + }) + test("多段线4", () => + { + let f = + [1, "Polyline", 5, 2, 109, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 7, [2764.373573094752, 78.02271311095797], 0, [3928.7352569216746, 78.02271311095797], 0, [5000.233738970991, 78.02271311095797], 0, [5000.233738970991, -793.4627189558191], 0, [3985.8818426309717, -1136.3422332116], 0, [4107.3183372632275, -422.0099118453894], 0, [2764.373573094752, 78.02271311095797], 0, false] + let pl = LoadCurvesFromFileData(f)[0] as Polyline; + + expect(pl.IsBulge).toBeFalsy(); + expect(pl.Reverse().IsBulge).toBeFalsy(); + }) + test("多段线5", () => + { + let f = + [1, "Polyline", 6, 2, 101, false, 1, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -129.5912740248159, 469.63460268545, 0, 1], 0, 0, true, 2, 7, [-50.619121903376026, -47.47742379906265], -0.9844157985538912, [49.10300899457479, 49.04381490609535], -0.8478171566452227, [149.19015915639648, 6.942320328602818], -0.9667128487795215, [197.7928852001328, -103.76551963369957], -0.8868998721515904, [142.07655502392345, -192.71770334928226], -0.6984434005122749, [67.67670179730408, -219.99685004135756], -1.5805804792006357, [-50.619121903376026, -47.47742379906265], 0, false] + let pl = LoadCurvesFromFileData(f)[0] as Polyline; + + expect(pl.IsBulge).toBeFalsy(); + expect(pl.Reverse().IsBulge).toBeFalsy(); + }) + test("多段线6", () => + { + let f = + [1, "Polyline", 6, 2, 100, false, 1, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1210.270699862136, -541.9634834389516, 0, 1], 0, 0, true, 2, 5, [896.401913875598, 343.41626794258354], 0, [1300.1244019138753, 343.41626794258354], 0.9999999999999997, [1300.1244019138753, 495.3397129186602], 0, [896.401913875598, 495.3397129186602], 1.0000000000000002, [896.401913875598, 343.41626794258354], 0, false] + let pl = LoadCurvesFromFileData(f)[0] as Polyline; + + expect(pl.IsBulge).toBeTruthy(); + expect(pl.Reverse().IsBulge).toBeTruthy(); + }) + test("多段线7", () => + { + let f = + [1, "Polyline", 6, 2, 106, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, 2, 3, [2250.54489975216, -384.30088235874064], 1.7704294517701693, [2338.029348647192, 40.623583702842495], 1.8751658801449689, [2250.54489975216, -384.30088235874064], 0, false] + let pl = LoadCurvesFromFileData(f)[0] as Polyline; + + expect(pl.IsBulge).toBeFalsy(); + expect(pl.Reverse().IsBulge).toBeFalsy(); + }) + test("多段线8", () => + { + let f = + [1, "Polyline", 6, 2, 100, false, 1, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, 2, 4, [-52.05811138014525, -73.43607691883707], 0.36387790102474465, [85.9564164648911, 232.44552058111378], 0.1015665592498786, [384.9878934624697, 16.949152542372893], 0.06768033499064963, [-52.05811138014525, -73.43607691883707], 0, false] + let pl = LoadCurvesFromFileData(f)[0] as Polyline; + + expect(pl.IsBulge).toBeFalsy(); + expect(pl.Reverse().IsBulge).toBeFalsy(); + }) +}) + + diff --git a/src/DatabaseServices/Entity/Polyline.ts b/src/DatabaseServices/Entity/Polyline.ts index 910fafe0f..82dae2910 100644 --- a/src/DatabaseServices/Entity/Polyline.ts +++ b/src/DatabaseServices/Entity/Polyline.ts @@ -1122,7 +1122,56 @@ export class Polyline extends Curve return { pts, buls }; } + get IsBulge() + { + if (!this.IsClose) return false; + + let refDir = Math.sign(this.Area2); + let c1: Curve; + let c2: Curve; + + for (let i = 0; i < this.EndParam; i++) + { + c1 = this.GetCurveAtIndex(i); + c2 = this.GetCurveAtIndex(FixIndex(i + 1, this.EndParam)); + let len1 = c1.Length; + let len2 = c2.Length; + let minLen = Math.min(len1, len2) * 0.2; + + let p = c1.EndPoint; + let p1: Vector3; + let p2: Vector3; + + if (c1 instanceof Arc) + { + let dir = c1.IsClockWise ? -1 : 1; + if (dir !== refDir) + return false; + p1 = c1.GetPointAtDistance(len1 - minLen); + } + else + p1 = c1.StartPoint; + + if (c2 instanceof Arc) + { + let dir = c2.IsClockWise ? -1 : 1; + if (dir !== refDir) + return false; + p2 = c2.GetPointAtDistance(minLen); + } + else + p2 = c2.EndPoint; + + let vec1 = p.clone().sub(p1); + let vec2 = p2.sub(p); + let dir = Math.sign(vec1.cross(vec2).z); + + if (dir !== 0 && dir !== refDir) + return false; + } + return true; + } get Shape() { let { pts, buls } = this.PtsBuls; diff --git a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts index 6be5c7a7f..c288e76a6 100644 --- a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts +++ b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts @@ -18,7 +18,7 @@ import { GetCurveToInDir, OptimizeToolPath, GetOffsetCurves } from "./OptimizeTo export class FeedingToolPath extends Singleton { /** - * 处理形状,内偏移 + * 处理形状,内偏移 * @param shape 造型Shape * @param knifRadius 刀半径/偏移距离 * @param [isOut=true] 是否是最外轮廓,如果是,洞需要外偏移一个刀半径,多段线偏移保留不闭合轮廓 @@ -27,6 +27,7 @@ export class FeedingToolPath extends Singleton { let outline = shape.Outline.Curve.Clone(); + let isBulge = (outline instanceof Polyline) && outline.IsBulge; let dir = GetCurveToInDir(outline); let offsetCus: Curve[] = [outline]; @@ -58,16 +59,27 @@ export class FeedingToolPath extends Singleton while (true) { - offsetDist += knifRadius; + if ((!isOut || offsetDist >= knifRadius) && isBulge) + offsetDist += knifRadius * 2; + else + offsetDist += knifRadius; let retCus: Curve[] = []; - if (outline instanceof Polyline) - retCus.push(...outline.GetFeedingToolPath(offsetDist * dir)); - else - retCus.push(...outline.GetOffsetCurves(offsetDist * dir)); + retCus.push(...GetOffsetCurves(outline, offsetDist * dir)); + + //最后一次内偏移如果是凸多边形,需在偏移一个刀半径避免没切到中心 + if (retCus.length === 0 && isBulge) + { + offsetDist -= knifRadius; + retCus.push(...GetOffsetCurves(outline, offsetDist * dir)); + } if (retCus.length === 0) break; + //如果凹内偏为凸,则按直径偏移 + if (!isBulge) + isBulge = retCus.every(c => c instanceof Polyline && c.IsBulge); + //是否和孤岛相交 let isInt = false; for (let c of retCus)