From 73d2fd0a9930d2ef5ce7a54935e8438f6b1a0033 Mon Sep 17 00:00:00 2001 From: ChenX Date: Thu, 15 Jun 2023 16:09:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96:=E7=82=B9=E5=9C=A8=E5=A4=9A?= =?UTF-8?q?=E6=AE=B5=E7=BA=BF=E5=86=85=E9=83=A8=E7=9A=84=E7=AE=97=E6=B3=95?= =?UTF-8?q?,=E9=81=BF=E5=85=8D=E7=82=B9=E5=9C=A8=E7=BA=BF=E4=B8=8A?= =?UTF-8?q?=E6=97=B6=E8=AE=A4=E4=B8=BA=E5=9C=A8=E5=A4=9A=E6=AE=B5=E7=BA=BF?= =?UTF-8?q?=E5=86=85=E9=83=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__snapshots__/EdgeGeometry.test.ts.snap | 2 +- __test__/Polyline/PtInPolylineDir.test.ts | 19 ++++++++-- __test__/Polyline/offset.test.ts | 7 ---- __test__/Polyline/offset4.test.ts | 7 +++- src/DatabaseServices/PointInPolyline.ts | 38 +++++++++++++++---- .../ExtrudeEdgeGeometry2.ts | 5 ++- 6 files changed, 55 insertions(+), 23 deletions(-) diff --git a/__test__/Geometry/__snapshots__/EdgeGeometry.test.ts.snap b/__test__/Geometry/__snapshots__/EdgeGeometry.test.ts.snap index ca614145d..6761447e9 100644 --- a/__test__/Geometry/__snapshots__/EdgeGeometry.test.ts.snap +++ b/__test__/Geometry/__snapshots__/EdgeGeometry.test.ts.snap @@ -60,7 +60,7 @@ exports[`极限共线 1`] = `432`; exports[`极限共线 2`] = `294`; -exports[`构建盖子失败2 1`] = `441`; +exports[`构建盖子失败2 1`] = `432`; exports[`构建盖子失败2 2`] = `282`; diff --git a/__test__/Polyline/PtInPolylineDir.test.ts b/__test__/Polyline/PtInPolylineDir.test.ts index 15c6defde..160c079fb 100644 --- a/__test__/Polyline/PtInPolylineDir.test.ts +++ b/__test__/Polyline/PtInPolylineDir.test.ts @@ -1,8 +1,10 @@ -import { CADFiler } from '../../src/DatabaseServices/CADFiler'; -import { Polyline } from '../../src/DatabaseServices/Entity/Polyline'; +import { Vector2, Vector3 } from 'three'; import { GetPointAtCurveDir } from '../../src/Common/CurveUtils'; -import { Vector3, Vector2 } from 'three'; import { Factory } from '../../src/DatabaseServices/CADFactory'; +import { CADFiler } from '../../src/DatabaseServices/CADFiler'; +import { Circle } from '../../src/DatabaseServices/Entity/Circle'; +import { Polyline } from '../../src/DatabaseServices/Entity/Polyline'; +import { LoadEntityFromFileData } from '../Utils/LoadEntity.util'; Factory(Polyline); test('2个大圆中间', () => @@ -241,3 +243,14 @@ test('圆弧过大导致直线小角错误', () => isR = GetPointAtCurveDir(pl, pt); expect(isR).toBe(-1); }); + + +test('切线,点在线上', () => +{ + + let d = + { "file": [2, "Polyline", 10, 2, 126, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -405.9814378012583, 366.1257443169635, 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.9999999999999999, [0, -24.613926371726052], 0, [0, -19.48602504428311], -0.9999999999999999, [0, -5.127901327442942], 0, [0, 0], 0, false, "Circle", 10, 2, 135, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -413.1604996596784, 353.8187811311005, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 1, 0.6969724503326413], "basePt": { "x": -418.28840098712135, "y": 341.51181794523745, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let [pl, pt] = LoadEntityFromFileData(d) as [Polyline, Circle]; + + expect(pl.PtInCurve(pt.Center)).toBeFalsy(); +}); diff --git a/__test__/Polyline/offset.test.ts b/__test__/Polyline/offset.test.ts index 5098caddc..c335bb40e 100644 --- a/__test__/Polyline/offset.test.ts +++ b/__test__/Polyline/offset.test.ts @@ -1089,10 +1089,3 @@ test('精度问题导致的连接错误', () => )[0]; testOffset(pl, 2.4254); }); - -test('偏移连接失败', () => -{ - let d = - { "file": [1, "Polyline", 10, 2, 111, 0, 1, 7, 0, [1, 0, 0, 0, 0, 2.220446049250313e-16, 1, 0, 0, -1, 2.220446049250313e-16, 0, 3448.9478393627373, 588.8818635607608, 2277.4901004968165, 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.27588288158564067, [-68.01871597353602, 76.74348620727369], 0.1548304020399718, [-904.2903739294561, 76.74348340440201], 0.27588268439117536, [-972.3091079030273, -0.00014195760331858764], 0, [-9.094947017729282e-13, 4.547473508864641e-13], 0, false], "basePt": { "x": 2476.63873145971, "y": 588.8818635607608, "z": 2277.489958539213 }, "ucs": [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 610.4825291181364, 588.8818635607321, 0, 1] }; - -}); diff --git a/__test__/Polyline/offset4.test.ts b/__test__/Polyline/offset4.test.ts index 68e2b4681..463dfe04f 100644 --- a/__test__/Polyline/offset4.test.ts +++ b/__test__/Polyline/offset4.test.ts @@ -23,8 +23,10 @@ test('圆裁剪精度', () => test("错误的点在多段线内部", () => { - let d = ["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, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 5, [-903.9879626621178, 75.79030586302474], -0.1548304020399718, [-68.32112723448535, 75.79030866386893], 0, [-68.01871597353619, 76.74348620727369], 0.1548304020399718, [-904.2903739294563, 76.74348340440224], 0, [-903.9879626621178, 75.79030586302474], 0, false, -486.15450978803466, 140.48362331381213, 0]; + let d = + [1, "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, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 5, [-903.9879626621178, 75.79030586302474], -0.1548304020399718, [-68.32112723448535, 75.79030866386893], 0, [-68.01871597353619, 76.74348620727369], 0.1548304020399718, [-904.2903739294563, 76.74348340440224], 0, [-903.9879626621178, 75.79030586302474], 0, false, -486.15450978803466, 140.48362331381213, 0]; let f = new CADFiler(d); + f.Read(); let pl = f.ReadObject() as Polyline; let p = new Vector3(f.Read(), f.Read(), f.Read()); expect(pl.PtInCurve(p)).toBeFalsy(); @@ -33,8 +35,9 @@ test("错误的点在多段线内部", () => test('错误的点在多段线内部2', () => { let d = - ["Polyline", 10, 2, 108, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -438.1577281907905, 358.23373269662113, 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, 3, [0, 0], 0.9999999999999999, [-58.58109281699865, 0], -0.7547474747474747, [0, 0], 0, false, -467.44827459928985, 380.3406986324097, 0]; + [1, "Polyline", 10, 2, 108, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -438.1577281907905, 358.23373269662113, 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, 3, [0, 0], 0.9999999999999999, [-58.58109281699865, 0], -0.7547474747474747, [0, 0], 0, false, -467.44827459928985, 380.3406986324097, 0]; let f = new CADFiler(d); + f.Read(); let pl = f.ReadObject() as Polyline; let p = new Vector3(f.Read(), f.Read(), f.Read()); expect(pl.PtInCurve(p)).toBeFalsy(); diff --git a/src/DatabaseServices/PointInPolyline.ts b/src/DatabaseServices/PointInPolyline.ts index 515366a95..a728d1a01 100644 --- a/src/DatabaseServices/PointInPolyline.ts +++ b/src/DatabaseServices/PointInPolyline.ts @@ -1,5 +1,5 @@ import { Vec2, Vector3 } from 'three'; -import { angle, equaln, equalv3 } from '../Geometry/GeUtils'; +import { angle, equaln, equalv2 } from '../Geometry/GeUtils'; import { IntersectOption } from '../GraphicsSystem/IntersectWith'; import { Arc } from './Entity/Arc'; import { Line } from './Entity/Line'; @@ -55,7 +55,7 @@ export function IsPointInBowArc(arc: Arc, pt: Vector3, isInChrodIsTrue = false): } /** - * 判断点在多段线内外 + * 判断点在多段线内外(如果点在线上 则返回false) * @param pl 多段线 * @param pt 点 * @returns 点在多段线内部 @@ -72,13 +72,22 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean { let sp = pl.GetPointAtParam(i); let ep = pl.GetPointAtParam(i + 1); + + if (equalv2(sp, pt, 1e-5) || equalv2(ep, pt, 1e-5))//在起点或者终点 + return false; + //点位于线上面 if (pt.y > Math.max(sp.y, ep.y)) continue; //线垂直Y轴 let derX = ep.x - sp.x; if (equaln(derX, 0, 5e-6)) + { + if (equaln(pt.x, ep.x, 1e-5) + && (pt.y > Math.min(sp.y, ep.y) - 1e-5 && pt.y < Math.max(sp.y, ep.y) + 1e-5)) + return false;//点在线上 continue; + } //起点 if (equaln(sp.x, pt.x, 5e-6)) @@ -100,7 +109,10 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean let derY = ep.y - sp.y; let k = derY / derX; - if ((pt.x - sp.x) * k + sp.y > pt.y) + let iptY = (pt.x - sp.x) * k + sp.y; + if (equaln(iptY, pt.y, 1e-5))//点在线上 返回false + return false; + if (iptY > pt.y) crossings++; } } @@ -110,9 +122,17 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean let sp = arc.StartPoint; let ep = arc.EndPoint; + if (equalv2(sp, pt, 1e-5) || equalv2(ep, pt, 1e-5))//在起点或者终点 + return false; + + let center = arc.Center; //如果相切 - if (equaln(Math.abs(pt.x - arc.Center.x), arc.Radius)) + if (equaln(Math.abs(pt.x - center.x), arc.Radius)) { + //点在线上 + if (equaln(pt.y, center.y) && arc.ParamOnCurve(arc.GetParamAtPoint2(pt))) + return false; + //当点和起点或者终点和点相切时 if (equaln(sp.x, pt.x) && sp.y > pt.y) { @@ -141,12 +161,14 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean for (let pti of arc.IntersectWith(insLine, IntersectOption.ExtendArg)) { - if (pti.y < pt.y || equalv3(sp, pti, 1e-5) || equalv3(ep, pti, 1e-5)) + if (equalv2(pti, pt, 1e-5))//点在线上 返回false + return false; + + //交点在点下 交点在起点? 交点在终点? + if (pti.y + 1e-5 < pt.y || equalv2(sp, pti, 1e-5) || equalv2(ep, pti, 1e-5)) continue; - let der = arc.GetFistDeriv(pti).normalize(); - if (!equaln(der.y, 0, 1e-5)) //相切. - crossings++; + crossings++; } } } diff --git a/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2.ts b/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2.ts index 4057678b9..e2333aa9c 100644 --- a/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2.ts +++ b/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2.ts @@ -362,11 +362,12 @@ class EdgeGeometryBuild for (let l of lines) if (!parse.GetCueveUsed(l)) unusedLines.push(l); - if (unusedLines.length) + if (unusedLines.length > 2) { let groups = curveLinkGroup(unusedLines, 1); for (let g of groups) { + if (g.length < 2) continue; let pl = new Polyline(); pl.ColorIndex = g[0].ColorIndex; pl.OCS = ComputerCurvesNormalOCS(g); @@ -378,7 +379,7 @@ class EdgeGeometryBuild pl.CloseMark = true; let c = Contour.CreateContour(pl, false) ?? CreateContour2(pl.Explode(), 0.1);; - if (c) + if (c && c.Area > 0.1) contourNodes.push(new ContourTreeNode(c)); else console.error("错误:构建板件的MeshGeometry的盖子生成轮廓失败了!");