优化:点在多段线内部的算法,避免点在线上时认为在多段线内部

pull/2249/MERGE
ChenX 1 year ago
parent 719dbbf6df
commit 73d2fd0a99

@ -60,7 +60,7 @@ exports[`极限共线 1`] = `432`;
exports[`极限共线 2`] = `294`;
exports[`构建盖子失败2 1`] = `441`;
exports[`构建盖子失败2 1`] = `432`;
exports[`构建盖子失败2 2`] = `282`;

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

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

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

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

@ -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的盖子生成轮廓失败了!");

Loading…
Cancel
Save