!2260 优化:判断IsRect的代码,支持容差

pull/2263/MERGE
ChenX 1 year ago
parent 12d23f0347
commit 9d62a5df38

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`封闭多段线分割矩形测试 交点参数为负数? 1`] = `20916.000000000233`; exports[`封闭多段线分割矩形测试 交点参数为负数? 1`] = `20915.968910871656`;
exports[`封闭多段线分割矩形测试 轮廓1 1`] = `333239.8526794412`; exports[`封闭多段线分割矩形测试 轮廓1 1`] = `333239.8526794412`;

@ -190,3 +190,11 @@ test('重复点过多导致的布尔错误', () =>
let brs = LoadBoardsFromFileData(d); let brs = LoadBoardsFromFileData(d);
testPathCount(brs[0]); testPathCount(brs[0]);
}); });
test('判断为不是矩形导致无法槽加宽', () =>
{
let d =
{ "file": [1, "Board", 10, 2, 87004, 0, 1, 2, 71, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -911.4661169474057, -16630.679370175498, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -911.4661169474057, -16630.679370175498, 0, 1], 0, 0, 1, 3, 2080, 329, 18, true, "Polyline", 10, 2, 0, 0, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, -1595.2199999999998, -50.82822461578962, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [329, 0], 0, [329, 2080], 0, [0, 2080], 0, true, 1, 3, 2030.0000066750217, 9, 8, true, "Polyline", 10, 2, 0, 0, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -310, 2030.0000066750217, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -310, 2030.0000066750217, 0, 1], 0, 0, 1, 2, 4, [319, 0], 0, [310, -0.000006675021722912788], 0, [310, -2030.0000066750217], 0, [319, -2030.0000066750217], 0, true, 0, 5, 10, 1, 1, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -901.4661169474057, -16320.679370175498, 49.99999332497828, 1], 3, 0, 0, 0, 0, 0, 11, 1, "左侧板开缺", "", "14 男孩房展示柜", "万华禾香板柠檬绸", "万华禾香板", "柠檬绸", 0, 0, "**多种**", 2, 0, "1", "1", "1", "1", "", "", "", 4, "不排", "不排", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, null], "basePt": { "x": -911.4661169474057, "y": -16630.679370175498, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let brs = LoadBoardsFromFileData(d);
testPathCount(brs[0]);
});

@ -34,6 +34,10 @@ exports[`刀切到外轮廓情况: 走刀数量 1`] = `2`;
exports[`刀切到外轮廓情况: 走刀数量 2`] = `4`; exports[`刀切到外轮廓情况: 走刀数量 2`] = `4`;
exports[`判断为不是矩形导致无法槽加宽 1`] = `"2030.00001"`;
exports[`判断为不是矩形导致无法槽加宽: 走刀数量 1`] = `1`;
exports[`包含刀路丢失#I2CW2U 1`] = `"3096.00000"`; exports[`包含刀路丢失#I2CW2U 1`] = `"3096.00000"`;
exports[`包含刀路丢失#I2CW2U 2`] = `"436.00000"`; exports[`包含刀路丢失#I2CW2U 2`] = `"436.00000"`;

@ -1,24 +1,202 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`矩形偏移 isrect 1`] = `
Object {
"OCS": Matrix4 {
"elements": Array [
0.7071067811865474,
0.7071067811865476,
0,
0,
-0.7071067811865476,
0.7071067811865474,
0,
0,
0,
0,
1,
0,
667.9517737972537,
248.9700940733262,
0,
1,
],
},
"box": Box3 {
"max": Vector3 {
"x": 932.0360172380435,
"y": 323.35943455197435,
"z": 0,
},
"min": Vector3 {
"x": -2.842170943040401e-14,
"y": -5.684341886080802e-14,
"z": 0,
},
},
"size": Vector3 {
"x": 932.0360172380435,
"y": 323.3594345519744,
"z": 0,
},
}
`;
exports[`矩形偏移 isrect 2`] = `
Array [
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 0,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 659.0489880991222,
"y": 659.0489880991224,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 430.39933916677364,
"y": 887.6986370314712,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": -228.64964893234873,
"y": 228.64964893234855,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 0,
},
},
]
`;
exports[`矩形偏移 isrect_p0 1`] = `
Object {
"OCS": Matrix4 {
"elements": Array [
-0.7428079605957125,
0.6695045434316621,
0,
0,
-0.6695045434316621,
-0.7428079605957125,
0,
0,
0,
0,
1,
0,
446.3180609256271,
738.920133175647,
0,
1,
],
},
"box": Box3 {
"max": Vector3 {
"x": 144.64212978369372,
"y": 397.7658569051579,
"z": 0,
},
"min": Vector3 {
"x": -2.2737367544323206e-13,
"y": -0,
"z": 0,
},
},
"size": Vector3 {
"x": 144.64212978369395,
"y": 397.7658569051579,
"z": 0,
},
}
`;
exports[`矩形偏移 isrect_p0 2`] = `
Array [
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 0,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 92.43681019536899,
"y": 102.55762882989848,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 156.26222675883798,
"y": 173.37122968863787,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 48.82090131799208,
"y": 270.20979275045295,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": -217.48514710199936,
"y": -25.25385221187355,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": -110.04382166115346,
"y": -122.09241527368857,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 0,
},
},
]
`;
exports[`矩形偏移 其他视图旋转矩形 1`] = `50`; exports[`矩形偏移 其他视图旋转矩形 1`] = `50`;
exports[`矩形偏移 其他视图旋转矩形 2`] = ` exports[`矩形偏移 其他视图旋转矩形 2`] = `
Array [ Array [
0.7789093282833537, 0.7789093282833541,
0, 0,
0.6271365547575544, 0.6271365547575537,
0, 0,
-0.6271365547575544, -0.6271365547575537,
0, 0,
0.7789093282833537, 0.7789093282833541,
0, 0,
0, 0,
-1, -1,
0, 0,
0, 0,
-1062.1715399995587,
0, 0,
0, 0.21291538503150775,
0,
1, 1,
] ]
`; `;
@ -27,21 +205,21 @@ exports[`矩形偏移 其他视图旋转矩形 3`] = `89.99993930803612`;
exports[`矩形偏移 其他视图旋转矩形 4`] = ` exports[`矩形偏移 其他视图旋转矩形 4`] = `
Array [ Array [
0.7789093282833537, 0.7789093282833541,
0, 0,
0.6271365547575544, 0.6271365547575537,
0, 0,
-0.6271365547575544, -0.6271365547575537,
0, 0,
0.7789093282833537, 0.7789093282833541,
0, 0,
0, 0,
-1, -1,
0, 0,
0, 0,
-1062.1715399995587,
0, 0,
0, 0.21291538503150775,
0,
1, 1,
] ]
`; `;
@ -50,21 +228,21 @@ exports[`矩形偏移 其他视图旋转矩形 5`] = `15.00001517299097`;
exports[`矩形偏移 其他视图旋转矩形 6`] = ` exports[`矩形偏移 其他视图旋转矩形 6`] = `
Array [ Array [
0.7789093282833537, 0.7789093282833541,
0, 0,
0.6271365547575544, 0.6271365547575537,
0, 0,
-0.6271365547575544, -0.6271365547575537,
0, 0,
0.7789093282833537, 0.7789093282833541,
0, 0,
0, 0,
-1, -1,
0, 0,
0, 0,
-1062.1715399995587,
0, 0,
0, 0.21291538503150775,
0,
1, 1,
] ]
`; `;
@ -85,8 +263,8 @@ Array [
0, 0,
1, 1,
0, 0,
0, -1327.419794987397,
0, 40.97675544794174,
0, 0,
1, 1,
] ]
@ -108,8 +286,8 @@ Array [
0, 0,
1, 1,
0, 0,
0, -1327.419794987397,
0, 40.97675544794174,
0, 0,
1, 1,
] ]
@ -131,8 +309,8 @@ Array [
0, 0,
1, 1,
0, 0,
0, -1327.419794987397,
0, 40.97675544794174,
0, 0,
1, 1,
] ]
@ -142,20 +320,20 @@ exports[`矩形偏移 旋转矩形 1`] = `50`;
exports[`矩形偏移 旋转矩形 2`] = ` exports[`矩形偏移 旋转矩形 2`] = `
Array [ Array [
0.7789093282833537, 0.7789093282833541,
0.6271365547575543, 0.6271365547575537,
0, 0,
0, 0,
-0.6271365547575543, -0.6271365547575537,
0.7789093282833537, 0.7789093282833541,
0, 0,
0, 0,
0, 0,
0, 0,
1, 1,
0, 0,
0, -1281.8810060380358,
0, 34.63108438909671,
0, 0,
1, 1,
] ]
@ -165,20 +343,20 @@ exports[`矩形偏移 旋转矩形 3`] = `89.99993930803612`;
exports[`矩形偏移 旋转矩形 4`] = ` exports[`矩形偏移 旋转矩形 4`] = `
Array [ Array [
0.7789093282833537, 0.7789093282833541,
0.6271365547575543, 0.6271365547575537,
0, 0,
0, 0,
-0.6271365547575543, -0.6271365547575537,
0.7789093282833537, 0.7789093282833541,
0, 0,
0, 0,
0, 0,
0, 0,
1, 1,
0, 0,
0, -1281.8810060380358,
0, 34.63108438909671,
0, 0,
1, 1,
] ]
@ -188,20 +366,20 @@ exports[`矩形偏移 旋转矩形 5`] = `15.00001517299097`;
exports[`矩形偏移 旋转矩形 6`] = ` exports[`矩形偏移 旋转矩形 6`] = `
Array [ Array [
0.7789093282833537, 0.7789093282833541,
0.6271365547575543, 0.6271365547575537,
0, 0,
0, 0,
-0.6271365547575543, -0.6271365547575537,
0.7789093282833537, 0.7789093282833541,
0, 0,
0, 0,
0, 0,
0, 0,
1, 1,
0, 0,
0, -1281.8810060380358,
0, 34.63108438909671,
0, 0,
1, 1,
] ]

@ -7,7 +7,8 @@ describe("矩形偏移", () =>
{ {
test("常规矩形", () => test("常规矩形", () =>
{ {
let d = { "file": [1, "Polyline", 8, 2, 102, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1327.419794987397, 40.97675544794174, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1875.419794987397, -2248.0232597250492, 0, 1], 0, 2, 5, [0, 0], 0, [25, 0], 0, [25, 9.99998482700903], 0, [0, 9.99998482700903], 0, [0, 0], 0, false], "basePt": { "x": -1327.419794987397, "y": 40.97675544794174, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; let d =
{ "file": [1, "Polyline", 8, 2, 102, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1327.419794987397, 40.97675544794174, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1875.419794987397, -2248.0232597250492, 0, 1], 0, 2, 5, [0, 0], 0, [25, 0], 0, [25, 9.99998482700903], 0, [0, 9.99998482700903], 0, [0, 0], 0, false], "basePt": { "x": -1327.419794987397, "y": 40.97675544794174, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadEntityFromFileData(d)[0] as Polyline; let pl = LoadEntityFromFileData(d)[0] as Polyline;
@ -49,7 +50,8 @@ describe("矩形偏移", () =>
}); });
test("其他视图旋转矩形", () => test("其他视图旋转矩形", () =>
{ {
let d = { "file": [1, "Polyline", 8, 2, 113, false, 1, 7, 0, [0.7789093282833541, 0, 0.6271365547575537, 0, -0.6271365547575537, 0, 0.7789093282833541, 0, 0, -1, 0, 0, -1062.1715399995587, 0, 0.21291538503150775, 1], 0, 0, true, [0.7789093282833541, 0, 0.6271365547575537, 0, -0.6271365547575537, 0, 0.7789093282833541, 0, 0, -1, 0, 0, -53.4982685432592, 0, -2126.381380881089, 1], 0, 2, 5, [0, 0], 0, [25, 0], 0, [25, 9.99998482700903], 0, [0, 9.99998482700903], 0, [0, 0], 0, false], "basePt": { "x": -1068.442896031597, "y": 0, "z": 0.21291538503150775 }, "ucs": [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1] }; let d =
{ "file": [1, "Polyline", 8, 2, 113, false, 1, 7, 0, [0.7789093282833541, 0, 0.6271365547575537, 0, -0.6271365547575537, 0, 0.7789093282833541, 0, 0, -1, 0, 0, -1062.1715399995587, 0, 0.21291538503150775, 1], 0, 0, true, [0.7789093282833541, 0, 0.6271365547575537, 0, -0.6271365547575537, 0, 0.7789093282833541, 0, 0, -1, 0, 0, -53.4982685432592, 0, -2126.381380881089, 1], 0, 2, 5, [0, 0], 0, [25, 0], 0, [25, 9.99998482700903], 0, [0, 9.99998482700903], 0, [0, 0], 0, false], "basePt": { "x": -1068.442896031597, "y": 0, "z": 0.21291538503150775 }, "ucs": [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1] };
let pl = LoadEntityFromFileData(d)[0] as Polyline; let pl = LoadEntityFromFileData(d)[0] as Polyline;
@ -68,4 +70,26 @@ describe("矩形偏移", () =>
expect(l).toBeUndefined(); expect(l).toBeUndefined();
} }
}); });
test('isrect', () =>
{
let d =
{ "file": [1, "Polyline", 10, 2, 114, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 667.9517737972537, 248.9700940733262, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 5, [0, 0], 0, [659.0489880991222, 659.0489880991224], 0, [430.39933916677364, 887.6986370314712], 0, [-228.64964893234873, 228.64964893234855], 0, [0, 0], 0, false], "basePt": { "x": 439.302124864905, "y": 248.9700940733262, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadEntityFromFileData(d)[0] as Polyline;
let rectInfo = IsRect(pl);
expect(rectInfo).toMatchSnapshot();
expect(pl.LineData).toMatchSnapshot();
});
test('isrect_p0', () =>
{
let d =
{ "file": [1, "Polyline", 10, 2, 125, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 290.0558341667891, 565.5489034870092, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 7, [0, 0], 0, [92.43681019536899, 102.55762882989848], 0, [156.26222675883798, 173.37122968863787], 0, [48.82090131799208, 270.20979275045295], 0, [-217.48514710199936, -25.25385221187355], 0, [-110.04382166115346, -122.09241527368857], 0, [0, 0], 0, false], "basePt": { "x": 72.57068706478975, "y": 443.4564882133206, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadEntityFromFileData(d)[0] as Polyline;
let rectInfo = IsRect(pl);
expect(rectInfo).toMatchSnapshot();
expect(pl.LineData).toMatchSnapshot();
});
}); });

@ -6,11 +6,11 @@ import { EBoardKeyList } from "../../Common/BoardKeyList";
import { IRectInfo, IsRect } from "../../Common/CurveUtils"; import { IRectInfo, IsRect } from "../../Common/CurveUtils";
import { GroupEntitysByBox } from "../../Common/GroupEntitysByBox"; import { GroupEntitysByBox } from "../../Common/GroupEntitysByBox";
import { ToplineUrls } from "../../Common/HostUrl"; import { ToplineUrls } from "../../Common/HostUrl";
import { inflateBase64 } from "../../Common/inflate";
import { KeyWord } from "../../Common/InputState"; import { KeyWord } from "../../Common/InputState";
import { PostJson, RequestStatus } from "../../Common/Request"; import { PostJson, RequestStatus } from "../../Common/Request";
import { GroupFileIn } from "../../Common/SerializeMaterial"; import { GroupFileIn } from "../../Common/SerializeMaterial";
import { Sleep } from "../../Common/Sleep"; import { Sleep } from "../../Common/Sleep";
import { inflateBase64 } from "../../Common/inflate";
import { Hole } from "../../DatabaseServices/3DSolid/Hole"; import { Hole } from "../../DatabaseServices/3DSolid/Hole";
import { SweepSolid } from "../../DatabaseServices/3DSolid/SweepSolid"; import { SweepSolid } from "../../DatabaseServices/3DSolid/SweepSolid";
import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension"; import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension";
@ -550,11 +550,11 @@ export class OneKeyLayout implements Command
{ {
if (en instanceof Polyline) if (en instanceof Polyline)
{ {
let res = IsRect(en); let rectInfo = IsRect(en);
if (res.isRect && res.size.x > 50 && res.size.y > 50) if (rectInfo && rectInfo.size.x > 50 && rectInfo.size.y > 50)
{ {
this._cacheRect.add(en); this._cacheRect.add(en);
vpRects.push(res); vpRects.push(rectInfo);
} }
} }
else if (en instanceof Text) else if (en instanceof Text)

@ -0,0 +1,26 @@
import { app } from "../../ApplicationServices/Application";
import { IsRect } from "../../Common/CurveUtils";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { TestDraw } from "../test/TestUtil";
export class Command_Test_IsRect implements Command
{
async exec()
{
let enRes = await app.Editor.GetEntity({ Filter: { filterTypes: [Polyline] } });
if (enRes.Status !== PromptStatus.OK) return;
let pl = enRes.Entity as Polyline;
let rectInfo = IsRect(pl);
if (rectInfo)
{
let pl = new Polyline().Rectangle(rectInfo.size.x, rectInfo.size.y);
pl.Move(rectInfo.box.min);
pl.ApplyMatrix(rectInfo.OCS);
TestDraw(pl, 1);
}
}
}

@ -1,16 +1,17 @@
import { Box3, Line3, Matrix3, Matrix4, Vec2, Vector2, Vector3 } from 'three'; import { Box2, Box3, Line3, Matrix3, Matrix4, Vec2, Vector2, Vector3 } from 'three';
import { Arc } from '../DatabaseServices/Entity/Arc'; import { Arc } from '../DatabaseServices/Entity/Arc';
import { Circle } from '../DatabaseServices/Entity/Circle'; import { Circle } from '../DatabaseServices/Entity/Circle';
import { Curve } from '../DatabaseServices/Entity/Curve'; import { Curve } from '../DatabaseServices/Entity/Curve';
import { Ellipse } from '../DatabaseServices/Entity/Ellipse'; import { Ellipse } from '../DatabaseServices/Entity/Ellipse';
import { Line } from '../DatabaseServices/Entity/Line'; import { Line } from '../DatabaseServices/Entity/Line';
import { Polyline } from '../DatabaseServices/Entity/Polyline'; import { BUL_IS_LINE_FUZZ, Polyline } from '../DatabaseServices/Entity/Polyline';
import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline'; import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline';
import { Spline } from '../DatabaseServices/Spline'; import { Spline } from '../DatabaseServices/Spline';
import { Count } from '../Geometry/Count'; import { Count } from '../Geometry/Count';
import { CurveMap, Vertice } from '../Geometry/CurveMap'; import { CurveMap, Vertice } from '../Geometry/CurveMap';
import { AsVector2, AsVector3, equaln, equalv2, equalv3, isIntersect, isParallelTo, isPerpendicularityTo, XAxis, YAxis, ZeroVec } from '../Geometry/GeUtils'; import { AsVector2, AsVector3, equaln, equalv2, equalv3, isIntersect, isParallelTo, isPerpendicularityTo, XAxis, YAxis, ZAxis, ZeroVec } from '../Geometry/GeUtils';
import { Vec3 } from '../Geometry/IVec3'; import { Vec3 } from '../Geometry/IVec3';
import { Matrix2 } from '../Geometry/Matrix2';
import { Orbit } from '../Geometry/Orbit'; import { Orbit } from '../Geometry/Orbit';
import { PlaneExt } from '../Geometry/Plane'; import { PlaneExt } from '../Geometry/Plane';
import { IntersectOption, IntersectResult } from '../GraphicsSystem/IntersectWith'; import { IntersectOption, IntersectResult } from '../GraphicsSystem/IntersectWith';
@ -500,56 +501,143 @@ export function getTanPtsOnEllipse(cu: Ellipse, lastPoint: Vector3)
export interface IRectInfo export interface IRectInfo
{ {
isRect: boolean; size: Vector3;
size?: Vector3; box: Box3;
box?: Box3; OCS: Matrix4;
OCS?: Matrix4;
} }
export function IsRect(cu: Curve): IRectInfo /**
* 线
* ,
* 1.4
* -x,
* -
* 2.box
* 3.4,
* @param cu
*/
export function IsRect(cu: Curve): IRectInfo | undefined
{ {
if (cu instanceof Polyline) if (cu instanceof Polyline)
{ {
if (!cu.IsClose) return { isRect: false }; //如果不封闭(就不是矩形)
if (!cu.IsClose) return;
let pts = cu.GetStretchPoints(); //如果点个数小于4(就不是矩形)
if (cu.LineData.length < 4) return;
if (pts.length < 4) return { isRect: false }; //如果有圆弧(就不是矩形)
for (let i = 0; i < cu.LineData.length; i++)
let xVec: Vector3;
let p1 = pts[0];
for (let i = 1; i < pts.length; i++)
{ {
xVec = pts[i].clone().sub(p1).normalize(); let d = cu.LineData[i];
if (!equalv3(xVec, ZeroVec)) if (equaln(d.bul, 0, BUL_IS_LINE_FUZZ))
break; continue;
let next = FixIndex(i + 1, cu.LineData);
if (equalv2(d.pt, cu.LineData[next].pt))
continue;
return;
} }
if (!xVec) return { isRect: false }; let pts2d = cu.LineData.map(d => d.pt);
let zVec = cu.Normal; //去除重复点
let yVec = zVec.clone().cross(xVec).normalize(); arrayRemoveDuplicateBySort(pts2d, (p1, p2) => equalv2(p1, p2));
if (equalv2(pts2d[0], pts2d[pts2d.length - 1]))
pts2d.pop();
let rectOCS = new Matrix4().makeBasis(xVec, yVec, zVec); //这里我们判断它是不是有4个90度的角,并且有4个点
let rectOCSInv = new Matrix4().getInverse(rectOCS); let preV = pts2d[0].clone().sub(pts2d[pts2d.length - 1]).negate();//preVector
let preL = preV.length();//preLength
let nowV = new Vector2;//nowVector
let crossV = 0;//永远相同方向的90度,如果不是(就不是矩形)
for (let p of pts) let pts4: Vector2[] = [];//简化成4个点
p.applyMatrix4(rectOCSInv);
let box = new Box3().setFromPoints(pts); for (let i = 0; i < pts2d.length; i++)
{
nowV.subVectors(pts2d[FixIndex(i + 1, pts2d.length)], pts2d[i]);
let size = box.getSize(new Vector3); let cross = preV.cross(nowV) / preL;
if (equaln(size.x * size.y, cu.Area, 0.1))
let nowL = nowV.length();//nowLength
if (equaln(cross, 0, 0.01))//平行 此时的cross = 三角形的高(其中preL是三角形的底边) 我们认为它移动了0.01是可以接受的
continue;//TODOX:我们可能要合并这条线? 把preV preL更新一下?
cross /= nowL;//此时的cross = sin@
//如果不等于90度(就不是矩形)
if (!equaln(Math.abs(cross), 1, 1e-5))
return;
cross = Math.sign(cross);
if (!crossV)
crossV = cross;
else if (crossV !== cross)//如果方向不一致(没有绕着90度)(就不是矩形)
return;
pts4.push(pts2d[i]);
if (pts4.length > 4)//如果超过4个点(就不是矩形)
return;
preL = nowL;
preV.copy(nowV).negate();//翻转它 以便下一次计算
}
if (pts4.length === 4 && !crossV)//没有90度 (就不是矩形)
return;
let rectOCS: Matrix4;
preV.subVectors(pts4[1], pts4[0]);
let box = new Box2;
if (equaln(preV.x, 0, 1e-3) || equaln(preV.y, 0, 1e-3))//判断是不是与X轴平行或者与Y轴平行,精度容差在0.001 看起来没问题
{ {
return { rectOCS = cu.OCS;
isRect: true, box.setFromPoints(pts4);
size,
box,
OCS: rectOCS,
};
} }
else//如果矩形不与X轴平行,我们旋转这个点表,然后变换它
{
let a = Math.atan2(preV.y, preV.x);
let r = new Matrix2().setRotate(-a);
let p0 = pts4[0];
pts4 = pts4.map(p =>
{
p = p.clone().sub(p0);
r.applyVector(p);
return p;
});
box.setFromPoints(pts4);
nowV.set(-preV.y, preV.x);//旋转90度
rectOCS = new Matrix4().makeBasis(
AsVector3(preV.normalize()),
AsVector3(nowV.normalize()),
ZAxis,
).setPosition(p0.x, p0.y, 0);
rectOCS.multiplyMatrices(cu.OCSNoClone, rectOCS);
}
//4个点都在角上
if (!pts4.every(p =>
{
return (equaln(p.x, box.min.x, 0.01) || equaln(p.x, box.max.x, 0.01))
&& (equaln(p.y, box.min.y, 0.01) || equaln(p.y, box.max.y, 0.01));
}))
return;
let size = box.getSize(new Vector2);
return {
size: AsVector3(size),
box: new Box3(AsVector3(box.min), AsVector3(box.max)),
OCS: rectOCS,
};
} }
return { isRect: false };
} }
/**用4个矩形点构造矩形 */ /**用4个矩形点构造矩形 */
@ -819,7 +907,7 @@ const PolylineSpliteRectFuzz = 1e-3;
/**封闭多段线 分割成矩形 */ /**封闭多段线 分割成矩形 */
export function PolylineSpliteRect(outline: Polyline): Polyline[] export function PolylineSpliteRect(outline: Polyline): Polyline[]
{ {
if (!outline.IsClose || IsRect(outline).isRect) if (!outline.IsClose || IsRect(outline))
return [outline]; return [outline];
let firstDerv = outline.GetFistDeriv(0).normalize(); let firstDerv = outline.GetFistDeriv(0).normalize();

@ -216,6 +216,7 @@ import { Command_TemplateSearch } from "../Add-on/TemplateSearch";
import { TestIntersect } from "../Add-on/test/testIntersect"; import { TestIntersect } from "../Add-on/test/testIntersect";
import { Command_TestParseEdgeSealDir } from "../Add-on/test/TestParseEdgeSealDir"; import { Command_TestParseEdgeSealDir } from "../Add-on/test/TestParseEdgeSealDir";
import { Command_TestTape } from "../Add-on/test/TestTape"; import { Command_TestTape } from "../Add-on/test/TestTape";
import { Command_Test_IsRect } from "../Add-on/testEntity/Cmd_Test_IsRect";
import { Command_UpdateLight } from "../Add-on/testEntity/CMD_UpdateLight"; import { Command_UpdateLight } from "../Add-on/testEntity/CMD_UpdateLight";
import { Command_DebugTemplateAssocCount } from "../Add-on/testEntity/DebugShowTemplateAssocEntityCount"; import { Command_DebugTemplateAssocCount } from "../Add-on/testEntity/DebugShowTemplateAssocEntityCount";
import { Test } from "../Add-on/testEntity/test"; import { Test } from "../Add-on/testEntity/test";
@ -330,6 +331,8 @@ export function registerCommand()
commandMachine.RegisterCommand("testRegionParse", new Command_TestRegionParse()); commandMachine.RegisterCommand("testRegionParse", new Command_TestRegionParse());
commandMachine.RegisterCommand("TestBoundaryBox", new Command_TestBoundaryBox()); commandMachine.RegisterCommand("TestBoundaryBox", new Command_TestBoundaryBox());
commandMachine.RegisterCommand("TestSweepMaxLength", new Command_TestSweepMaxLength()); commandMachine.RegisterCommand("TestSweepMaxLength", new Command_TestSweepMaxLength());
commandMachine.RegisterCommand("isrect", new Command_Test_IsRect());
} }
//插入图纸 //插入图纸

@ -75,7 +75,7 @@ export class FeedingToolPath extends Singleton
while (true) while (true)
{ {
if ((!isOut || offsetDist >= knifRadius) && rectInfo.isRect) if ((!isOut || offsetDist >= knifRadius) && rectInfo)
offsetDist += knifRadius * 2; offsetDist += knifRadius * 2;
else else
offsetDist += knifRadius; offsetDist += knifRadius;
@ -91,7 +91,7 @@ export class FeedingToolPath extends Singleton
retCus.push(...tempOffsetCus); retCus.push(...tempOffsetCus);
//最后一次内偏移如果是矩形,需在偏移一个刀半径避免没切到中心 //最后一次内偏移如果是矩形,需在偏移一个刀半径避免没切到中心
if (retCus.length === 0 && rectInfo.isRect && offsetDist > knifRadius) if (retCus.length === 0 && rectInfo && offsetDist > knifRadius)
{ {
offsetDist -= knifRadius; offsetDist -= knifRadius;
retCus.push(...GetOffsetCurves(outline, offsetDist * dir, rectInfo)); retCus.push(...GetOffsetCurves(outline, offsetDist * dir, rectInfo));
@ -273,11 +273,11 @@ export class FeedingToolPath extends Singleton
//若是矩形,应用槽加长 //若是矩形,应用槽加长
if (addLen > 0 || addWidth > 0) if (addLen > 0 || addWidth > 0)
{ {
let curveData = IsRect(shape.Outline.Curve); let rectInfo = IsRect(shape.Outline.Curve);
if (curveData.isRect) if (rectInfo)
{ {
let box = curveData.box; let box = rectInfo.box;
let size = curveData.size; let size = rectInfo.size;
if (size.x > size.y) if (size.x > size.y)
{ {
box.max.add(new Vector3(addLen / 2, addWidth / 2)); box.max.add(new Vector3(addLen / 2, addWidth / 2));
@ -288,7 +288,7 @@ export class FeedingToolPath extends Singleton
box.max.add(new Vector3(addWidth / 2, addLen / 2)); box.max.add(new Vector3(addWidth / 2, addLen / 2));
box.min.add(new Vector3(-addWidth / 2, -addLen / 2)); box.min.add(new Vector3(-addWidth / 2, -addLen / 2));
} }
let pl = new Polyline().RectangleFrom2Pt(box.min, box.max).ApplyMatrix(curveData.OCS); let pl = new Polyline().RectangleFrom2Pt(box.min, box.max).ApplyMatrix(rectInfo.OCS);
shape.Outline = Contour.CreateContour(pl); shape.Outline = Contour.CreateContour(pl);
} }
} }

@ -247,7 +247,7 @@ export function GetOffsetCurves(cu: Curve, dist: number, rectInfo?: IRectInfo):
{ {
if (cu instanceof Polyline) if (cu instanceof Polyline)
{ {
if (rectInfo?.isRect) if (rectInfo)
{ {
let r = RectOffset(cu, rectInfo, Math.abs(dist)); let r = RectOffset(cu, rectInfo, Math.abs(dist));
return r ? [r] : []; return r ? [r] : [];
@ -265,12 +265,12 @@ export function GetCurveToInDir(cu: Curve): number
} }
/**矩形偏移,正为内偏移 */ /**矩形偏移,正为内偏移 */
export function RectOffset(rect: Polyline, res: IRectInfo, dist: number) export function RectOffset(rect: Polyline, rectInfo: IRectInfo, dist: number)
{ {
if (!res.isRect || equaln(dist, 0)) return; if (!rectInfo || equaln(dist, 0)) return;
let box = res.box; let box = rectInfo.box;
let size = res.size; let size = rectInfo.size;
let min = box.min.clone(); let min = box.min.clone();
let max = box.max.clone(); let max = box.max.clone();
@ -281,19 +281,19 @@ export function RectOffset(rect: Polyline, res: IRectInfo, dist: number)
let x = (box.min.x + box.max.x) * 0.5; let x = (box.min.x + box.max.x) * 0.5;
let sPt = new Vector3(x, box.min.y + dist); let sPt = new Vector3(x, box.min.y + dist);
let ePt = new Vector3(x, box.max.y - dist); let ePt = new Vector3(x, box.max.y - dist);
return new Polyline([{ pt: AsVector2(sPt), bul: 0 }, { pt: AsVector2(ePt), bul: 0 }]).ApplyMatrix(res.OCS); return new Polyline([{ pt: AsVector2(sPt), bul: 0 }, { pt: AsVector2(ePt), bul: 0 }]).ApplyMatrix(rectInfo.OCS);
} }
else if (equaln(size.y / 2, dist, 1e-5)) else if (equaln(size.y / 2, dist, 1e-5))
{ {
let y = (box.min.y + box.max.y) * 0.5; let y = (box.min.y + box.max.y) * 0.5;
let sPt = new Vector3(box.min.x + dist, y); let sPt = new Vector3(box.min.x + dist, y);
let ePt = new Vector3(box.max.x - dist, y); let ePt = new Vector3(box.max.x - dist, y);
return new Polyline([{ pt: AsVector2(sPt), bul: 0 }, { pt: AsVector2(ePt), bul: 0 }]).ApplyMatrix(res.OCS); return new Polyline([{ pt: AsVector2(sPt), bul: 0 }, { pt: AsVector2(ePt), bul: 0 }]).ApplyMatrix(rectInfo.OCS);
} }
else else
{ {
min.add(new Vector3(dist, dist)); min.add(new Vector3(dist, dist));
max.add(new Vector3(-dist, -dist)); max.add(new Vector3(-dist, -dist));
return new Polyline().RectangleFrom2Pt(min, max).ApplyMatrix(res.OCS); return new Polyline().RectangleFrom2Pt(min, max).ApplyMatrix(rectInfo.OCS);
} }
} }

Loading…
Cancel
Save