!217 更新3d直线求交函数.

Merge pull request !217 from ChenX/Int3dLine
pull/217/MERGE
ChenX 6 years ago
parent 007a5d3f33
commit 6a9920e056

@ -8,7 +8,7 @@ exports[`常规板件,常规坐标系 3`] = `712816`;
exports[`异型板件,常规坐标系 1`] = `2709777.7883832143`;
exports[`异型板件,常规坐标系 2`] = `2682243.404899422`;
exports[`异型板件,常规坐标系 2`] = `2682243.4048994216`;
exports[`异型板件,常规坐标系 3`] = `2660261.483308105`;
@ -20,4 +20,4 @@ exports[`异型板件,非常规坐标系 1`] = `75939516.39226122`;
exports[`异型板件,非常规坐标系 2`] = `75852693.84266448`;
exports[`异型板件,非常规坐标系 3`] = `75675829.72975095`;
exports[`异型板件,非常规坐标系 3`] = `75675829.72975093`;

@ -4,7 +4,7 @@ exports[`刀切到外轮廓情况: 曲线长度 1`] = `3600`;
exports[`刀切到外轮廓情况: 曲线长度 2`] = `22596.75011038597`;
exports[`刀切到外轮廓情况: 曲线长度 3`] = `6355.243980782`;
exports[`刀切到外轮廓情况: 曲线长度 3`] = `6355.243980781998`;
exports[`刀切到外轮廓情况: 曲线长度 4`] = `1478.9393851461323`;
@ -12,21 +12,21 @@ exports[`刀切到外轮廓情况: 曲线长度 5`] = `729.5688477133849`;
exports[`刀切到外轮廓情况: 曲线长度 6`] = `3600`;
exports[`刀切到外轮廓情况: 曲线长度 7`] = `939.4039853849399`;
exports[`刀切到外轮廓情况: 曲线长度 7`] = `939.4039853849379`;
exports[`刀切到外轮廓情况: 曲线长度 8`] = `13736.355649626385`;
exports[`刀切到外轮廓情况: 曲线长度 8`] = `13736.355649626326`;
exports[`刀切到外轮廓情况: 曲线长度 9`] = `1216.9875775199403`;
exports[`刀切到外轮廓情况: 曲线长度 9`] = `1216.9875775199405`;
exports[`刀切到外轮廓情况: 曲线长度 10`] = `13428.231939084159`;
exports[`刀切到外轮廓情况: 曲线长度 10`] = `13428.231939084173`;
exports[`刀切到外轮廓情况: 曲线长度 11`] = `939.4039853849375`;
exports[`刀切到外轮廓情况: 曲线长度 12`] = `13736.35564962633`;
exports[`刀切到外轮廓情况: 曲线长度 13`] = `13428.231939084155`;
exports[`刀切到外轮廓情况: 曲线长度 13`] = `13428.23193908413`;
exports[`刀切到外轮廓情况: 曲线长度 14`] = `1216.9875775199403`;
exports[`刀切到外轮廓情况: 曲线长度 14`] = `1216.9875775199384`;
exports[`刀切到外轮廓情况: 曲线长度 15`] = `2683.281572999748`;
@ -44,10 +44,12 @@ exports[`复杂极限刀半径: 曲线长度 3`] = `951.5402172137751`;
exports[`复杂极限刀半径: 曲线长度 4`] = `35730.26757931215`;
exports[`复杂极限刀半径: 曲线长度 5`] = `2927.3167299028473`;
exports[`复杂极限刀半径: 曲线长度 5`] = `2927.3167299028455`;
exports[`复杂极限刀半径: 曲线长度 6`] = `3278.917934988776`;
exports[`复杂极限刀半径: 曲线长度 7`] = `3278.917934988776`;
exports[`复杂极限刀半径: 走刀数量 1`] = `4`;
exports[`复杂造型测试: 曲线长度 1`] = `2402.511185283596`;
@ -72,7 +74,7 @@ exports[`复杂造型测试: 曲线长度 10`] = `4096.105045378745`;
exports[`复杂造型测试: 曲线长度 11`] = `476.0989607667294`;
exports[`复杂造型测试: 曲线长度 12`] = `910.1341511193465`;
exports[`复杂造型测试: 曲线长度 12`] = `910.1341511193467`;
exports[`复杂造型测试: 曲线长度 13`] = `1167.5479341842504`;
@ -102,11 +104,11 @@ exports[`复杂造型测试: 曲线长度 25`] = `162.171881370416`;
exports[`复杂造型测试: 曲线长度 26`] = `3600`;
exports[`复杂造型测试: 曲线长度 27`] = `103756.10963582453`;
exports[`复杂造型测试: 曲线长度 27`] = `103756.1096358091`;
exports[`复杂造型测试: 曲线长度 28`] = `487.19933816470575`;
exports[`复杂造型测试: 曲线长度 29`] = `2152.7628031484855`;
exports[`复杂造型测试: 曲线长度 29`] = `2152.7628031484846`;
exports[`复杂造型测试: 曲线长度 30`] = `2581.084814115112`;
@ -164,7 +166,7 @@ exports[`极限刀半径: 曲线长度 7`] = `3600`;
exports[`极限刀半径: 曲线长度 8`] = `3517.9183450322453`;
exports[`极限刀半径: 曲线长度 9`] = `1638.9591725161226`;
exports[`极限刀半径: 曲线长度 9`] = `1638.9591725161224`;
exports[`极限刀半径: 曲线长度 10`] = `3600`;

@ -5,8 +5,7 @@ import { CADFile } from '../../src/DatabaseServices/CADFile';
import { Circle } from '../../src/DatabaseServices/Circle';
import { Curve } from '../../src/DatabaseServices/Curve';
import { Line } from '../../src/DatabaseServices/Line';
import { IntersectCircleAndCircle, IntersectLAndLFor3D, IntersectOption } from '../../src/GraphicsSystem/IntersectWith';
import { IntersectCircleAndCircle, IntersectLine3AndLine3, IntersectOption } from '../../src/GraphicsSystem/IntersectWith';
test('相交测试', () =>
{
@ -18,13 +17,13 @@ test('相交测试', () =>
let p5 = new THREE.Vector3(3, 0, 0);
let p6 = new THREE.Vector3(6, 0, 0);
let res = IntersectLAndLFor3D(p1, p2, p3, p4);/*?*/
let res = IntersectLine3AndLine3(p1, p2, p3, p4);/*?*/
expect(res).toMatchSnapshot();
res = IntersectLAndLFor3D(p1, p2, p5, p6);/*?*/
res = IntersectLine3AndLine3(p1, p2, p5, p6);/*?*/
expect(res).toMatchSnapshot();
let ins = IntersectLAndLFor3D(
let ins = IntersectLine3AndLine3(
new THREE.Vector3(0, 5),
new THREE.Vector3(5, 5),
new THREE.Vector3(0.5, 1),
@ -42,22 +41,22 @@ test('三维空间直线相交测试', () =>
let p5 = new THREE.Vector3(3, 3, 3);
let p6 = new THREE.Vector3(6, 6, 6);
let res = IntersectLAndLFor3D(p1, p2, p3, p4);/*?*/
let res = IntersectLine3AndLine3(p1, p2, p3, p4);/*?*/
expect(res).toMatchSnapshot();
res = IntersectLAndLFor3D(p1, p2, p5, p6);/*?*/
res = IntersectLine3AndLine3(p1, p2, p5, p6);/*?*/
expect(res).toMatchSnapshot();
res = IntersectLAndLFor3D(p2, p6, p3, p4);/*?*/
res = IntersectLine3AndLine3(p2, p6, p3, p4);/*?*/
expect(res).toMatchSnapshot();
res = IntersectLAndLFor3D(
res = IntersectLine3AndLine3(
new Vector3(1, 1, 1),
new Vector3(1, 1, 4),
new Vector3(2, 2, 2),
new Vector3(2, 2, 10)
)
expect(res).toBeUndefined();
res = IntersectLAndLFor3D(
res = IntersectLine3AndLine3(
new Vector3(1, 0, 1),
new Vector3(1, 0, 4),
new Vector3(0.5, 0, 3),

@ -5,7 +5,7 @@ import { Circle } from "../../DatabaseServices/Circle";
import { Curve } from "../../DatabaseServices/Curve";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { IntersectCircleAndCircle, IntersectLAndLFor3D, IntersectOption } from "../../GraphicsSystem/IntersectWith";
import { IntersectCircleAndCircle, IntersectOption } from "../../GraphicsSystem/IntersectWith";
import { Point } from "../../DatabaseServices/Point";
export class TestIntersect implements Command
@ -44,27 +44,6 @@ export class TestIntersect implements Command
}
}
}
async testLineAndLine()
{
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);
console.log('pt: ', pt);
if (pt)
{
cus[0].ColorIndex = 7;
cus[1].ColorIndex = 7;
let cir = new Circle(pt, 0.1);
cir.ColorIndex = 2;
app.m_Database.ModelSpace.Append(cir);
} else
{
cus[0].ColorIndex = 1;
cus[1].ColorIndex = 1;
}
}
async testLineAndCirOrArc()
{
let exRefSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true });

@ -1,12 +1,11 @@
import { Vector3 } from 'three';
import { arrayRemoveDuplicateBySort } from '../Common/ArrayExt';
import { getDeterminantFor3V } from '../Common/CurveUtils';
import { Arc } from '../DatabaseServices/Arc';
import { Circle } from '../DatabaseServices/Circle';
import { Curve } from '../DatabaseServices/Curve';
import { Line } from '../DatabaseServices/Line';
import { Polyline } from '../DatabaseServices/Polyline';
import { comparePoint, equalv3, equaln, midPoint } from '../Geometry/GeUtils';
import { comparePoint, equaln, equalv3, midPoint } from '../Geometry/GeUtils';
/**
@ -217,101 +216,67 @@ export function IntersectLAndLFor2D(p1: Vector3, p2: Vector3, p3: Vector3, p4: V
return pt;
}
export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3)
{
let x12 = p1.x - p2.x;
let x43 = p4.x - p3.x;
let x42 = p4.x - p2.x;
let y12 = p1.y - p2.y;
let y43 = p4.y - p3.y;
let y42 = p4.y - p2.y;
let z12 = p1.z - p2.z;
let z43 = p4.z - p3.z;
let z42 = p4.z - p2.z;
let v1 = p2.clone().sub(p1).normalize();
let v2 = p4.clone().sub(p3).normalize();
let w = p3.clone().sub(p1).normalize();
if (equaln(Math.abs(v1.dot(v2)), 1, 1e-6) && (equalv3(w, new Vector3()) || equaln(Math.abs(v1.dot(w)), 1, 1e-6))) //平行共线
return undefined;
else if (equaln(Math.abs(v1.dot(v2)), 1, 1e-6)) //平行不共线
return undefined;
else if (equaln(getDeterminantFor3V(v1, v2, w), 0, 0.01))
{
let t: number;
if (x12 * y43 - y12 * x43)
{
t = (x42 * y43 - x43 * y42) / (x12 * y43 - y12 * x43);
}
else if (x12 * z43 - x43 * z12)
{
t = (x42 * z43 - x43 * z42) / (x12 * z43 - x43 * z12);
}
else
export function IntersectLine3AndLine3(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3, epsilon = 1e-6)
{
t = (y42 * z43 - y43 * z42) / (y12 * z43 - y43 * z12);
}
return new Vector3(x12 * t + p2.x, y12 * t + p2.y, z12 * t + p2.z);
let pts = ShortestLine3AndLine3(p1, p2, p3, p4);
if (pts) return pts[0];
}
}
export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3)
/**
* 线
* ref:https://stackoverflow.com/questions/2316490/the-algorithm-to-find-the-point-of-intersection-of-two-3d-line-segment
* ref:http://paulbourke.net/geometry/pointlineplane/
* ref:http://paulbourke.net/geometry/pointlineplane/calclineline.cs
*
* @export
* @param {Vector3} p1 l1.start
* @param {Vector3} p2 l1.end
* @param {Vector3} p3 l2.start
* @param {Vector3} p4 l2.end
* @returns
*/
function ShortestLine3AndLine3(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3, epsilon = 1e-6)
{
let x12 = p1.x - p2.x;
let x43 = p4.x - p3.x;
let x42 = p4.x - p2.x;
let y12 = p1.y - p2.y;
let y43 = p4.y - p3.y;
let y42 = p4.y - p2.y;
let z12 = p1.z - p2.z;
let z43 = p4.z - p3.z;
let z42 = p4.z - p2.z;
let p43 = p4.clone().sub(p3);
if (p43.lengthSq() < epsilon)
return;
let p21 = p2.clone().sub(p1);
if (p21.lengthSq() < epsilon)
return;
let pts: Vector3[] = [];
let v1 = p2.clone().sub(p1).normalize();
let v2 = p4.clone().sub(p3).normalize();
let w = p3.clone().sub(p1).normalize();
let p13 = p1.clone().sub(p3);
if (equaln(Math.abs(v1.dot(v2)), 1, 1e-6) && equaln(Math.abs(v1.dot(w)), 1, 1e-6)) //平行共线
{
let tmpPts = [p1, p2, p3, p4];
tmpPts.sort(comparePoint('xyz'));
if (equalv3(tmpPts[1], p3) || equalv3(tmpPts[1], p4))
{
pts = [tmpPts[1], tmpPts[2]];
}
else
{
pts = [midPoint(tmpPts[1], tmpPts[2])]
}
}
else if (equaln(Math.abs(v1.dot(v2)), 1, 1e-6)) //平行不共线
{
return [];
}
else if (equaln(getDeterminantFor3V(v1, v2, w), 0, 0.01))
{
let t: number;
if (x12 * y43 - y12 * x43)
{
t = (x42 * y43 - x43 * y42) / (x12 * y43 - y12 * x43);
}
else if (x12 * z43 - x43 * z12)
{
t = (x42 * z43 - x43 * z42) / (x12 * z43 - x43 * z12);
}
else
{
t = (y42 * z43 - y43 * z42) / (y12 * z43 - y43 * z12);
}
pts = [new Vector3(x12 * t + p2.x, y12 * t + p2.y, z12 * t + p2.z)]
}
return pts;
let d1343 = p13.x * p43.x + p13.y * p43.y + p13.z * p43.z;
let d4321 = p43.x * p21.x + p43.y * p21.y + p43.z * p21.z;
let d1321 = p13.x * p21.x + p13.y * p21.y + p13.z * p21.z;
let d4343 = p43.x * p43.x + p43.y * p43.y + p43.z * p43.z;
let d2121 = p21.x * p21.x + p21.y * p21.y + p21.z * p21.z;
let denom = d2121 * d4343 - d4321 * d4321;
if (Math.abs(denom) < epsilon)
return;
let numer = d1343 * d4321 - d1321 * d4343;
let mua = numer / denom;
let mub = (d1343 + d4321 * (mua)) / d4343;
let resultSegmentPoint1 = new Vector3();
resultSegmentPoint1.x = p1.x + mua * p21.x;
resultSegmentPoint1.y = p1.y + mua * p21.y;
resultSegmentPoint1.z = p1.z + mua * p21.z;
let resultSegmentPoint2 = new Vector3();
resultSegmentPoint2.x = p3.x + mub * p43.x;
resultSegmentPoint2.y = p3.y + mub * p43.y;
resultSegmentPoint2.z = p3.z + mub * p43.z;
return [resultSegmentPoint1, resultSegmentPoint2];
}
//直线和直线
export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOption)
{
let pt = IntersectLAndLFor3D(l1.StartPoint, l1.EndPoint, l2.StartPoint, l2.EndPoint);
let pt = IntersectLine3AndLine3(l1.StartPoint, l1.EndPoint, l2.StartPoint, l2.EndPoint);
return pt ? CheckPointOnCurve([pt], l1, l2, extType) : [];
}

Loading…
Cancel
Save