!1190 修复:异型切割板件错误

pull/1190/MERGE
ZoeLeeFZ 4 years ago committed by ChenX
parent e16bd26a07
commit debfded9ba

@ -3,3 +3,11 @@
exports[`差集共线(圆) 1`] = `442426.78778792813`;
exports[`差集问题 1`] = `546438.8158863322`;
exports[`弧形板差集 1`] = `165548.3611026407`;
exports[`弧形板差集 2`] = `331151.31923948776`;
exports[`弧形板差集2 1`] = `165548.36022878048`;
exports[`弧形板差集2 2`] = `331151.3192394876`;

@ -23,3 +23,24 @@ test('差集问题', () =>
expect(regs[0].Explode().length).toBe(16);
expect(regs[0].Area).toMatchSnapshot();
});
test("弧形板差集", () =>
{
let d = { "file": [2, "Region", 8, 2, 239, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7164.031205116695, -312.3853909685172, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7164.031205116695, -312.3853909685172, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7164.031205116695, -312.3853909685172, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7164.031205116695, -312.3853909685172, 0, 1], 0, 2, 4, [1488.2724956409866, -403.9906338621595], 0, [1556.769411177408, -276.18933276551024], 0.25108720252037403, [-1817.9873510282487, -276.1893327618018], 0, [-1749.4904354922473, -403.99063385883346], -0.25108720252039435, true, 0, "Region", 8, 2, 238, false, 1, 7, 0, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6729.018004950986, -356.8947148198645, 0, 1], 0, 0, true, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6729.018004950986, -356.8947148198645, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 4, 0, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6729.018004950986, -356.8947148198645, 0, 1], 0, 0, true, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6729.018004950986, -356.8947148198645, 0, 1], 0, 2, 4, [0, 0], 0, [145.0094999623654, 0], 0, [145.0094999623654, 18], 0, [0, 18], 0, true, 0], "basePt": { "x": -8982.018556144943, "y": -716.3760248306767, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let regs = LoadRegionsFromFileData(d);
regs[0].BooleanOper(regs[1], BoolOpeartionType.Subtract);
expect(regs[0].ShapeManager.ShapeList.length).toBe(2);
for (let s of regs[0].ShapeManager.ShapeList)
expect(s.Area).toMatchSnapshot();
});
test("弧形板差集2", () =>
{
let d = { "file": [2, "Region", 8, 2, 237, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -6781.659977097809, -1502.9438267095907, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -6781.659977097809, -1502.9438267095907, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -6781.659977097809, -1502.9438267095907, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -6781.659977097809, -1502.9438267095907, 0, 1], 0, 2, 4, [1488.2724956409866, -403.9906338621595], 0, [1556.769411177408, -276.18933276551024], 0.25108720252037403, [-1817.9873510282487, -276.1893327618018], 0, [-1749.4904354922473, -403.99063385883346], -0.25108720252039435, true, 0, "Region", 8, 2, 236, false, 1, 7, 0, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6346.646776932101, -1547.453150560938, 0, 1], 0, 0, true, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6346.646776932101, -1547.453150560938, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 4, 0, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6346.646776932101, -1547.453150560938, 0, 1], 0, 0, true, [0.16234909674127015, 0.9867333838414984, 0, 0, -0.9867333838414984, 0.16234909674127015, 0, 0, 0, 0, 1, 0, -6346.646776932101, -1547.453150560938, 0, 1], 0, 2, 4, [0, 0], 0, [144.9994999623654, 0], 0, [144.9994999623654, 18], 0, [0, 18], 0, true, 0], "basePt": { "x": -8599.647328126059, "y": -1906.9344605717502, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let regs = LoadRegionsFromFileData(d);
regs[0].BooleanOper(regs[1], BoolOpeartionType.Subtract);
expect(regs[0].ShapeManager.ShapeList.length).toBe(2);
for (let s of regs[0].ShapeManager.ShapeList)
expect(s.Area).toMatchSnapshot();
});

@ -0,0 +1,91 @@
import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util";
import { PolylineSpliteRect } from "../../src/Common/CurveUtils";
import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
describe("封闭多段线分割矩形测试", () =>
{
test("轮廓1", () =>
{
let data = { "file": [1, "Polyline", 8, 2, 176, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 9, [8387.713348727397, 1084.5343505247351], 0, [7226.765061171589, 1084.5343505247351], 0, [7226.765061171589, 829.0146317325472], 0, [4632.684437781331, 829.0146317325472], 0, [4632.684437781331, 1078.9795740292527], 0, [5965.830796697095, 1078.9795740292527], 0, [5965.830796697095, 1301.1706338485465], 0, [8387.713348727397, 1301.1706338485465], 0, [8387.713348727397, 1084.5343505247351], 0, false], "basePt": { "x": 4632.684437781331, "y": 829.0146317325472, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadCurvesFromFileData(data) as Polyline[];
let cons = PolylineSpliteRect(pl[0]);
expect(cons.length).toBe(3);
for (let c of cons)
expect(c.Area).toMatchSnapshot();
});
test("轮廓2", () =>
{
let data = { "file": [1, "Polyline", 8, 2, 209, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5376.119285317616, -2438.550333164698, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 17, [0, 0], 0, [0, -2396.493624880947], 0, [774.4127870794337, -2396.493624880947], 0, [774.4127870794337, -805.8079000691391], 0, [1852.3116663926985, -805.8079000691391], 0, [1852.3116663926985, -1789.521440413283], 0, [2972.0706963589055, -1789.521440413283], 0, [2972.0706963589055, -1088.3639169765001], 0, [4029.0395003456997, -1088.3639169765001], 0, [4029.0395003456997, -2155.797758626529], 0, [4719.731986119246, -2155.797758626529], 0, [4719.731986119246, -1517.4304611691587], 0, [7095.295535673724, -1517.4304611691587], 0, [7095.295535673724, -690.6924857735476], 0, [4426.7109315486505, -690.6924857735476], 0, [4426.7109315486505, 0], 0, [0, 0], 0, false], "basePt": { "x": 5376.119285317616, "y": -4835.043958045645, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadCurvesFromFileData(data) as Polyline[];
let cons = PolylineSpliteRect(pl[0]);
expect(cons.length).toBe(7);
for (let c of cons)
expect(c.Area).toMatchSnapshot();
});
test("轮廓3", () =>
{
let data = { "file": [1, "Polyline", 8, 2, 204, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 13, [6757.27535177342, -889.6497705352106], 0, [8091.75010660756, -889.6497705352106], 0, [8091.75010660756, -490.4058330764652], 0, [6922.134064474898, -490.4058330764652], 0, [6922.134064474898, -259.85651707916213], 0, [5668.170711611516, -259.85651707916213], 0, [5668.170711611516, -479.1595249790362], 0, [4577.27882616086, -479.1595249790362], 0, [4577.27882616086, -889.6497705352106], 0, [5898.729096631669, -889.6497705352106], 0, [5898.729096631669, -658.1101316379868], 0, [6757.27535177342, -658.1101316379868], 0, [6757.27535177342, -889.6497705352106], 0, false], "basePt": { "x": 4577.27882616086, "y": -889.6497705352106, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadCurvesFromFileData(data) as Polyline[];
let cons = PolylineSpliteRect(pl[0]);
expect(cons.length).toBe(5);
for (let c of cons)
expect(c.Area).toMatchSnapshot();
});
test("轮廓4", () =>
{
let data = { "file": [1, "Polyline", 8, 2, 187, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 7, [-93.87293003759919, -1554.1191971829958], 0, [-93.87293003759919, -706.4182647686482], 0, [1667.016560471175, -706.4182647686482], 0, [1667.016560471175, -993.8361774756588], 0, [2743.9241827657966, -993.8361774756588], 0, [2743.9241827657966, -1554.1191971829958], 0, [-93.87293003759919, -1554.1191971829958], 0, false], "basePt": { "x": -93.87293003759919, "y": -1554.1191971829958, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadCurvesFromFileData(data) as Polyline[];
let cons = PolylineSpliteRect(pl[0]);
expect(cons.length).toBe(2);
for (let c of cons)
expect(c.Area).toMatchSnapshot();
});
test("轮廓5", () =>
{
let data = { "file": [1, "Polyline", 8, 2, 216, false, 1, 3, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2422.6764429900863, -452.7252899848789, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2422.6764429900863, -452.7252899848789, 0, 1], 0, 2, 6, [784.7209559691166, 681.8216720645796], 0, [193.7209559691164, 681.8216720645796], 0, [193.7209559691164, 663.8216720645796], 0, [1173, 663.8216720645796], 0, [1173, 672.8216720645801], 0, [784.7209559691164, 672.8216720645801], 0, true], "basePt": { "x": 2616.3973989592027, "y": 211.09638207970073, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadCurvesFromFileData(data) as Polyline[];
let cons = PolylineSpliteRect(pl[0]);
expect(cons.length).toBe(2);
for (let c of cons)
expect(c.Area).toMatchSnapshot();
});
test("轮廓6", () =>
{
let data = { "file": [1, "Polyline", 8, 2, 226, false, 1, 3, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1095.4517523011439, -5530.527123641856, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1095.4517523011439, -5530.527123641856, 0, 1], 0, 2, 8, [749.147341015374, 360.98889708156776], 0, [740.147341015374, 360.98889708156776], 0, [740.1473410153737, 582], 0, [731.147341015374, 582], 0, [731.1473410153742, 0], 0, [740.1473410153849, 0], 0, [740.1473410153849, 168.38705445030928], 0, [749.147341015374, 168.38705445030945], 0, true], "basePt": { "x": 1826.5990933165178, "y": -5530.527123641856, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadCurvesFromFileData(data) as Polyline[];
let cons = PolylineSpliteRect(pl[0]);
expect(cons.length).toBe(2);
for (let c of cons)
expect(c.Area).toMatchSnapshot();
});
});

@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`封闭多段线分割矩形测试 轮廓1 1`] = `333239.8526794412`;
exports[`封闭多段线分割矩形测试 轮廓1 2`] = `595357.6812453549`;
exports[`封闭多段线分割矩形测试 轮廓1 3`] = `251503.5221472336`;
exports[`封闭多段线分割矩形测试 轮廓2 1`] = `1855875.3072621506`;
exports[`封闭多段线分割矩形测试 轮廓2 2`] = `868579.4324262962`;
exports[`封闭多段线分割矩形测试 轮廓2 3`] = `2003832.7922209054`;
exports[`封闭多段线分割矩形测试 轮廓2 4`] = `1150366.7076290324`;
exports[`封闭多段线分割矩形测试 轮廓2 5`] = `857299.1800571308`;
exports[`封闭多段线分割矩形测试 轮廓2 6`] = `429306.6921083182`;
exports[`封闭多段线分割矩形测试 轮廓2 7`] = `1963968.5993822813`;
exports[`封闭多段线分割矩形测试 轮廓3 1`] = `447800.4779338776`;
exports[`封闭多段线分割矩形测试 轮廓3 2`] = `145204.1154134143`;
exports[`封闭多段线分割矩形测试 轮廓3 3`] = `341919.1493761451`;
exports[`封闭多段线分割矩形测试 轮廓3 4`] = `103826.90503283963`;
exports[`封闭多段线分割矩形测试 轮廓3 5`] = `466962.1139759575`;
exports[`封闭多段线分割矩形测试 轮廓4 1`] = `1492707.6629829132`;
exports[`封闭多段线分割矩形测试 轮廓4 2`] = `603373.0545650794`;
exports[`封闭多段线分割矩形测试 轮廓5 1`] = `10638`;
exports[`封闭多段线分割矩形测试 轮廓5 2`] = `3494.5113962781616`;
exports[`封闭多段线分割矩形测试 轮廓6 1`] = `5238`;
exports[`封闭多段线分割矩形测试 轮廓6 2`] = `1733.4165836796165`;

@ -8,7 +8,7 @@ import { Polyline } from '../DatabaseServices/Entity/Polyline';
import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline';
import { Count } from '../Geometry/Count';
import { CurveMap, Vertice } from '../Geometry/CurveMap';
import { AsVector2, AsVector3, equaln, equalv2, equalv3, isParallelTo, ZeroVec } from '../Geometry/GeUtils';
import { AsVector2, AsVector3, equaln, equalv2, equalv3, isParallelTo, ZeroVec, XAxis, YAxis, isIntersect } from '../Geometry/GeUtils';
import { Orbit } from '../Geometry/Orbit';
import { PlaneExt } from '../Geometry/Plane';
import { IntersectOption, IntersectResult } from '../GraphicsSystem/IntersectWith';
@ -684,3 +684,84 @@ export function Pts2Polyline(pts: (Vector3 | Vector2)[], isClose: boolean)
}
return pl;
}
const PolylineSpliteRectFuzz = 1e-3;
/**封闭多段线 分割成矩形 */
export function PolylineSpliteRect(outline: Polyline): Polyline[]
{
if (!outline.IsClose || IsRect(outline).isRect)
return [outline];
let firstDerv = outline.GetFistDeriv(0).normalize();
if (!isParallelTo(firstDerv, XAxis, PolylineSpliteRectFuzz) && !isParallelTo(firstDerv, YAxis, PolylineSpliteRectFuzz)) return [outline];
let cus = outline.Explode();
let yCus: Curve[] = [];
for (let c of cus)
{
let derv = c.GetFistDeriv(0).normalize();
if (isParallelTo(derv, YAxis, PolylineSpliteRectFuzz))
yCus.push(c);
else
if (!isParallelTo(derv, XAxis, PolylineSpliteRectFuzz) || c instanceof Arc)
{
console.log(derv.clone().cross(XAxis).lengthSq());
return [outline];
}
}
yCus.sort((c1, c2) => c1.StartPoint.x - c2.StartPoint.x);
let rects: Polyline[] = [];
for (let i = 0; i < yCus.length - 1; i++)
{
let c1 = yCus[i];
let c2 = yCus[i + 1];
let x1 = c1.StartPoint.x;
let x2 = c2.StartPoint.x;
if (equaln(x1, x2))
continue;
let y1: number;
let y2: number;
let res = c1.IntersectWith2(outline, IntersectOption.ExtendThis);
let res2 = c2.IntersectWith2(outline, IntersectOption.ExtendThis);
let pars = [...res.map(r => Math.floor(r.argParam)), ...res2.map(r => Math.floor(r.argParam))];
pars = [...new Set(pars)];
pars.sort((a, b) => a - b);
let ys: number[] = [];
for (let par of pars)
{
let c = outline.GetCurveAtIndex(par);
let derv = c.GetFistDeriv(0).normalize();
if (isParallelTo(derv, XAxis, PolylineSpliteRectFuzz))
{
let x3 = c.StartPoint.x;
let x4 = c.EndPoint.x;
if (x3 > x4)
[x3, x4] = [x4, x3];
if (isIntersect(x1, x2, x3, x4, -PolylineSpliteRectFuzz))
ys.push(c.StartPoint.y);
}
}
if (ys.length < 2) return [outline];
ys.sort((a, b) => a - b);
y1 = ys[0];
y2 = arrayLast(ys);
rects.push(new Polyline().RectangleFrom2Pt(new Vector3(x1, y1), new Vector3(x2, y2)));
}
return rects;
}

@ -43,7 +43,7 @@ export class Contour
return;
}
let closeCurve = Contour.Combine(cus, needLink) as Polyline | Circle;
let closeCurve = Contour.Combine(cus, needLink, 1e-2) as Polyline | Circle;
if (closeCurve && closeCurve.IsClose)
{
if (closeCurve instanceof Polyline && closeCurve.CloseMark === false)
@ -450,7 +450,7 @@ export class Contour
let plMidParam = pl.MidParam;
let plDir = pl.GetFistDeriv(plMidParam).normalize();
let index = targetCus.findIndex(cu => fastEqualCurve(cu, pl));
let index = targetCus.findIndex(cu => fastEqualCurve(cu, pl, 0.05));
if (index !== -1)
{
let cu = targetCus[index];
@ -526,9 +526,9 @@ export class Contour
let gclone = g.map(c => c.Clone());
arrayRemoveDuplicateBySort(gclone, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True);
arrayRemoveDuplicateBySort(gclone, (cu1: Curve, cu2: Curve) => cu1.Join(cu2, false, tolerance) === Status.True);
if (gclone.length > 1 && gclone[0].Join(arrayLast(gclone)))
if (gclone.length > 1 && gclone[0].Join(arrayLast(gclone), false, tolerance))
gclone.pop();
let pl = Polyline.Combine(gclone, tolerance);

@ -2,7 +2,7 @@ import { BoxGeometry, BufferGeometry, ExtrudeGeometry, ExtrudeGeometryOptions, L
import { Line2 } from "three/examples/jsm/lines/Line2";
import { arrayClone, arrayLast, arrayRemoveIf, arrayRemoveOnce, arraySortByNumber, arraySum } from "../../Common/ArrayExt";
import { ColorMaterial } from "../../Common/ColorPalette";
import { equalCurve } from "../../Common/CurveUtils";
import { equalCurve, PolylineSpliteRect } from "../../Common/CurveUtils";
import { DisposeThreeObj } from "../../Common/Dispose";
import { Log } from "../../Common/Log";
import { matrixSetVector, Vector2ApplyMatrix4 } from "../../Common/Matrix4Utils";
@ -1025,24 +1025,31 @@ export class ExtrudeSolid extends Entity
}
return grooves;
}
project.ApplyMatrix(target.OCSInv);
// project.ApplyMatrix(target.OCSInv);
project.Z0();
let c1 = Contour.CreateContour(project);
let c2 = Contour.CreateContour(target.ContourCurve);
//投影轮廓列表
let contours = c1.IntersectionBoolOperation(c2);
let outlines: ExtureContourCurve[] = [];
for (let c of contours)
{
if (c.Curve instanceof Polyline)
outlines.push(...PolylineSpliteRect(c.Curve));
else
outlines.push(c.Curve);
}
let xv = this.Normal;
let zv = target.Normal;
let yv = zv.clone().cross(xv);
//把<投影轮廓>对齐到肉的侧面坐标系上
let projection2SideMatrix4 = new Matrix4().makeBasis(xv, yv, zv);
for (let c of contours)
for (let c of outlines)
{
let g = target.Clone().ClearDraw();
let gs = [g];
g.ContourCurve = c.Curve;
g.ContourCurve = c;
g.GrooveCheckAll(gs);
for (let g1 of gs)
@ -1928,7 +1935,7 @@ function ProjectBoard(knifBoard: ExtrudeSolid, projectBoard: ExtrudeSolid)
}));
pl.CloseMark = true;
pl.ApplyMatrix(knifBoard.OCS);
// pl.ApplyMatrix(knifBoard.OCS);
return pl;
}

@ -180,9 +180,9 @@ export function createLookAtMat4(dir: Vector3): Matrix4
/**
* 2,,
*/
export function isParallelTo(v1: Vector3, v2: Vector3): boolean
export function isParallelTo(v1: Vector3, v2: Vector3, fuzz = 1e-8): boolean
{
return v1.clone().cross(v2).lengthSq() < 1e-8;
return v1.clone().cross(v2).lengthSq() < fuzz;
}
/**

Loading…
Cancel
Save