!436 修复平行线倒角,多段线与曲线倒角

pull/436/MERGE
ChenX 5 years ago
parent d6658e7978
commit 0deb962685

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -335,6 +335,31 @@ test('自交多段线R0', () =>
let pts = [new Vector3(4759.472137764609, -479.7070785210667, 0), new Vector3(6024.774672494344, 265.369726606551, 0), new Vector3(5976.082363634626, 748.2320220970707, 0), new Vector3(6672.691303327904, 807.7793855808623, 0), new Vector3(6683.501141538695, 782.8164602281072, 0), new Vector3(6586.348726590796, 528.4389981312158, 0), new Vector3(6696.36087689051, 753.119751786805, 0), new Vector3(7099.123174513582, 768.6481023223804, 0), new Vector3(6658.806811968616, 562.3819760828667, 0), new Vector3(6851.152936781651, 395.661799048499, 0), new Vector3(6890.235750785234, 305.4087027928025, 0), new Vector3(7047.556803344554, 744.4918443904984, 0)]; let pts = [new Vector3(4759.472137764609, -479.7070785210667, 0), new Vector3(6024.774672494344, 265.369726606551, 0), new Vector3(5976.082363634626, 748.2320220970707, 0), new Vector3(6672.691303327904, 807.7793855808623, 0), new Vector3(6683.501141538695, 782.8164602281072, 0), new Vector3(6586.348726590796, 528.4389981312158, 0), new Vector3(6696.36087689051, 753.119751786805, 0), new Vector3(7099.123174513582, 768.6481023223804, 0), new Vector3(6658.806811968616, 562.3819760828667, 0), new Vector3(6851.152936781651, 395.661799048499, 0), new Vector3(6890.235750785234, 305.4087027928025, 0), new Vector3(7047.556803344554, 744.4918443904984, 0)];
for (let i = 0; i + 1 < pts.length; i = i + 2)
{
let p1 = pts[i];
let p2 = pts[i + 1];
let e1 = new PromptEntityResult(pl, p1);
let e2 = new PromptEntityResult(pl, p2);
let fres = fillet.Fillet(e1, e2);
excepeRes(fres);
}
});
test('多段线平行倒圆弧', () =>
{
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, [697.5655502392347, 300.3177033492824], 0, [1666.4995215311, 300.3177033492824], 0, [1666.4995215311, 1182.5990430622012], 0, [697.5655502392347, 1182.5990430622012], 0, true]
let pl = LoadEntityFromFileData(f)[0] as Polyline;
let fillet = new FilletUtils();
fillet.FilletRadius = 10;
let pts = [new Vector3(697.5655502392347, 1007.4491640902602, 0), new Vector3(1666.4995215311, 999.8584025880182, 0), new Vector3(1011.2689613363971, 300.3177033492824, 0), new Vector3(1056.8135303498493, 1182.5990430622012, 0), new Vector3(697.5655502392347, 458.38408209475665, 0), new Vector3(1666.4995215311, 450.79332059251453, 0)];
for (let i = 0; i + 1 < pts.length; i = i + 2) for (let i = 0; i + 1 < pts.length; i = i + 2)
{ {
let p1 = pts[i]; let p1 = pts[i];

@ -6,6 +6,12 @@ exports[`圆弧跨越分割线 1`] = `"1420.95209"`;
exports[`多段线双圆R0 1`] = `"5151.46930"`; exports[`多段线双圆R0 1`] = `"5151.46930"`;
exports[`多段线平行倒圆弧 1`] = `"4255.49457"`;
exports[`多段线平行倒圆弧 2`] = `"4206.03357"`;
exports[`多段线平行倒圆弧 3`] = `"4255.49457"`;
exports[`自交多段线 1`] = `"7791.00495"`; exports[`自交多段线 1`] = `"7791.00495"`;
exports[`自交多段线 2`] = `"9003.48566"`; exports[`自交多段线 2`] = `"9003.48566"`;

@ -2,19 +2,19 @@
exports[`IKKGK圆与直线补圆弧 1`] = `1`; exports[`IKKGK圆与直线补圆弧 1`] = `1`;
exports[`IKKGK圆与直线补圆弧 2`] = `44.99893545255323`; exports[`IKKGK圆与直线补圆弧 2`] = `"44.99894"`;
exports[`IKKGK圆与直线补圆弧 3`] = `1`; exports[`IKKGK圆与直线补圆弧 3`] = `1`;
exports[`IKKGK圆与直线补圆弧 4`] = `44.998935452553226`; exports[`IKKGK圆与直线补圆弧 4`] = `"44.99894"`;
exports[`IKKGK圆与直线补圆弧 5`] = `1`; exports[`IKKGK圆与直线补圆弧 5`] = `1`;
exports[`IKKGK圆与直线补圆弧 6`] = `52.526991974363945`; exports[`IKKGK圆与直线补圆弧 6`] = `"52.52699"`;
exports[`中间区域需要圆裁剪 1`] = `1`; exports[`中间区域需要圆裁剪 1`] = `1`;
exports[`中间区域需要圆裁剪 2`] = `24.711300177432427`; exports[`中间区域需要圆裁剪 2`] = `"24.71130"`;
exports[`圆求交错误导致的线丢失 1`] = `4148.6552839918695`; exports[`圆求交错误导致的线丢失 1`] = `4148.6552839918695`;
@ -46,51 +46,51 @@ exports[`圆求交错误导致的线丢失 14`] = `6316.980887212943`;
exports[`复杂圆盘选点 1`] = `1`; exports[`复杂圆盘选点 1`] = `1`;
exports[`复杂圆盘选点 2`] = `197.02551075687774`; exports[`复杂圆盘选点 2`] = `"197.02551"`;
exports[`复杂圆盘选点 3`] = `1`; exports[`复杂圆盘选点 3`] = `1`;
exports[`复杂圆盘选点 4`] = `190.82843823827838`; exports[`复杂圆盘选点 4`] = `"190.82844"`;
exports[`复杂圆盘选点 5`] = `1`; exports[`复杂圆盘选点 5`] = `1`;
exports[`复杂圆盘选点 6`] = `204.54080647675428`; exports[`复杂圆盘选点 6`] = `"204.54081"`;
exports[`复杂圆盘选点 7`] = `1`; exports[`复杂圆盘选点 7`] = `1`;
exports[`复杂圆盘选点 8`] = `205.5702779513265`; exports[`复杂圆盘选点 8`] = `"205.57028"`;
exports[`复杂圆盘选点 9`] = `1`; exports[`复杂圆盘选点 9`] = `1`;
exports[`复杂圆盘选点 10`] = `206.8233228255668`; exports[`复杂圆盘选点 10`] = `"206.82332"`;
exports[`多段线因为合并问题造成的错误 1`] = `1`; exports[`多段线因为合并问题造成的错误 1`] = `1`;
exports[`多段线因为合并问题造成的错误 2`] = `2210.3833040297086`; exports[`多段线因为合并问题造成的错误 2`] = `"2210.38330"`;
exports[`多段线存在0长度线段导致偏移错误 1`] = `1`; exports[`多段线存在0长度线段导致偏移错误 1`] = `1`;
exports[`多段线存在0长度线段导致偏移错误 2`] = `81933.70549460052`; exports[`多段线存在0长度线段导致偏移错误 2`] = `"81933.70549"`;
exports[`多段线存在0长度线段导致偏移错误 3`] = `1`; exports[`多段线存在0长度线段导致偏移错误 3`] = `1`;
exports[`多段线存在0长度线段导致偏移错误 4`] = `86144.16549499573`; exports[`多段线存在0长度线段导致偏移错误 4`] = `"86144.16549"`;
exports[`拱门偏移 1`] = `1`; exports[`拱门偏移 1`] = `1`;
exports[`拱门偏移 2`] = `4.314159265358979`; exports[`拱门偏移 2`] = `"4.31416"`;
exports[`拱门偏移 3`] = `1`; exports[`拱门偏移 3`] = `1`;
exports[`拱门偏移 4`] = `6.827433388230814`; exports[`拱门偏移 4`] = `"6.82743"`;
exports[`海豚圆选点导致的错误 1`] = `1`; exports[`海豚圆选点导致的错误 1`] = `1`;
exports[`海豚圆选点导致的错误 2`] = `1591.1982232513815`; exports[`海豚圆选点导致的错误 2`] = `"1591.19822"`;
exports[`海豚圆选点导致的错误 3`] = `1`; exports[`海豚圆选点导致的错误 3`] = `1`;
exports[`海豚圆选点导致的错误 4`] = `1827.6352392619826`; exports[`海豚圆选点导致的错误 4`] = `"1827.63524"`;
exports[`简单图形因为点在线内算法错误导致的丢失 1`] = `8.675189454805244`; exports[`简单图形因为点在线内算法错误导致的丢失 1`] = `8.675189454805244`;
@ -102,11 +102,11 @@ exports[`简单图形因为点在线内算法错误导致的丢失 4`] = `6.0456
exports[`纯圆生成的多段线偏移 1`] = `1`; exports[`纯圆生成的多段线偏移 1`] = `1`;
exports[`纯圆生成的多段线偏移 2`] = `7585.215254159188`; exports[`纯圆生成的多段线偏移 2`] = `"7585.21525"`;
exports[`纯圆生成的多段线偏移 3`] = `1`; exports[`纯圆生成的多段线偏移 3`] = `1`;
exports[`纯圆生成的多段线偏移 4`] = `6328.578192723271`; exports[`纯圆生成的多段线偏移 4`] = `"6328.57819"`;
exports[`补充bug测试 1`] = `7385.123391644449`; exports[`补充bug测试 1`] = `7385.123391644449`;
@ -114,91 +114,91 @@ exports[`补充bug测试 2`] = `7455.861403941378`;
exports[`补圆弧测试 补圆弧测试1 1`] = `1`; exports[`补圆弧测试 补圆弧测试1 1`] = `1`;
exports[`补圆弧测试 补圆弧测试1 2`] = `202.39253405175808`; exports[`补圆弧测试 补圆弧测试1 2`] = `"202.39253"`;
exports[`补圆弧测试 补圆弧测试1 3`] = `1`; exports[`补圆弧测试 补圆弧测试1 3`] = `1`;
exports[`补圆弧测试 补圆弧测试1 4`] = `202.97120101469034`; exports[`补圆弧测试 补圆弧测试1 4`] = `"202.97120"`;
exports[`补圆弧测试 补圆弧测试1 5`] = `1`; exports[`补圆弧测试 补圆弧测试1 5`] = `1`;
exports[`补圆弧测试 补圆弧测试1 6`] = `203.6336810139832`; exports[`补圆弧测试 补圆弧测试1 6`] = `"203.63368"`;
exports[`补圆弧测试 补圆弧测试1 7`] = `1`; exports[`补圆弧测试 补圆弧测试1 7`] = `1`;
exports[`补圆弧测试 补圆弧测试1 8`] = `204.40243508941455`; exports[`补圆弧测试 补圆弧测试1 8`] = `"204.40244"`;
exports[`补圆弧测试 补圆弧测试1 9`] = `1`; exports[`补圆弧测试 补圆弧测试1 9`] = `1`;
exports[`补圆弧测试 补圆弧测试1 10`] = `205.30936570465022`; exports[`补圆弧测试 补圆弧测试1 10`] = `"205.30937"`;
exports[`补圆弧测试 补圆弧测试1 11`] = `1`; exports[`补圆弧测试 补圆弧测试1 11`] = `1`;
exports[`补圆弧测试 补圆弧测试1 12`] = `206.40161902342368`; exports[`补圆弧测试 补圆弧测试1 12`] = `"206.40162"`;
exports[`补圆弧测试 补圆弧测试1 13`] = `1`; exports[`补圆弧测试 补圆弧测试1 13`] = `1`;
exports[`补圆弧测试 补圆弧测试1 14`] = `207.75245158170867`; exports[`补圆弧测试 补圆弧测试1 14`] = `"207.75245"`;
exports[`补圆弧测试 补圆弧测试1 15`] = `1`; exports[`补圆弧测试 补圆弧测试1 15`] = `1`;
exports[`补圆弧测试 补圆弧测试1 16`] = `209.48342742923182`; exports[`补圆弧测试 补圆弧测试1 16`] = `"209.48343"`;
exports[`补圆弧测试 补圆弧测试1 17`] = `1`; exports[`补圆弧测试 补圆弧测试1 17`] = `1`;
exports[`补圆弧测试 补圆弧测试1 18`] = `211.81548185565424`; exports[`补圆弧测试 补圆弧测试1 18`] = `"211.81548"`;
exports[`补圆弧测试 补圆弧测试1 19`] = `1`; exports[`补圆弧测试 补圆弧测试1 19`] = `1`;
exports[`补圆弧测试 补圆弧测试1 20`] = `215.20917509215795`; exports[`补圆弧测试 补圆弧测试1 20`] = `"215.20918"`;
exports[`补圆弧测试 补圆弧测试1 21`] = `1`; exports[`补圆弧测试 补圆弧测试1 21`] = `1`;
exports[`补圆弧测试 补圆弧测试1 22`] = `220.89156198708565`; exports[`补圆弧测试 补圆弧测试1 22`] = `"220.89156"`;
exports[`补圆弧测试 补圆弧测试1 23`] = `1`; exports[`补圆弧测试 补圆弧测试1 23`] = `1`;
exports[`补圆弧测试 补圆弧测试1 24`] = `243.05208882995845`; exports[`补圆弧测试 补圆弧测试1 24`] = `"243.05209"`;
exports[`补圆弧测试 补圆弧测试1 25`] = `1`; exports[`补圆弧测试 补圆弧测试1 25`] = `1`;
exports[`补圆弧测试 补圆弧测试1 26`] = `236.7000505929851`; exports[`补圆弧测试 补圆弧测试1 26`] = `"236.70005"`;
exports[`补圆弧测试 补圆弧测试1 27`] = `1`; exports[`补圆弧测试 补圆弧测试1 27`] = `1`;
exports[`补圆弧测试 补圆弧测试1 28`] = `236.7000505929851`; exports[`补圆弧测试 补圆弧测试1 28`] = `"236.70005"`;
exports[`补圆弧测试 补圆弧测试1 29`] = `1`; exports[`补圆弧测试 补圆弧测试1 29`] = `1`;
exports[`补圆弧测试 补圆弧测试1 30`] = `205.63007530643267`; exports[`补圆弧测试 补圆弧测试1 30`] = `"205.63008"`;
exports[`补圆弧测试 补圆弧测试1 31`] = `1`; exports[`补圆弧测试 补圆弧测试1 31`] = `1`;
exports[`补圆弧测试 补圆弧测试1 32`] = `198.5522282383345`; exports[`补圆弧测试 补圆弧测试1 32`] = `"198.55223"`;
exports[`补圆弧测试 补圆弧测试1 33`] = `1`; exports[`补圆弧测试 补圆弧测试1 33`] = `1`;
exports[`补圆弧测试 补圆弧测试1 34`] = `195.9134975736565`; exports[`补圆弧测试 补圆弧测试1 34`] = `"195.91350"`;
exports[`补圆弧测试 补圆弧测试1 35`] = `1`; exports[`补圆弧测试 补圆弧测试1 35`] = `1`;
exports[`补圆弧测试 补圆弧测试1 36`] = `194.55187803685857`; exports[`补圆弧测试 补圆弧测试1 36`] = `"194.55188"`;
exports[`补圆弧测试 补圆弧测试1 37`] = `1`; exports[`补圆弧测试 补圆弧测试1 37`] = `1`;
exports[`补圆弧测试 补圆弧测试1 38`] = `193.73994771001938`; exports[`补圆弧测试 补圆弧测试1 38`] = `"193.73995"`;
exports[`补圆弧测试 补圆弧测试1 39`] = `1`; exports[`补圆弧测试 补圆弧测试1 39`] = `1`;
exports[`补圆弧测试 补圆弧测试1 40`] = `193.2116587563558`; exports[`补圆弧测试 补圆弧测试1 40`] = `"193.21166"`;
exports[`补圆弧测试 补圆弧测试1 41`] = `1`; exports[`补圆弧测试 补圆弧测试1 41`] = `1`;
exports[`补圆弧测试 补圆弧测试1 42`] = `192.84673020284998`; exports[`补圆弧测试 补圆弧测试1 42`] = `"192.84673"`;
exports[`补圆弧测试 补圆弧测试1 43`] = `1`; exports[`补圆弧测试 补圆弧测试1 43`] = `1`;
exports[`补圆弧测试 补圆弧测试1 44`] = `192.58327191623619`; exports[`补圆弧测试 补圆弧测试1 44`] = `"192.58327"`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 1`] = `54789.24964851234`; exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 1`] = `54789.24964851234`;

@ -2,6 +2,8 @@ import { Factory } from "../../src/DatabaseServices/CADFactory";
import { Curve } from "../../src/DatabaseServices/Entity/Curve"; import { Curve } from "../../src/DatabaseServices/Entity/Curve";
import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
import "../Utils/jest.util";
Factory(Polyline); Factory(Polyline);
function loadFile(data) function loadFile(data)
@ -14,7 +16,7 @@ function EntityToMatchSnapshot(ens: Curve[])
expect(ens.length).toMatchSnapshot(); expect(ens.length).toMatchSnapshot();
for (let c of ens) for (let c of ens)
{ {
expect(c.Length).toMatchSnapshot(); expect(c.Length).toMatchNumberSnapshot();
} }
} }

@ -63,9 +63,16 @@ export class CommandFillet implements Command
res2.Entity.UpdateJigMaterial(); res2.Entity.UpdateJigMaterial();
lastCu = res2.Entity as Curve; lastCu = res2.Entity as Curve;
let fres = this.m_FilletUtils.Fillet(enRes1, res2); let fres = this.m_FilletUtils.Fillet(enRes1, res2);
for (let v in fres)
if (fres[v]) if (fres)
JigUtils.Draw(fres[v]) {
if (fres.arc)
JigUtils.Draw(fres.arc);
if (fres.cu1)
JigUtils.Draw(fres.cu1);
if (fres.cu2)
JigUtils.Draw(fres.cu2);
}
app.Editor.UpdateScreen(); app.Editor.UpdateScreen();
} }
let keydownUpdateRadius = (e: KeyboardEvent) => let keydownUpdateRadius = (e: KeyboardEvent) =>

@ -1,5 +1,5 @@
import { Matrix4, Vector3 } from "three"; import { Matrix4, Vector3 } from "three";
import { curveLinkGroup, GetPointAtCurveDir } from "../Common/CurveUtils"; import { GetPointAtCurveDir } from "../Common/CurveUtils";
import { Arc } from "../DatabaseServices/Entity/Arc"; import { Arc } from "../DatabaseServices/Entity/Arc";
import { Board } from "../DatabaseServices/Entity/Board"; import { Board } from "../DatabaseServices/Entity/Board";
import { Circle } from "../DatabaseServices/Entity/Circle"; import { Circle } from "../DatabaseServices/Entity/Circle";
@ -8,9 +8,9 @@ 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 { Polyline } from "../DatabaseServices/Entity/Polyline";
import { Spline } from "../DatabaseServices/Spline"; import { Spline } from "../DatabaseServices/Spline";
import { JigUtils } from "../Editor/JigUtils";
import { PromptEntityResult, PromptPointResult } from "../Editor/PromptResult"; import { PromptEntityResult, PromptPointResult } from "../Editor/PromptResult";
import { angle, AsVector2, equalv3, isParallelTo, midPoint } from "../Geometry/GeUtils"; import { angle, AsVector2, equalv3, isIntersect2, isParallelTo, midPoint } from "../Geometry/GeUtils";
import { Orbit } from "../Geometry/Orbit";
import { IntersectOption } from "../GraphicsSystem/IntersectWith"; import { IntersectOption } from "../GraphicsSystem/IntersectWith";
function Encode(res: PromptEntityResult, enMap: (PromptEntityResult[])[]) function Encode(res: PromptEntityResult, enMap: (PromptEntityResult[])[])
@ -57,7 +57,7 @@ function CircleEnResToArc(enRes: PromptEntityResult)
} }
} }
function GetFilletCurve(enRes: PromptEntityResult): any[] function GetFilletCurve(enRes: PromptEntityResult): [Curve, number]
{ {
if (enRes.Entity instanceof Polyline) if (enRes.Entity instanceof Polyline)
{ {
@ -67,7 +67,7 @@ function GetFilletCurve(enRes: PromptEntityResult): any[]
return [pl.GetCurveAtParam(param), paramF]; return [pl.GetCurveAtParam(param), paramF];
} }
else else
return [enRes.Entity, NaN]; return [enRes.Entity as Curve, NaN];
} }
enum ExtendType enum ExtendType
@ -79,7 +79,9 @@ enum ExtendType
export interface FilletRes export interface FilletRes
{ {
cu1?: Curve; cu1?: Curve;
cu1Extend?: ExtendType;
cu2?: Curve; cu2?: Curve;
cu2Extend?: ExtendType;
arc?: Arc; arc?: Arc;
} }
@ -193,6 +195,10 @@ export class FilletUtils
this.ExtendPt(splitedCu1, arcP1); this.ExtendPt(splitedCu1, arcP1);
this.ExtendPt(splitedCu2, arcP2); this.ExtendPt(splitedCu2, arcP2);
} }
res.cu1Extend = splitedCu1.ExtType;
res.cu2Extend = splitedCu2.ExtType;
return res; return res;
} }
FilletPolyLineSelf(enRes1: PromptEntityResult, enRes2: PromptEntityResult): FilletRes FilletPolyLineSelf(enRes1: PromptEntityResult, enRes2: PromptEntityResult): FilletRes
@ -241,14 +247,14 @@ export class FilletUtils
if (fres.cu2 instanceof Arc) if (fres.cu2 instanceof Arc)
pln.SetBulgeAt(parF2, fres.cu2.Bul); pln.SetBulgeAt(parF2, fres.cu2.Bul);
let splitType1 = equalv3(c1.StartPoint, fres.cu1.StartPoint); let splitType1 = fres.cu1Extend;
let splitType2 = equalv3(c2.StartPoint, fres.cu2.StartPoint); let splitType2 = fres.cu2Extend;
if (splitType1 === splitType2) if (splitType1 === splitType2)
return; return;
if (!fres.arc) if (!fres.arc)
{ {
if (splitType1) if (splitType1 === ExtendType.End)
{ {
let ep = AsVector2(fres.cu1.EndPoint.applyMatrix4(pln.OCSInv)); let ep = AsVector2(fres.cu1.EndPoint.applyMatrix4(pln.OCSInv));
pln.SetPointAt(parF1 + 1, ep); pln.SetPointAt(parF1 + 1, ep);
@ -275,7 +281,7 @@ export class FilletUtils
} }
} }
if (splitType1)//没有经过起点 if (splitType1 === ExtendType.End)//没有经过起点
{ {
let sp = AsVector2(fres.cu1.EndPoint.applyMatrix4(pln.OCSInv)); let sp = AsVector2(fres.cu1.EndPoint.applyMatrix4(pln.OCSInv));
if (parF2 - parF1 === 1) if (parF2 - parF1 === 1)
@ -334,24 +340,42 @@ export class FilletUtils
let fres = this.Fillet(es1, es2); let fres = this.Fillet(es1, es2);
if (fres) if (fres)
{ {
let pln: Polyline;
let isFirst = false;
let cus: Curve[] = []; let cus: Curve[] = [];
let isFirst = false;
if (fres.cu1) if (fres.cu1)
{ {
if (enRes1.Entity instanceof Polyline) if (enRes1.Entity instanceof Polyline)
{ {
isFirst = true; isFirst = true;
pln = enRes1.Entity.Clone(); let pln = enRes1.Entity.Clone();
pln.DigestionCloseMark();
let xcus = enRes1.Entity.Explode(); if (fres.cu1 instanceof Arc)
xcus[paramF1] = fres.cu1; pln.SetBulgeAt(paramF1, fres.cu1.Bul);
cus.push(...xcus);
if (fres.cu1Extend === ExtendType.End)
{
pln.LineData.splice(paramF1 + 2);
let ep = AsVector2(fres.cu1.EndPoint.applyMatrix4(pln.OCSInv));
pln.SetPointAt(paramF1 + 1, ep);
}
else
{
pln.LineData.splice(0, paramF1);
let sp = AsVector2(fres.cu1.StartPoint.applyMatrix4(pln.OCSInv));
pln.SetPointAt(0, sp);
}
cus.push(pln);
} }
//@ts-ignore //@ts-ignore
else if (!enRes1.IsCircle) else if (!enRes1.IsCircle)
cus.push(fres.cu1); cus.push(fres.cu1);
} }
if (fres.arc) if (fres.arc)
cus.push(fres.arc); cus.push(fres.arc);
@ -359,34 +383,49 @@ export class FilletUtils
{ {
if (enRes2.Entity instanceof Polyline) if (enRes2.Entity instanceof Polyline)
{ {
if (!pln) let pln = enRes2.Entity.Clone();
pln = enRes2.Entity.Clone(); pln.DigestionCloseMark();
if (fres.cu2 instanceof Arc)
pln.SetBulgeAt(paramF2, fres.cu2.Bul);
if (fres.cu2Extend === ExtendType.End)
{
pln.LineData.splice(paramF2 + 2);
let xcus = enRes2.Entity.Explode(); let ep = AsVector2(fres.cu2.EndPoint.applyMatrix4(pln.OCSInv));
xcus[paramF2] = fres.cu2; pln.SetPointAt(paramF2 + 1, ep);
cus.push(...xcus); }
else
{
pln.LineData.splice(0, paramF2);
let sp = AsVector2(fres.cu2.StartPoint.applyMatrix4(pln.OCSInv));
pln.SetPointAt(0, sp);
}
cus.push(pln);
cus.reverse();
} }
//@ts-ignore //@ts-ignore
else if (!enRes2.IsCircle) else if (!enRes2.IsCircle)
cus.push(fres.cu2); cus.push(fres.cu2);
} }
let groups = curveLinkGroup(cus); if (cus.length > 0)
for (let g of groups)
{
if (g.includes(fres.cu1) || g.includes(fres.cu2))
{ {
pln.LineData = []; let pl = cus[0] as Polyline;
pln.ApplyMatrix(pln.OCSInv); if (!(pl instanceof Polyline))
pln.CloseMark = false; return;
for (let cu of g)
pln.Join(cu); for (let i = 1; i < cus.length; i++)
pl.Join(cus[i]);
if (isFirst) if (isFirst)
return { cu1: pln, cu2: undefined, arc: undefined }; return { cu1: pl };
else else
return { cu1: undefined, cu2: pln, arc: undefined }; return { cu2: pl };
}
} }
} }
return undefined; return undefined;
@ -501,9 +540,6 @@ export class FilletUtils
/** /**
* 线 * 线
* @param enRes1
* @param enRes2
* @returns parallel line
*/ */
private FilletParallelLine(enRes1: PromptEntityResult, enRes2: PromptEntityResult): FilletRes private FilletParallelLine(enRes1: PromptEntityResult, enRes2: PromptEntityResult): FilletRes
{ {
@ -514,9 +550,15 @@ export class FilletUtils
if (!isParallelTo(l1Derv, l2.GetFistDeriv(0))) if (!isParallelTo(l1Derv, l2.GetFistDeriv(0)))
return; return;
let vec = l2.StartPoint.sub(l1.StartPoint);
if (isParallelTo(vec, l1Derv))
return;
let planeNormal = vec.cross(l1Derv).normalize();
let par1 = l2.GetClosestAtPoint(l1.StartPoint, true).param; let par1 = l2.GetClosestAtPoint(l1.StartPoint, true).param;
let par2 = l2.GetClosestAtPoint(l1.EndPoint, true).param; let par2 = l2.GetClosestAtPoint(l1.EndPoint, true).param;
if (!l1.ParamOnCurve(par1) && !l1.ParamOnCurve(par2)) if (!isIntersect2(0, 1, par1, par2))
return; return;
let lineClone1 = l1.Clone(); let lineClone1 = l1.Clone();
@ -527,27 +569,56 @@ export class FilletUtils
let parFix = Math.round(par); let parFix = Math.round(par);
let ptFix = lineClone1.GetPointAtParam(parFix); let ptFix = lineClone1.GetPointAtParam(parFix);
let ptL2Fix = lineClone2.GetClosestAtPoint(ptFix, true).closestPt; let ptL2Fix = lineClone2.GetClosestAtPoint(ptFix, true).closestPt;
let cu1Extend = parFix === 0 ? ExtendType.Start : ExtendType.End;
let cu2Extend: ExtendType;
if ((par1 > par2) === (parFix === 1)) if ((par1 > par2) === (parFix === 1))
{
lineClone2.StartPoint = ptL2Fix; lineClone2.StartPoint = ptL2Fix;
cu2Extend = ExtendType.Start;
}
else else
{
lineClone2.EndPoint = ptL2Fix; lineClone2.EndPoint = ptL2Fix;
cu2Extend = ExtendType.End;
}
let radius = ptFix.distanceTo(ptL2Fix) / 2;
if (radius < 1e-3)
return;
let arcCenter = midPoint(ptFix, ptL2Fix); let arcCenter = midPoint(ptFix, ptL2Fix);
let sv = ptFix.sub(arcCenter).applyMatrix4(l1.OCSInv); let sv = ptFix.sub(arcCenter);
let ev = ptL2Fix.sub(arcCenter).applyMatrix4(l2.OCSInv); let ev = ptL2Fix.sub(arcCenter);
if (parFix === 0) if (parFix === 0)
l1Derv.negate(); l1Derv.negate();
let arc = new Arc(new Vector3(), ptFix.distanceTo(ptL2Fix) / 2, angle(sv), angle(ev), ev.cross(l1Derv.applyMatrix4(l1.OCSInv)).z > 0); //平面矩阵
arc.ApplyMatrix(l1.OCS); let xVec = new Vector3();
let yVec = new Vector3();
Orbit.ComputUpDirection(planeNormal, yVec, xVec);
let mtx = new Matrix4().makeBasis(xVec, yVec, planeNormal.negate());
let mtxInv = new Matrix4().getInverse(mtx);
//变换
sv.applyMatrix4(mtxInv);
ev.applyMatrix4(mtxInv);
l1Derv.applyMatrix4(mtxInv);
let sa = angle(sv);
let ea = angle(ev);
let clockwise = ev.cross(l1Derv).z > 0;
let arc = new Arc(new Vector3(), radius, sa, ea, clockwise);
arc.ApplyMatrix(mtx);
arc.Center = arcCenter; arc.Center = arcCenter;
return { return {
cu1: lineClone1, cu1: lineClone1,
cu1Extend,
cu2: lineClone2, cu2: lineClone2,
arc cu2Extend,
arc,
}; };
} }

@ -354,7 +354,8 @@ export class Polyline extends Curve
//闭合且起点不等于终点 //闭合且起点不等于终点
if (this.m_ClosedMark && if (this.m_ClosedMark &&
!this.m_LineData[0].pt.equals(arrayLast(this.m_LineData).pt)) !equalv2(this.m_LineData[0].pt, arrayLast(this.m_LineData).pt)
)
return this.m_LineData.length; return this.m_LineData.length;
return this.m_LineData.length - 1; return this.m_LineData.length - 1;
} }
@ -405,6 +406,19 @@ export class Polyline extends Curve
this.m_ClosedMark = v; this.m_ClosedMark = v;
this.Update() this.Update()
} }
DigestionCloseMark()
{
if (this.m_ClosedMark && this.m_LineData.length > 1)
{
this.WriteAllObjectRecord();
this.m_ClosedMark = false;
if (!equalv2(this.m_LineData[0].pt, arrayLast(this.m_LineData).pt))
this.m_LineData.push({ pt: AsVector2(this.m_LineData[0].pt), bul: 0 });
}
}
get Length() get Length()
{ {
return this.Explode().reduce((l, cu) => l + cu.Length, 0); return this.Explode().reduce((l, cu) => l + cu.Length, 0);

@ -23,6 +23,13 @@ export function isIntersect(amin: number, amax: number, bmin: number, bmax: numb
return Math.max(amin, bmin) < Math.min(amax, bmax) + eps; return Math.max(amin, bmin) < Math.min(amax, bmax) + eps;
} }
export function isIntersect2(a1: number, a2: number, b1: number, b2: number, eps = 0)
{
if (a1 > a2) [a1, a2] = [a2, a1];
if (b1 > b2) [b1, b2] = [b2, b1];
return Math.max(a1, b1) < Math.min(a2, b2) + eps;
}
/** /**
* , * ,
* @param {Vector3} p * @param {Vector3} p

Loading…
Cancel
Save