diff --git a/__test__/Geometry/__snapshots__/intersect.test.ts.snap b/__test__/Geometry/__snapshots__/intersect.test.ts.snap index 5fdbadd8f..d30d9c645 100644 --- a/__test__/Geometry/__snapshots__/intersect.test.ts.snap +++ b/__test__/Geometry/__snapshots__/intersect.test.ts.snap @@ -123,49 +123,66 @@ Array [ `; exports[`三维空间直线相交测试 1`] = ` -Vector3 { - "x": 5, - "y": 5, - "z": 5, -} +Array [ + Vector3 { + "x": 5, + "y": 5, + "z": 5, + }, +] `; exports[`三维空间直线相交测试 2`] = ` -Vector3 { - "x": 4.5, - "y": 4.5, - "z": 4.5, -} +Array [ + Vector3 { + "x": 3, + "y": 3, + "z": 3, + }, + Vector3 { + "x": 6, + "y": 6, + "z": 6, + }, +] `; exports[`三维空间直线相交测试 3`] = ` -Vector3 { - "x": 5, - "y": 5, - "z": 5, -} +Array [ + Vector3 { + "x": 5, + "y": 5, + "z": 5, + }, +] `; exports[`相交测试 1`] = ` -Vector3 { - "x": 0.5, - "y": 0, - "z": 0, -} +Array [ + Vector3 { + "x": 0.5, + "y": 0, + "z": 0, + }, +] `; exports[`相交测试 2`] = ` -Vector3 { - "x": 2, - "y": 0, - "z": 0, -} +Array [ + Vector3 { + "x": 2, + "y": 0, + "z": 0, + }, +] `; exports[`相交测试 3`] = ` -Vector3 { - "x": 0.5, - "y": 5, - "z": 0, -} +Array [ + Vector3 { + "x": 0.5, + "y": 5, + "z": 0, + }, +] `; diff --git a/__test__/Geometry/intersect.test.ts b/__test__/Geometry/intersect.test.ts index b8f77f5c4..ad994deab 100644 --- a/__test__/Geometry/intersect.test.ts +++ b/__test__/Geometry/intersect.test.ts @@ -56,14 +56,14 @@ test('三维空间直线相交测试', () => new Vector3(2, 2, 2), new Vector3(2, 2, 10) ) - expect(res).toBeUndefined(); + expect(res.length).toBe(0); res = IntersectLAndLFor3D( new Vector3(1, 0, 1), new Vector3(1, 0, 4), new Vector3(0.5, 0, 3), new Vector3(0.5, 0, 10) ) - expect(res).toBeUndefined(); + expect(res.length).toBe(0); }) test('三维空间圆圆相交测试', () => { diff --git a/src/Add-on/test/testIntersect.ts b/src/Add-on/test/testIntersect.ts index cc812415d..42be36f7f 100644 --- a/src/Add-on/test/testIntersect.ts +++ b/src/Add-on/test/testIntersect.ts @@ -21,7 +21,7 @@ export class TestIntersect implements Command let exRefSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true }); if (exRefSsRes.Status !== PromptStatus.OK) return; let cus = exRefSsRes.SelectSet.SelectEntityList as Curve[]; - let pt = IntersectLAndLFor3D(cus[0].StartPoint, cus[0].EndPoint, cus[1].StartPoint, cus[1].EndPoint); + let pt = IntersectLAndLFor3D(cus[0].StartPoint, cus[0].EndPoint, cus[1].StartPoint, cus[1].EndPoint)[0]; console.log('pt: ', pt); if (pt) { diff --git a/src/DatabaseServices/Dimension/LineAngularDimension.ts b/src/DatabaseServices/Dimension/LineAngularDimension.ts index c5eace2b6..8459b9850 100644 --- a/src/DatabaseServices/Dimension/LineAngularDimension.ts +++ b/src/DatabaseServices/Dimension/LineAngularDimension.ts @@ -116,7 +116,7 @@ export class LineAngularDimension extends Dimension private getCaclSPtAndEPt() { // 2线交点即为圆心 - let center = IntersectLAndLFor3D(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2); + let center = IntersectLAndLFor3D(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2)[0]; // 获取实际的首尾点,离圆心近的的为起始点 let [spt1, ept1] = this.StartPoint1.distanceTo(center) < this.EndPoint1.distanceTo(center) ? [this.StartPoint1, this.EndPoint1] : [this.EndPoint1, this.StartPoint1]; let [spt2, ept2] = this.StartPoint2.distanceTo(center) < this.EndPoint2.distanceTo(center) ? [this.StartPoint2, this.EndPoint2] : [this.EndPoint2, this.StartPoint2]; @@ -126,7 +126,7 @@ export class LineAngularDimension extends Dimension private getDimArcData() { // 2线交点即为圆心 - let center = IntersectLAndLFor3D(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2); + let center = IntersectLAndLFor3D(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2)[0]; let rad = this.m_ArcPoint.distanceTo(center); let { ept1, ept2 } = this.getCaclSPtAndEPt(); //标注线段的起始端点 diff --git a/src/Editor/SnapServices.ts b/src/Editor/SnapServices.ts index 9c9449591..986a6b89a 100644 --- a/src/Editor/SnapServices.ts +++ b/src/Editor/SnapServices.ts @@ -104,7 +104,7 @@ export class SnapServices for (let j = i + 1; j < snapAxisList.length; j++) { let axis2 = snapAxisList[j]; - let insP = IntersectLAndLFor3D(axis1.BasePoint, axis1.SnapPoint, axis2.BasePoint, axis2.SnapPoint); + let insP = IntersectLAndLFor3D(axis1.BasePoint, axis1.SnapPoint, axis2.BasePoint, axis2.SnapPoint)[0]; if (insP) axisIntersectList.push({ IntersectPoint: insP, diff --git a/src/GraphicsSystem/IntersectWith.ts b/src/GraphicsSystem/IntersectWith.ts index cf02a5f8c..796a1e4ff 100644 --- a/src/GraphicsSystem/IntersectWith.ts +++ b/src/GraphicsSystem/IntersectWith.ts @@ -224,7 +224,7 @@ export function IntersectLAndLFor2D(p1: Vector3, p2: Vector3, p3: Vector3, p4: V return pt; } -export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3) +export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3) { let x12 = p1.x - p2.x; let x43 = p4.x - p3.x; @@ -272,7 +272,7 @@ export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: V } return pt; } -export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3) +export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3) { let x12 = p1.x - p2.x; let x43 = p4.x - p3.x; @@ -284,7 +284,6 @@ export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: let z43 = p4.z - p3.z; let z42 = p4.z - p2.z; - let pt: Vector3; let pts: Vector3[] = []; let v1 = p2.clone().sub(p1).normalize(); let v2 = p4.clone().sub(p3).normalize(); @@ -292,15 +291,15 @@ export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: if (equaln(Math.abs(v1.dot(v2)), 1, 1e-6) && equaln(Math.abs(v1.dot(w)), 1, 1e-6)) //平行共线 { - let pts = [p1, p2, p3, p4]; - pts.sort(comparePoint('xyz')); - if (equal(pts[1], p3) || equal(pts[1], p4)) + let tmpPts = [p1, p2, p3, p4]; + tmpPts.sort(comparePoint('xyz')); + if (equal(tmpPts[1], p3) || equal(tmpPts[1], p4)) { - pts = [pts[1], pts[2]]; + pts = [tmpPts[1], tmpPts[2]]; } else { - pts = [midPoint(pts[1], pts[2])] + pts = [midPoint(tmpPts[1], tmpPts[2])] } } else if (equaln(Math.abs(v1.dot(v2)), 1, 1e-6)) //平行不共线 @@ -331,7 +330,7 @@ export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOptio { let pt = IntersectLAndLFor3D(l1.StartPoint, l1.EndPoint, l2.StartPoint, l2.EndPoint); - return pt ? CheckPointOnCurve([pt], l1, l2, extType) : []; + return CheckPointOnCurve(pt, l1, l2, extType); } export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: IntersectOption): Vector3[] diff --git a/src/GraphicsSystem/LinkSelft.ts b/src/GraphicsSystem/LinkSelft.ts index dd1a072c4..2c887210e 100644 --- a/src/GraphicsSystem/LinkSelft.ts +++ b/src/GraphicsSystem/LinkSelft.ts @@ -2,23 +2,28 @@ import { Vector3 } from "three"; import { Curve } from "../DatabaseServices/Curve"; import { CurveIntersection } from "../Geometry/CurveIntersection"; import { CurveMap } from "../Geometry/CurveMap"; -import { equal } from "../Geometry/GeUtils"; +import { equal, equaln } from "../Geometry/GeUtils"; import { Stand } from "../Geometry/RegionParse"; import { app } from "../ApplicationServices/Application"; -import { Circle } from "../DatabaseServices/Circle"; export class LinkSelf { - private curveUseData: WeakMap = new WeakMap(); private curveIndexData: WeakMap = new WeakMap(); sealCus: Set[] = []; noSealCus: Curve[][] = []; + private m_Count; private cuMap: CurveMap; constructor(cus: Curve[]) { + this.m_Count = cus.length; //打断曲线 let breakCus: Curve[] = this.BreakCurve(cus); + // breakCus.forEach(c => + // { + // c.ColorIndex = 3; + // app.m_Database.ModelSpace.Append(c); + // }) //曲线图 用来快速搜索求交 this.cuMap = this.GenerateCurveMap(breakCus); @@ -36,8 +41,8 @@ export class LinkSelf let insMap = new CurveIntersection(cus.concat()); //打断后存储的曲线列表 let breakCus: Curve[] = []; - let count = cus.length; - for (let i = 0; i < count; i++) + // let count = cus.length; + for (let i = 0; i < this.m_Count; i++) { let cu = cus[i]; //交点数据 @@ -59,8 +64,11 @@ export class LinkSelf { for (let c of spCus) { - this.SetCurveIndex(c, i); - breakCus.push(c); + if (!equaln(c.Length, 0, 1e-6)) + { + this.SetCurveIndex(c, i); + breakCus.push(c); + } } } } @@ -72,8 +80,6 @@ export class LinkSelf { let breakCount = breakCus.length; - let selfRoutes: Set[] = []; - //搜索闭合自交 for (let i = 0; i < breakCount; i++) { @@ -99,18 +105,18 @@ export class LinkSelf if (routeIndex < cuIndex) continue;//不和小于自己索引的计算 - routeCus.add(cu); - routeCus.add(route.curve); - //如果存在闭合区域 if (this.FindCloseCurve(route.to, cuIndex, ways, routeCus, cuMap)) { + routeCus.add(route.curve); + routeCus.add(cu); //提取闭合区域 for (let c of routeCus) { this.SetCurveUse(c); } this.sealCus.push(routeCus); + break; } } } @@ -145,6 +151,17 @@ export class LinkSelf { let oldCount = cs.length; let routes = cuMap.GetStand(isInv ? originCu.StartPoint : originCu.EndPoint).routes; + // 最后一段从大到小搜 + + for (let i = 0; i < routes.length; i++) + { + let index = this.GetCurveIndex(routes[i].curve); + if (index === cuIndex) + { + routes.unshift(routes.splice(i, 1)[0]); + } + } + for (let j = routes.length; j--;) //按照索引从小到大搜索 { let cu2 = routes[j].curve; @@ -152,7 +169,7 @@ export class LinkSelf if (this.GetCurveUse(cu2)) continue; if (cuIndex === cu2Index) { - continue;//如果和自身的线连接,则需要判断这条路线是否合理 + // continue;//如果和自身的线连接,则需要判断这条路线是否合理 } //能够连接 let isLink = isInv ? equal(cu2.EndPoint, originCu.StartPoint) : equal(cu2.StartPoint, originCu.EndPoint); @@ -225,7 +242,6 @@ export class LinkSelf this.curveIndexData.set(curve, index); } - //搜索闭合的区域 private FindCloseCurve(nowStand: Stand, cuIndex: number, ways: Stand[], routes: Set, cuMap: CurveMap) { @@ -242,7 +258,6 @@ export class LinkSelf if (routeIndex < cuIndex) continue;//不和小于自己索引的计算 - //验证通过,可以连接. let toStand = route.to; diff --git a/src/GraphicsSystem/OffestPolyline.ts b/src/GraphicsSystem/OffestPolyline.ts index 4a50ef465..1c444a117 100644 --- a/src/GraphicsSystem/OffestPolyline.ts +++ b/src/GraphicsSystem/OffestPolyline.ts @@ -73,10 +73,11 @@ export class PolyOffestUtil if (!this.IsKeepAllCurves) { // console.time('k'); - // rets = this.optimizeCus(rets); + rets = this.optimizeCus(rets); // console.timeEnd('k'); } return rets; + // return []; } /** * 过滤优化曲线数组 @@ -416,50 +417,54 @@ export class PolyOffestUtil let outline = c.Outline; for (let l of needCutCus) { - let posSrcForTar = TargetCurPosForSourceCur(outline, l as Arc | Line); - if (posSrcForTar.onSrc || posSrcForTar.outSrc) + // let posSrcForTar = TargetCurPosForSourceCur(outline, l as Arc | Line); + // if (posSrcForTar.onSrc || posSrcForTar.outSrc) + // { + // tmpCus.push(l); + // } + // else if (posSrcForTar.throughSrc) + // { + // let par = posSrcForTar.pts.map(p => l.GetParamAtPoint(p)); + // let cus = l.GetSplitCurves(par); + // if (cus.length === 0) + // { + // tmpCus.push(l); + // } + // else + // { + // tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && isTargetCurOutOrOnSourceCur(outline, cu))); + // } + // } + // else + // { + // l instanceof Arc && tmpCus.push(l); + // } + + // 在上面或者在外面 + if (isTargetCurOutOrOnSourceCur(outline, l)) { tmpCus.push(l); } - else if (posSrcForTar.throughSrc) + else if (!isTargetCurInOrOnSourceCur(outline, l)) { - let par = posSrcForTar.pts.map(p => l.GetParamAtPoint(p)); - let cus = l.GetSplitCurves(par); - if (cus.length === 0) - { - tmpCus.push(l); - } - else + let pts = l.IntersectWith(outline, IntersectOption.OnBothOperands); + if (pts.length > 0) { - tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && isTargetCurOutOrOnSourceCur(outline, cu))); + let par = pts.map(p => l.GetParamAtPoint(p)); + let cus = l.GetSplitCurves(par); + + if (cus.length > 0) + tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && !isTargetCurInOrOnSourceCur(outline, cu))); + else + { + tmpCus.push(l); + } } } else { - l instanceof Arc && tmpCus.push(l); + // l instanceof Arc && tmpCus.push(l); } - - // 在上面或者在外面 - // if (isTargetCurOutOrOnSourceCur(outline, l)) - // { - // tmpCus.push(l); - // } - // else - // { - // let pts = l.IntersectWith(outline, IntersectOption.OnBothOperands); - // if (pts.length > 0) - // { - // let par = pts.map(p => l.GetParamAtPoint(p)); - // let cus = l.GetSplitCurves(par); - - // if (cus.length > 0) - // tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && !isTargetCurInOrOnSourceCur(outline, cu))); - // else - // { - // tmpCus.push(l); - // } - // } - // } } needCutCus = tmpCus; }) @@ -609,7 +614,7 @@ export class PolyOffestUtil { let retPls: Polyline[] = []; let retsCus = new LinkSelf(cus); - let noSealCus: Polyline[] = retsCus.noSealCus.map(cs => + let noSealCus = retsCus.noSealCus.map(cs => { return this.linkCurves2(cs); }) @@ -617,14 +622,14 @@ export class PolyOffestUtil { return this.linkCurves2(s); }) - let firstLine = noSealCus[0]; - noSealCus.sort((a, b) => b.Length - a.Length); - if (firstLine !== noSealCus[0]) - { - retPls.push(noSealCus[0]); - } - firstLine && retPls.push(firstLine); - // retPls.push(...noSealCus); + // let firstLine = noSealCus[0]; + // noSealCus.sort((a, b) => b.Length - a.Length); + // if (firstLine !== noSealCus[0]) + // { + // retPls.push(noSealCus[0]); + // } + // firstLine && retPls.push(firstLine); + retPls.push(...noSealCus); retPls.push(...sealCus); return retPls; }