!540 判断多段线为凸边形,优化走刀结果

pull/540/MERGE
ZoeLeeFZ 5 years ago committed by ChenX
parent e98da4453b
commit 2c70166f3c

@ -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`;

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

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

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

Loading…
Cancel
Save