From cad71af247cd360c011af0cc220edbdc7379055f Mon Sep 17 00:00:00 2001 From: ZoeLeeFZ Date: Tue, 18 Feb 2020 16:52:47 +0800 Subject: [PATCH] =?UTF-8?q?!737=20=E7=9B=B8=E4=BA=A4=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E4=BA=A4=E7=82=B9=E5=92=8C=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/EdgeSealing/EdgeSealing.test.ts | 9 +- .../__snapshots__/EdgeSealing.test.ts.snap | 10 +- .../__snapshots__/intersect.test.ts.snap | 104 +++++++++----- src/Add-on/test/testIntersect.ts | 4 +- src/Common/CurveUtils.ts | 13 +- src/DatabaseServices/Contour.ts | 12 +- src/DatabaseServices/Entity/Arc.ts | 53 +++---- src/DatabaseServices/Entity/Circle.ts | 21 +-- src/DatabaseServices/Entity/Curve.ts | 19 ++- src/DatabaseServices/Entity/Ellipse.ts | 11 +- src/DatabaseServices/Entity/Line.ts | 7 +- src/DatabaseServices/Entity/Polyline.ts | 2 +- src/GraphicsSystem/IntersectWith.ts | 129 +++++++++++++----- 13 files changed, 256 insertions(+), 138 deletions(-) diff --git a/__test__/EdgeSealing/EdgeSealing.test.ts b/__test__/EdgeSealing/EdgeSealing.test.ts index c0e7c8a5a..c545fc315 100644 --- a/__test__/EdgeSealing/EdgeSealing.test.ts +++ b/__test__/EdgeSealing/EdgeSealing.test.ts @@ -15,7 +15,14 @@ function testBrSealing(br: Board, sealingSize: number[]) for (let i = 0; i < calcCus.length; i++) { let cu = calcCus[i]; - offsetCus.push(...cu.GetOffsetCurves(sealingSize[i] * dir)); + let cs = cu.GetOffsetCurves(sealingSize[i] * dir); + for (let c of cs) + { + if (c instanceof Polyline) + offsetCus.push(...c.Explode()); + else + offsetCus.push(c); + } } CalcEdgeSealing(offsetCus); let pl = new Polyline(); diff --git a/__test__/EdgeSealing/__snapshots__/EdgeSealing.test.ts.snap b/__test__/EdgeSealing/__snapshots__/EdgeSealing.test.ts.snap index 8d19d6ef6..670b093de 100644 --- a/__test__/EdgeSealing/__snapshots__/EdgeSealing.test.ts.snap +++ b/__test__/EdgeSealing/__snapshots__/EdgeSealing.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`丢失线段板件 1`] = `538651.2759963807`; +exports[`丢失线段板件 1`] = `554052.5007766786`; exports[`丢失线段板件 2`] = `398758.87896958226`; @@ -16,13 +16,13 @@ exports[`异型板件,常规坐标系 2`] = `2682243.4048994216`; exports[`异型板件,常规坐标系 3`] = `2660261.4833081043`; -exports[`异型板件,常规坐标系 4`] = `2628158.6443366623`; +exports[`异型板件,常规坐标系 4`] = `2628158.6443366613`; -exports[`异型板件,常规坐标系 5`] = `2603082.551922609`; +exports[`异型板件,常规坐标系 5`] = `2603082.551922608`; -exports[`异型板件,非常规坐标系 1`] = `75939516.39226122`; +exports[`异型板件,非常规坐标系 1`] = `75939516.39226124`; -exports[`异型板件,非常规坐标系 2`] = `75863286.03232267`; +exports[`异型板件,非常规坐标系 2`] = `75863286.03232269`; exports[`异型板件,非常规坐标系 3`] = `75694680.60847881`; diff --git a/__test__/Geometry/__snapshots__/intersect.test.ts.snap b/__test__/Geometry/__snapshots__/intersect.test.ts.snap index 776168a64..0546c5904 100644 --- a/__test__/Geometry/__snapshots__/intersect.test.ts.snap +++ b/__test__/Geometry/__snapshots__/intersect.test.ts.snap @@ -2,60 +2,92 @@ exports[`三维空间圆圆相交测试 1`] = ` Array [ - Vector3 { - "x": 3.8465654731285666, - "y": -0.48984005103149847, - "z": 0.3777515851723183, - }, - Vector3 { - "x": 4.518686772594938, - "y": -2.26435797895917, - "z": -0.09066385360916496, + Object { + "argParam": 0.4536333241402826, + "pt": Vector3 { + "x": 3.8465654731285666, + "y": -0.48984005103149847, + "z": 0.3777515851723183, + }, + "thisParam": 0.7716603782612834, + }, + Object { + "argParam": 0.24200297426269035, + "pt": Vector3 { + "x": 4.518686772594938, + "y": -2.26435797895917, + "z": -0.09066385360916496, + }, + "thisParam": 0.9239759201416895, }, ] `; exports[`三维空间圆圆相交测试 2`] = ` Array [ - Vector3 { - "x": 1.25, - "y": -4.841229182759271, - "z": 0, - }, - Vector3 { - "x": 1.25, - "y": 4.841229182759271, - "z": 0, + Object { + "argParam": 0.7097846883724168, + "pt": Vector3 { + "x": 1.25, + "y": -4.841229182759271, + "z": 0, + }, + "thisParam": 0.7902153116275832, + }, + Object { + "argParam": 0.29021531162758313, + "pt": Vector3 { + "x": 1.25, + "y": 4.841229182759271, + "z": 0, + }, + "thisParam": 0.2097846883724169, }, ] `; exports[`三维空间圆圆相交测试 3`] = ` Array [ - Vector3 { - "x": 1.25, - "y": 0, - "z": -4.841229182759271, - }, - Vector3 { - "x": 1.25, - "y": 0, - "z": 4.841229182759271, + Object { + "argParam": 0.7097846883724168, + "pt": Vector3 { + "x": 1.25, + "y": 0, + "z": -4.841229182759271, + }, + "thisParam": 0.7902153116275832, + }, + Object { + "argParam": 0.29021531162758313, + "pt": Vector3 { + "x": 1.25, + "y": 0, + "z": 4.841229182759271, + }, + "thisParam": 0.2097846883724169, }, ] `; exports[`三维空间圆圆相交测试 4`] = ` Array [ - Vector3 { - "x": 0, - "y": -11.313088368701884, - "z": -9.556275638274851, - }, - Vector3 { - "x": 0, - "y": -9.579281670837858, - "z": -2.8986776905615708, + Object { + "argParam": -0.6390032202422545, + "pt": Vector3 { + "x": 0, + "y": -11.313088368701884, + "z": -9.556275638274851, + }, + "thisParam": 1.734018071788813, + }, + Object { + "argParam": 0.27309309551812694, + "pt": Vector3 { + "x": 0, + "y": -9.579281670837858, + "z": -2.8986776905615708, + }, + "thisParam": 0.8053579264405307, }, ] `; diff --git a/src/Add-on/test/testIntersect.ts b/src/Add-on/test/testIntersect.ts index b6f963a96..41c548b0a 100644 --- a/src/Add-on/test/testIntersect.ts +++ b/src/Add-on/test/testIntersect.ts @@ -81,9 +81,9 @@ export class TestIntersect implements Command { cus[0].ColorIndex = 7; cus[1].ColorIndex = 7; - pt.forEach(p => + pt.forEach(({ pt }) => { - let cir = new Circle(p, 0.1); + let cir = new Circle(pt, 0.1); cir.ColorIndex = 2; app.Database.ModelSpace.Append(cir); }); diff --git a/src/Common/CurveUtils.ts b/src/Common/CurveUtils.ts index 1d597dc34..dae59f222 100644 --- a/src/Common/CurveUtils.ts +++ b/src/Common/CurveUtils.ts @@ -11,7 +11,7 @@ import { CurveMap } from '../Geometry/CurveMap'; import { ZeroVec, equaln, equalv2, equalv3, isParallelTo, AsVector3, AsVector2 } from '../Geometry/GeUtils'; import { PlaneExt } from '../Geometry/Plane'; import { Stand } from '../Geometry/RegionParse'; -import { IntersectOption } from '../GraphicsSystem/IntersectWith'; +import { IntersectOption, IntersectResult } from '../GraphicsSystem/IntersectWith'; import { arrayLast, changeArrayStartIndex, equalArray } from './ArrayExt'; import { OffsetPolyline } from '../GraphicsSystem/OffsetPolyline'; import { FixIndex } from './Utils'; @@ -585,3 +585,14 @@ export function MergeCurvelist(cus: Curve[]) } return cus; } + +export function SwapParam(res: IntersectResult[]) +{ + for (let r of res) + { + let p = r.thisParam; + r.thisParam = r.argParam; + r.argParam = p; + } + return res; +} diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index 25db0e9ce..adc507eb6 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -192,7 +192,7 @@ export class Contour let sourceOutline = this._Curve; let targetOutline = target.Curve; - let interPts = sourceOutline.IntersectWith(targetOutline, IntersectOption.OnBothOperands); + let interPts = sourceOutline.IntersectWith2(targetOutline, IntersectOption.OnBothOperands); let sourceContainerTarget = this.CuInOutline(targetOutline); let targetContainerSource = target.CuInOutline(sourceOutline); @@ -214,8 +214,8 @@ export class Contour } else//相交 interPts.length > 0 { - let pars1 = interPts.map(p => sourceOutline.GetParamAtPoint(p)); - let pars2 = interPts.map(p => targetOutline.GetParamAtPoint(p)); + let pars1 = interPts.map(r => r.thisParam); + let pars2 = interPts.map(r => r.argParam); let sourceCus: Array = sourceOutline.GetSplitCurves(pars1); let targetCus: Array = targetOutline.GetSplitCurves(pars2); @@ -285,7 +285,7 @@ export class Contour let sourceOutline = this._Curve as Polyline; let targetOutline = target.Curve as Polyline; - let interPts = sourceOutline.IntersectWith(targetOutline, IntersectOption.OnBothOperands, 1e-3); + let interPts = sourceOutline.IntersectWith2(targetOutline, IntersectOption.OnBothOperands, 1e-3); if (interPts.length <= 1) { @@ -301,8 +301,8 @@ export class Contour //相交 let subtractList: Curve[] = []; - let sourceCus = sourceOutline.GetSplitCurvesByPts(interPts) as Polyline[]; - let targetCus = targetOutline.GetSplitCurvesByPts(interPts) as Polyline[]; + let sourceCus = sourceOutline.GetSplitCurves(interPts.map(r => r.thisParam)) as Polyline[]; + let targetCus = targetOutline.GetSplitCurves(interPts.map(r => r.argParam)) as Polyline[]; for (let pl of sourceCus) { diff --git a/src/DatabaseServices/Entity/Arc.ts b/src/DatabaseServices/Entity/Arc.ts index b13edcc6e..4693a72f1 100644 --- a/src/DatabaseServices/Entity/Arc.ts +++ b/src/DatabaseServices/Entity/Arc.ts @@ -15,11 +15,12 @@ import { Curve } from './Curve'; import { Line } from './Line'; import { Polyline } from './Polyline'; import { Ellipse } from './Ellipse'; +import { SwapParam } from './../../Common/CurveUtils'; /** * 圆弧实体类 * 与ACAD不同,这个类加入了时针变量,并且默认构造的圆弧为顺时针圆弧. - * + * * 关于时针圆弧: * 起始圆弧到终止圆弧总是在0-2PI之间.(一个完整的圆). * 圆弧的绘制从起始圆弧绘制到终止圆弧. 按照时针绘制. @@ -77,12 +78,12 @@ export class Arc extends Curve return 0.5 * this.AllAngle * this.Radius * this.Radius; } //获得曲线的面积,逆时针为正,顺时针为负. - get Area2(): number + get Area2(): number { let clockwise = this.m_Clockwise ? -1 : 1; return 0.5 * this.AllAngle * this.Radius * this.Radius * clockwise; } - get IsClose(): boolean + get IsClose(): boolean { return false; } @@ -254,9 +255,9 @@ export class Arc extends Curve * 利用角度计算该角度在圆弧中代表的参数. * 如果角度在圆弧内,那么返回0-1 * 如果角度不在圆弧内,那么尝试返回离圆弧起始或者结束的较近的参数 - * - * @param {number} an - * @returns + * + * @param {number} an + * @returns * @memberof Arc */ GetParamAtAngle(an: number) @@ -278,9 +279,9 @@ export class Arc extends Curve /** * Gets param at angle2 - * @param an + * @param an * @param [isStart] true:返回负数,false 返回正数 - * @returns + * @returns */ GetParamAtAngle2(an: number, isStart = true) { @@ -447,7 +448,7 @@ export class Arc extends Curve return this; } - IntersectWith(curve: Curve, intType: IntersectOption): Vector3[] + IntersectWith2(curve: Curve, intType: IntersectOption) { if (curve instanceof Arc) { @@ -455,23 +456,23 @@ export class Arc extends Curve } if (curve instanceof Line) { - return IntersectLineAndArc(curve, this, reverseIntersectOption(intType)); + return SwapParam(IntersectLineAndArc(curve, this, reverseIntersectOption(intType))); } if (curve instanceof Circle) { - return IntersectCircleAndArc(curve, this, reverseIntersectOption(intType)); + return SwapParam(IntersectCircleAndArc(curve, this, reverseIntersectOption(intType))); } if (curve instanceof Polyline) - return IntersectPolylineAndCurve(curve, this, reverseIntersectOption(intType)); + return SwapParam(IntersectPolylineAndCurve(curve, this, reverseIntersectOption(intType))); if (curve instanceof Ellipse) - return IntersectEllipseAndCircleOrArc(curve, this, intType); + return SwapParam(IntersectEllipseAndCircleOrArc(curve, this, intType)); return []; } /** * 计算出圆弧所包含的角度 - * + * * @readonly * @type {number} * @memberof Arc @@ -490,10 +491,10 @@ export class Arc extends Curve /** * 计算所包含的角度 - * + * * @private * @param {number} endAngle 结束的角度 - * @returns + * @returns * @memberof Arc */ ComputeAnlge(endAngle: number) @@ -517,10 +518,10 @@ export class Arc extends Curve /** * 解析两点和凸度所构成的圆弧 - * - * @param {Vector2} p1 - * @param {Vector2} p2 - * @param {number} bul 凸度,在cad中,凸度为 <(四分之一圆心角)的正切值> + * + * @param {Vector2} p1 + * @param {Vector2} p2 + * @param {number} bul 凸度,在cad中,凸度为 <(四分之一圆心角)的正切值> */ ParseFromBul(p1: Vector3 | Vector2, p2: Vector3 | Vector2, bul: number): Arc { @@ -574,7 +575,7 @@ export class Arc extends Curve let center = getCircleCenter(pt1, pt2, pt3); this.Center = center.clone().applyMatrix4(this.OCS); - //用圆心和其中一个点求距离得到半径: + //用圆心和其中一个点求距离得到半径: this.m_Radius = center.distanceTo(pt1); //起始角度 端点角度 this.m_StartAngle = angle(pt1.clone().sub(center)); @@ -589,8 +590,8 @@ export class Arc extends Curve /** * 重载: 初始化绘制实体. - * - * @param {RenderType} [renderType=RenderType.Wireframe] + * + * @param {RenderType} [renderType=RenderType.Wireframe] */ InitDrawObject(renderType: RenderType = RenderType.Wireframe): TLine { @@ -607,9 +608,9 @@ export class Arc extends Curve /** * 重载:更新绘制的实体 - * - * @param {RenderType} type - * @param {Object3D} obj + * + * @param {RenderType} type + * @param {Object3D} obj * @memberof Arc */ UpdateDrawObject(type: RenderType, obj: Object3D) diff --git a/src/DatabaseServices/Entity/Circle.ts b/src/DatabaseServices/Entity/Circle.ts index 7ed73b6fd..c0a81f7ad 100644 --- a/src/DatabaseServices/Entity/Circle.ts +++ b/src/DatabaseServices/Entity/Circle.ts @@ -17,6 +17,7 @@ import { DragPointType } from './DragPointType'; import { Ellipse } from './Ellipse'; import { Line } from './Line'; import { Polyline } from './Polyline'; +import { SwapParam } from './../../Common/CurveUtils'; let circleGeometry: BufferGeometry; function GetCircleGeometry() @@ -85,19 +86,19 @@ export class Circle extends Curve //******************** Curve function start*****************// - get StartPoint(): Vector3 + get StartPoint(): Vector3 { return this.GetPointAtParam(0); } - get StartParam(): number + get StartParam(): number { return 0; } - get EndPoint(): Vector3 + get EndPoint(): Vector3 { return this.GetPointAtParam(0); } - get EndParam(): number + get EndParam(): number { return 1; } @@ -118,7 +119,7 @@ export class Circle extends Curve return Math.PI * 2 * this._Radius; } - get IsClose(): boolean + get IsClose(): boolean { return true; } @@ -199,7 +200,7 @@ export class Circle extends Curve { return equaln(pt.distanceToSquared(this.Center), this._Radius * this._Radius, 1e-5); } - GetOffsetCurves(offsetDist: number) + GetOffsetCurves(offsetDist: number): Curve[] { if ((offsetDist + this._Radius) > 0) { @@ -210,7 +211,7 @@ export class Circle extends Curve return []; } - IntersectWith(curve: Curve, intType: IntersectOption): Vector3[] + IntersectWith2(curve: Curve, intType: IntersectOption) { if (curve instanceof Arc) { @@ -218,7 +219,7 @@ export class Circle extends Curve } if (curve instanceof Line) { - return IntersectLineAndCircle(curve, this, reverseIntersectOption(intType)); + return SwapParam(IntersectLineAndCircle(curve, this, reverseIntersectOption(intType))); } if (curve instanceof Circle) { @@ -226,10 +227,10 @@ export class Circle extends Curve } if (curve instanceof Ellipse) { - return IntersectEllipseAndCircleOrArc(curve, this, intType); + return SwapParam(IntersectEllipseAndCircleOrArc(curve, this, intType)); } if (curve instanceof Polyline) - return IntersectPolylineAndCurve(curve, this, reverseIntersectOption(intType)); + return SwapParam(IntersectPolylineAndCurve(curve, this, reverseIntersectOption(intType))); return []; } //******************** Curve function end*****************// diff --git a/src/DatabaseServices/Entity/Curve.ts b/src/DatabaseServices/Entity/Curve.ts index 6d984e325..18de8cac9 100644 --- a/src/DatabaseServices/Entity/Curve.ts +++ b/src/DatabaseServices/Entity/Curve.ts @@ -3,7 +3,7 @@ import { arrayRemoveDuplicateBySort, arraySortByNumber } from '../../Common/Arra import { ColorMaterial } from '../../Common/ColorPalette'; import { Status } from '../../Common/Status'; import { equaln, equalv3 } from '../../Geometry/GeUtils'; -import { IntersectOption } from '../../GraphicsSystem/IntersectWith'; +import { IntersectOption, IntersectResult } from '../../GraphicsSystem/IntersectWith'; import { RenderType } from '../../GraphicsSystem/RenderType'; import { Factory } from '../CADFactory'; import { DragPointType } from './DragPointType'; @@ -153,13 +153,18 @@ export abstract class Curve extends Entity GetClosestPointTo(pt: Vector3, extend: boolean): Vector3 { return; } /** - * 曲线相交 - * - * @param {Curve} curve - * @returns {Vector3[]} - * @memberof Curve + * 曲线相交点 + */ + IntersectWith(curve: Curve, intType: IntersectOption, tolerance = 1e-6): Vector3[] + { + return this.IntersectWith2(curve, intType, tolerance).map(r => r.pt); + } + + /** + * 曲线相交点和点的参数 */ - IntersectWith(curve: Curve, intType: IntersectOption, tolerance = 1e-6): Vector3[] { return []; } + IntersectWith2(curve: Curve, intType: IntersectOption, tolerance = 1e-6): IntersectResult[] { return []; } + /** * 拽托点个数 diff --git a/src/DatabaseServices/Entity/Ellipse.ts b/src/DatabaseServices/Entity/Ellipse.ts index d00eb155e..61f396654 100644 --- a/src/DatabaseServices/Entity/Ellipse.ts +++ b/src/DatabaseServices/Entity/Ellipse.ts @@ -14,6 +14,7 @@ import { Circle } from './Circle'; import { Curve } from './Curve'; import { Line } from './Line'; import { Polyline } from './Polyline'; +import { SwapParam } from './../../Common/CurveUtils'; @Factory export class Ellipse extends Curve @@ -35,11 +36,11 @@ export class Ellipse extends Curve this._radY = radY; this._rotate = angle; } - get StartParam(): number + get StartParam(): number { return 0; } - get EndParam(): number + get EndParam(): number { return 1; } @@ -449,12 +450,12 @@ export class Ellipse extends Curve return []; } } - IntersectWith(curve: Curve, intType: IntersectOption): Vector3[] + IntersectWith2(curve: Curve, intType: IntersectOption) { //TODO:优化椭圆和椭圆,椭圆和圆相交 if (curve instanceof Line) { - return IntersectEllipseAndLine(curve, this, reverseIntersectOption(intType)); + return SwapParam(IntersectEllipseAndLine(curve, this, reverseIntersectOption(intType))); } else if (curve instanceof Circle || curve instanceof Arc) { @@ -462,7 +463,7 @@ export class Ellipse extends Curve } else if (curve instanceof Polyline) { - return IntersectPolylineAndCurve(curve, this, intType); + return SwapParam(IntersectPolylineAndCurve(curve, this, intType)); } else if (curve instanceof Ellipse) { diff --git a/src/DatabaseServices/Entity/Line.ts b/src/DatabaseServices/Entity/Line.ts index b4f71a638..099d215a9 100644 --- a/src/DatabaseServices/Entity/Line.ts +++ b/src/DatabaseServices/Entity/Line.ts @@ -15,6 +15,7 @@ import { Circle } from './Circle'; import { Curve } from './Curve'; import { Polyline } from './Polyline'; import { Ellipse } from './Ellipse'; +import { SwapParam } from './../../Common/CurveUtils'; @Factory export class Line extends Curve @@ -155,7 +156,7 @@ export class Line extends Curve return this.EndPoint.sub(this.StartPoint); } - IntersectWith(curve: Curve, intType: IntersectOption, tolerance = 1e-4): Vector3[] + IntersectWith2(curve: Curve, intType: IntersectOption, tolerance = 1e-4) { if (curve instanceof Line) { @@ -171,7 +172,7 @@ export class Line extends Curve } if (curve instanceof Polyline) { - return IntersectPolylineAndCurve(curve, this, reverseIntersectOption(intType), tolerance); + return SwapParam(IntersectPolylineAndCurve(curve, this, reverseIntersectOption(intType), tolerance)); } if (curve instanceof Ellipse) @@ -348,7 +349,7 @@ export class Line extends Curve return this; } - GetOffsetCurves(offsetDist: number): Array + GetOffsetCurves(offsetDist: number): Array { let derv = this.GetFistDeriv(0).normalize().multiplyScalar(offsetDist); derv.applyMatrix4(new Matrix4().makeRotationAxis(this.Normal, -Math.PI / 2)); diff --git a/src/DatabaseServices/Entity/Polyline.ts b/src/DatabaseServices/Entity/Polyline.ts index 687e3f37e..023f1d8cd 100644 --- a/src/DatabaseServices/Entity/Polyline.ts +++ b/src/DatabaseServices/Entity/Polyline.ts @@ -1067,7 +1067,7 @@ export class Polyline extends Curve return curve; } - IntersectWith(curve: Curve, intType: IntersectOption, tolerance = 1e-5): Vector3[] + IntersectWith2(curve: Curve, intType: IntersectOption, tolerance = 1e-5) { return IntersectPolylineAndCurve(this, curve, intType, tolerance); } diff --git a/src/GraphicsSystem/IntersectWith.ts b/src/GraphicsSystem/IntersectWith.ts index 7fb3acf6c..e4cd7ce4a 100644 --- a/src/GraphicsSystem/IntersectWith.ts +++ b/src/GraphicsSystem/IntersectWith.ts @@ -33,6 +33,14 @@ export enum IntersectOption */ ExtendBoth = 3, } + +export interface IntersectResult +{ + pt: Vector3, + thisParam: number, + argParam: number, +} + //延伸自身还是参数反转 export function reverseIntersectOption(intType: IntersectOption) { @@ -46,28 +54,27 @@ export function reverseIntersectOption(intType: IntersectOption) * 校验相交点是否满足延伸选项 * 算法会计算无限延伸状态下的曲线交点,调用该方法进行校验返回校验后的点表 * - * @param {Vector3[]} intPts 相交点.曲线当作完全状态下的相交点 + * @param {Vector3[]} intRes 相交点.曲线当作完全状态下的相交点 * @param {Curve} c1 曲线1 由this参数传入 * @param {Curve} c2 曲线2 由arg 参数传入 * @param {Intersect} extType 延伸选项. * @returns {Array} 校验完成后的点表 */ -function CheckPointOnCurve(intPts: Vector3[], c1: Curve, c2: Curve, extType: IntersectOption, tolerance = 1e-6): Array +function CheckPointOnCurve(intRes: IntersectResult[], c1: Curve, c2: Curve, extType: IntersectOption, tolerance = 1e-6): Array { - return intPts.filter(p => + return intRes.filter(r => { if (!(extType & IntersectOption.ExtendThis)) - if (!c1.PtOnCurve3(p, tolerance)) + if (!c1.PtOnCurve3(r.pt, tolerance)) return false; if (!(extType & IntersectOption.ExtendArg)) - if (!c2.PtOnCurve3(p, tolerance)) + if (!c2.PtOnCurve3(r.pt, tolerance)) return false; return true; }); } - -export function IntersectCircleAndCircle(cu1: Circle | Arc, cu2: Circle | Arc) +export function IntersectCircleAndCircle(cu1: Circle | Arc, cu2: Circle | Arc): IntersectResult[] { if (!cu1.IsCoplaneTo(cu2)) return []; @@ -79,7 +86,7 @@ export function IntersectCircleAndCircle(cu1: Circle | Arc, cu2: Circle | Arc) let radius1 = cu1.Radius; let radius2 = cu2.Radius; - let pts: Vector3[] = []; + let pts: IntersectResult[] = []; let dist = center2.distanceTo(center1); if (dist < Math.abs(radius1 - radius2) @@ -111,9 +118,17 @@ export function IntersectCircleAndCircle(cu1: Circle | Arc, cu2: Circle | Arc) p1.applyMatrix4(c1Ocs); p2.applyMatrix4(c1Ocs); - pts.push(p1); + pts.push({ + pt: p1, + thisParam: cu1.GetParamAtPoint(p1), + argParam: cu2.GetParamAtPoint(p1), + }); if (!equalv3(p1, p2))//防止点重复 - pts.push(p2); + pts.push({ + pt: p2, + thisParam: cu1.GetParamAtPoint(p2), + argParam: cu2.GetParamAtPoint(p2), + }); return pts; } @@ -161,12 +176,12 @@ export function IntersectEllipseAndLine(l: Line, el: Ellipse, extType: Intersect * @param {(Circle | Arc)} circle 圆或圆弧 * @returns 交点集合 */ -function IntersectLineAndCircleOrArc(line: Line, circle: Circle | Arc) +function IntersectLineAndCircleOrArc(line: Line, circle: Circle | Arc): IntersectResult[] { let lineOrg = line.StartPoint; let lineDirection = line.EndPoint.sub(lineOrg); let dirLen = lineDirection.length(); - if (dirLen === 0) return []; + if (equaln(dirLen, 0)) return []; lineDirection.divideScalar(dirLen); let diff = lineOrg.clone().sub(circle.Center); @@ -176,14 +191,30 @@ function IntersectLineAndCircleOrArc(line: Line, circle: Circle | Arc) if (equaln(discr, 0, 1e-7)) { - return [lineOrg.add(lineDirection.multiplyScalar(-a1))]; + let pt = lineOrg.add(lineDirection.multiplyScalar(-a1)); + + return [{ + pt, + thisParam: -a1 / dirLen, + argParam: circle.GetParamAtPoint(pt) + }]; } else if (discr > 0) { let root = Math.sqrt(discr); + let p1 = lineOrg.clone().add(lineDirection.clone().multiplyScalar(-a1 + root)); + let p2 = lineOrg.add(lineDirection.multiplyScalar(-a1 - root)); + return [ - lineOrg.clone().add(lineDirection.clone().multiplyScalar(-a1 + root)), - lineOrg.add(lineDirection.multiplyScalar(-a1 - root)) + { + pt: p1, + thisParam: (-a1 + root) / dirLen, + argParam: circle.GetParamAtPoint(p1) + }, { + pt: p2, + thisParam: (-a1 - root) / dirLen, + argParam: circle.GetParamAtPoint(p2) + } ]; } return []; @@ -287,7 +318,7 @@ function ShortestLine3AndLine3(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector } //直线和直线 -export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOption, fuzz = 1e-4): Vector3[] +export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOption, fuzz = 1e-4): IntersectResult[] { // if (l1.Is2D && l2.Is2D) // { @@ -321,20 +352,23 @@ export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOptio )) return []; - return [pt]; + return [{ + pt, + thisParam: param1, + argParam: param2 + }]; } -export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: IntersectOption, tolerance = 1e-6): Vector3[] +export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: IntersectOption, tolerance = 1e-6): IntersectResult[] { let cus: Curve[] = pl.Explode(); let cus2: Curve[]; - if (cu instanceof Polyline) cus2 = cu.Explode(); else cus2 = [cu]; - let pts: Vector3[] = []; + let intRes: IntersectResult[] = []; for (let i = 0; i < cus.length; i++) { @@ -356,7 +390,7 @@ export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: Inte if ((cu instanceof Polyline && cu.CloseMark) || !(isStart2 || isEnd2)) ext = ext & ~IntersectOption.ExtendArg; - let ipts = cu1.IntersectWith(cu2, ext, tolerance).filter(p1 => pts.every(p2 => !equalv3(p1, p2))); + let ptPars = cu1.IntersectWith2(cu2, ext, tolerance).filter(r1 => intRes.every(r2 => !equalv3(r1.pt, r2.pt))); //校验延伸 if (IntersectOption.ExtendThis & ext) @@ -367,11 +401,11 @@ export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: Inte } else if (isStart) { - ipts = ipts.filter(p => cu1.GetParamAtPoint(p) <= 1); + ptPars = ptPars.filter(res => res.thisParam <= 1); } else if (isEnd) { - ipts = ipts.filter(p => cu1.GetParamAtPoint(p) >= 0); + ptPars = ptPars.filter(res => res.thisParam >= 0); } } if (IntersectOption.ExtendArg & ext) @@ -382,20 +416,27 @@ export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: Inte } else if (isStart2) { - ipts = ipts.filter(p => cu2.GetParamAtPoint(p) <= cu2.EndParam); + ptPars = ptPars.filter(res => res.argParam + j <= cu2.EndParam); } else if (isEnd2) { - ipts = ipts.filter(p => cu2.GetParamAtPoint(p) >= 0); + ptPars = ptPars.filter(res => res.argParam + j >= 0); } } - pts.push(...ipts); + intRes.push(...ptPars.map(r => + { + return { + pt: r.pt, + thisParam: pl.GetParamAtPoint(r.pt), + argParam: cu.GetParamAtPoint(r.pt), + } + })); } } - pts.sort(comparePoint("xyz")); - arrayRemoveDuplicateBySort(pts, equalv3); - return pts; + intRes.sort((r1, r2) => comparePoint("xyz")(r1.pt, r2.pt)); + arrayRemoveDuplicateBySort(intRes, (r1, r2) => equalv3(r1.pt, r2.pt)); + return intRes; } export function IntersectLineAndEllipseFor2D(l: Line, el: Ellipse) @@ -455,7 +496,15 @@ export function IntersectLineAndEllipseFor2D(l: Line, el: Ellipse) } let matInv = new Matrix4().getInverse(mat); - return pts.map(p => p.applyMatrix4(matInv)); + return pts.map(p => + { + let pt = p.applyMatrix4(matInv); + return { + pt, + thisParam: l.GetParamAtPoint(pt), + argParam: el.GetParamAtPoint(pt) + } + }); } export function IntersectEllipseAndCircleOrArc(el: Ellipse, cir: Circle | Arc, type: IntersectOption) { @@ -506,8 +555,16 @@ export function IntersectEllipseAndCircleOrArc(el: Ellipse, cir: Circle | Arc, t ]; } let ro = new Matrix4().makeRotationZ(el.Rotation); - pts = pts.map(p => p.applyMatrix4(ro).applyMatrix4(el.OCS)); - return CheckPointOnCurve(pts, el, cir, type); + let res = pts.map(p => + { + let pt = p.applyMatrix4(ro).applyMatrix4(el.OCS) + return { + pt, + thisParam: el.GetParamAtPoint(pt), + argParam: cir.GetParamAtPoint(pt) + } + }); + return CheckPointOnCurve(res, el, cir, type); } else { @@ -525,7 +582,8 @@ export function IntersectEllipseAndCircleOrArc(el: Ellipse, cir: Circle | Arc, t type = IntersectOption.OnBothOperands; let intPts = IntersectPolylineAndCurve(pl, cirClone, type); - return intPts.map(p => p.applyMatrix4(el.OCS)); + intPts.forEach(r => r.pt.applyMatrix4(el.OCS)); + return intPts; } } export function IntersectEllipse(el1: Ellipse, el2: Ellipse, type: IntersectOption) @@ -568,6 +626,7 @@ export function IntersectEllipse(el1: Ellipse, el2: Ellipse, type: IntersectOpti let pl1 = new Polyline(lineData1); let pl2 = new Polyline(lineData2).ApplyMatrix(diffMat); - let intPts = pl1.IntersectWith(pl2, 0); - return intPts.map(p => p.applyMatrix4(el1.OCS)); + let intPts = pl1.IntersectWith2(pl2, 0); + intPts.forEach(r => r.pt.applyMatrix4(el1.OCS)); + return intPts; }