!67 三维空间相交和切割

Merge pull request !67 from ZoeLeeFZ/3DTo2D_pr
pull/767481/MERGE
ChenX 6 years ago
parent 6cbe7a5d39
commit 50aaabeed9

@ -1,5 +1,151 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`三维空间圆圆相交测试 1`] = `
Array [
Vector3 {
"x": 3.8465654731285666,
"y": -0.4898400510314999,
"z": 0.3777515851723181,
},
Vector3 {
"x": 4.518686772594937,
"y": -2.2643579789591692,
"z": -0.09066385360916451,
},
]
`;
exports[`三维空间圆圆相交测试 2`] = `
Array [
Vector3 {
"x": 1.25,
"y": -4.841229182759271,
"z": 0,
},
Vector3 {
"x": 1.25,
"y": 4.841229182759271,
"z": 0,
},
]
`;
exports[`三维空间圆圆相交测试 3`] = `
Array [
Vector3 {
"x": 1.25,
"y": 0,
"z": -4.841229182759271,
},
Vector3 {
"x": 1.25,
"y": 0,
"z": 4.841229182759271,
},
]
`;
exports[`三维空间圆圆相交测试 4`] = `
Array [
Vector3 {
"x": 0,
"y": -11.313088368701884,
"z": -9.556275638274851,
},
Vector3 {
"x": 0,
"y": -9.579281670837858,
"z": -2.8986776905615708,
},
]
`;
exports[`三维空间圆圆相交测试 5`] = `Array []`;
exports[`三维空间直线和圆相交测试 1`] = `
Array [
Vector3 {
"x": 7.265045456946408,
"y": 0,
"z": 1.514708484572001,
},
Vector3 {
"x": 3.93574588263578,
"y": 0,
"z": 4.789429377336553,
},
]
`;
exports[`三维空间直线和圆相交测试 2`] = `
Array [
Vector3 {
"x": -3.622627029705465,
"y": -3.4462404738565997,
"z": 0,
},
Vector3 {
"x": -3.622627029705464,
"y": 3.4462404738566006,
"z": 0,
},
]
`;
exports[`三维空间直线和圆相交测试 3`] = `
Array [
Vector3 {
"x": 9.796270630192112,
"y": -13.16305455920182,
"z": 4.841809080303142,
},
Vector3 {
"x": 9.796270630192113,
"y": -6.270573611488618,
"z": 4.841809080303142,
},
]
`;
exports[`三维空间直线和圆相交测试 4`] = `
Array [
Vector3 {
"x": 12.384261138056765,
"y": -13.163054559201814,
"z": 6.346016491847222,
},
Vector3 {
"x": 12.384261138056765,
"y": -6.270573611488626,
"z": 6.346016491847221,
},
]
`;
exports[`三维空间直线相交测试 1`] = `
Vector3 {
"x": 5,
"y": 5,
"z": 5,
}
`;
exports[`三维空间直线相交测试 2`] = `
Vector3 {
"x": 4.75,
"y": 4.75,
"z": 4.75,
}
`;
exports[`三维空间直线相交测试 3`] = `
Vector3 {
"x": 5,
"y": 5,
"z": 5,
}
`;
exports[`相交测试 1`] = `
Vector3 {
"x": 0.5,

@ -1,6 +1,12 @@
import * as THREE from 'three';
import { IntersectLAndL } from '../../src/GraphicsSystem/IntersectWith';
import { IntersectLAndLFor3D, IntersectCircleAndCircle, IntersectOption } from '../../src/GraphicsSystem/IntersectWith';
import { Vector3 } from 'three';
import { CADFile } from '../../src/DatabaseServices/CADFile';
import { Curve } from '../../src/DatabaseServices/Curve';
import { Circle } from '../../src/DatabaseServices/Circle';
import { Arc } from '../../src/DatabaseServices/Arc';
import { Line } from '../../src/DatabaseServices/Line';
test('相交测试', () =>
{
@ -12,19 +18,102 @@ test('相交测试', () =>
let p5 = new THREE.Vector3(3, 0, 0);
let p6 = new THREE.Vector3(6, 0, 0);
let res = IntersectLAndL(p1, p2, p3, p4);/*?*/
let res = IntersectLAndLFor3D(p1, p2, p3, p4);/*?*/
expect(res).toMatchSnapshot();
res = IntersectLAndL(p1, p2, p5, p6);/*?*/
res = IntersectLAndLFor3D(p1, p2, p5, p6);/*?*/
expect(res).toMatchSnapshot();
let ins = IntersectLAndL(
let ins = IntersectLAndLFor3D(
new THREE.Vector3(0, 5),
new THREE.Vector3(5, 5),
new THREE.Vector3(0.5, 1),
new THREE.Vector3(0.5, 8));
expect(ins).toMatchSnapshot();
}
})
test('三维空间直线相交测试', () =>
{
let p1 = new THREE.Vector3();
let p2 = new THREE.Vector3(10, 10, 10);
let p3 = new THREE.Vector3(5, 5, 5);
let p4 = new THREE.Vector3(5, 10, 5);
let p5 = new THREE.Vector3(3, 3, 3);
let p6 = new THREE.Vector3(6, 6, 6);
let res = IntersectLAndLFor3D(p1, p2, p3, p4);/*?*/
expect(res).toMatchSnapshot();
res = IntersectLAndLFor3D(p1, p2, p5, p6);/*?*/
expect(res).toMatchSnapshot();
res = IntersectLAndLFor3D(p2, p6, p3, p4);/*?*/
expect(res).toMatchSnapshot();
res = IntersectLAndLFor3D(
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(
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();
})
test('三维空间圆圆相交测试', () =>
{
let data = [["Circle", 1, 1, 3, false, 7, -1, [-0.1485675258840154, -0.98346692600856, 0.10353982663678746, 0, 0.8068528994682419, -0.18108783903750572, -0.5623127183093208, 0, 0.5717657639911589, 0, 0.8204169129946106, 0, 5.585923427922135, -0.5874251796993211, -0.834443475807827, 1], 1, 2.1223349919617873], ["Circle", 1, 1, 9, false, 7, -1, [-0.1485675258840154, -0.98346692600856, 0.10353982663678746, 0, 0.8068528994682419, -0.18108783903750572, -0.5623127183093208, 0, 0.5717657639911589, 0, 0.8204169129946106, 0, 3.2540542870196947, -1.8996318241962369, 0.7906850652516981, 1], 1, 1.5840127550993974]]
testCirAndCirIntersect(data);
data = [["Circle", 1, 1, 3, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, 5], ["Circle", 1, 1, 4, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2.5, 0, 0, 1], 1, 5]];
testCirAndCirIntersect(data);
data = [["Circle", 1, 1, 5, false, 7, -1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 1, 5], ["Circle", 1, 1, 6, false, 7, -1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 2.5, 0, 0, 1], 1, 5]];
testCirAndCirIntersect(data);
data = [["Arc", 1, 1, 10, false, 7, -1, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, -7.223901135674274, -7.066640793063616, 1], 2, 4.787455889013074, 2.4468553886273967, 0.7203768859081977, true], ["Arc", 1, 1, 11, false, 7, -1, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, -12.887397630639091, -5.59172322768673, 1], 2, 4.265691675276281, 3.020045238916937, 0.9631807673370143, true]]
testCirAndCirIntersect(data);
data = [["Circle", 1, 1, 4, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2.5, 0, 0, 1], 1, 5], ["Circle", 1, 1, 6, false, 7, -1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 2.5, 0, 0, 1], 1, 5]];
testCirAndCirIntersect(data);
})
test('三维空间直线和圆相交测试', () =>
{
let data = [["Circle", 1, 1, 6, false, 7, -1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 2.5, 0, 0, 1], 1, 5], ["Line", 1, 1, 12, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [2.4219301113484804, 0, 6.278428496635537], [9.19486541121855, 0, -0.38347507700715716]]]
testLineAndCirIntersect(data);
data = [["Circle", 1, 1, 3, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, 5], ["Line", 1, 1, 13, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [-3.6226270297054635, 5.273119429622456, 0], [-3.6226270297054652, -5.297100907223948, 0]]];
testLineAndCirIntersect(data);
data = [["Circle", 1, 1, 3, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 13.418897659897576, -9.71681408534522, 4.841809080303142, 1], 1, 5], ["Line", 1, 1, 13, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [9.796270630192113, -4.443694655722764, 4.841809080303142], [9.796270630192112, -15.013914992569168, 4.841809080303142]]];
testLineAndCirIntersect(data);
data = [["Circle", 1, 1, 3, false, 7, -1, [0.8517840265050032, 0, -0.5238930923298417, 0, 0, 1, 0, 0, 0.5238930923298417, 0, 0.8517840265050032, 0, 15.469956975945145, -9.71681408534522, 4.4481472148971575, 1], 1, 5], ["Line", 1, 1, 13, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 1, [12.384261138056765, -4.443694655722764, 6.346016491847221], [12.384261138056765, -15.013914992569168, 6.346016491847222]]];
testLineAndCirIntersect(data);
})
function loadFile(data)
{
let file = new CADFile();
file.Data = data;
let cus: Curve[] = [];
for (let i = 0; i < file.Data.length; i++)
{
cus.push(file.ReadObject(undefined) as Curve);
}
return cus;
}
function testCirAndCirIntersect(data)
{
let cus = loadFile(data) as Array<Circle | Arc>;
let pts = IntersectCircleAndCircle(cus[0], cus[1]);
expect(pts).toMatchSnapshot();
}
function testLineAndCirIntersect(data)
{
let cus = loadFile(data);
let [cu1, cu2] = cus[0] instanceof Line ? cus : cus.reverse();
let pts = cu1.IntersectWith(cu2, IntersectOption.ExtendBoth);
expect(pts).toMatchSnapshot();
}

@ -34,7 +34,7 @@ Vector3 {
exports[`最近点 1`] = `
Vector3 {
"x": -2.5,
"x": -2.499999999999999,
"y": -2.499999999999999,
"z": 0,
}

@ -277,131 +277,6 @@ Array [
]
`;
exports[`单刀 6`] = `
Array [
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 0,
},
},
Object {
"bul": 1,
"pt": Vector2 {
"x": 5,
"y": 0,
},
},
Object {
"bul": -0.41421356237309503,
"pt": Vector2 {
"x": 5,
"y": 5,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 2.5,
"y": 7.5,
},
},
]
`;
exports[`单刀 7`] = `
Array [
Object {
"bul": -0.41421356237309503,
"pt": Vector2 {
"x": 2.5,
"y": 7.5,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 5,
"y": 10,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 10,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 0,
},
},
]
`;
exports[`单刀 8`] = `
Array [
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 0,
},
},
Object {
"bul": 1,
"pt": Vector2 {
"x": 5,
"y": 0,
},
},
Object {
"bul": -1,
"pt": Vector2 {
"x": 5,
"y": 5,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 5,
"y": 10,
},
},
]
`;
exports[`单刀 9`] = `
Array [
Object {
"bul": 0,
"pt": Vector2 {
"x": 5,
"y": 10,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 10,
},
},
Object {
"bul": 0,
"pt": Vector2 {
"x": 0,
"y": 0,
},
},
]
`;
exports[`单刀闭合 1`] = `
Array [
Object {

@ -1,55 +1,44 @@
import * as THREE from 'three';
import { Vector3, Vector2 } from 'three';
import { app } from '../ApplicationServices/Application';
import { Arc } from '../DatabaseServices/Arc';
import { Command } from '../Editor/CommandMachine';
import { PromptStatus } from '../Editor/PromptResult';
import { RenderType } from '../GraphicsSystem/Enum';
import { Arc } from '../DatabaseServices/Arc';
export class DrawArc implements Command
{
async exec()
{
let pt1 = app.m_Editor.m_MouseCtrl.m_CurMousePointWCS.clone();
let pt2 = pt1;
let pt3 = pt2;
app.m_Editor.UpdateScreen();
let ptRes = await app.m_Editor.GetPoint({ Msg: "请输入第一个点:" });
if (ptRes.Status != PromptStatus.OK)
{
return;
}
pt1 = ptRes.Value;
let pt1 = ptRes.Value;
let ptRes2 = await app.m_Editor.GetPoint({ Msg: "请输入第二个点:", BasePoint: pt1, AllowDrawRubberBand: true });
if (ptRes2.Status != PromptStatus.OK)
{
return;
}
pt2 = ptRes2.Value;
let pt2 = ptRes2.Value;
let arc = new Arc();
arc.ApplyMatrix(app.m_Editor.UCSMatrix);
app.m_Database.ModelSpace.Append(arc);
app.m_Editor.AddNoSnapEntity(arc);
let ptRes3 = await app.m_Editor.GetPoint({
Msg: "请输入第三个点:", Callback: (p) =>
const updateArc = (p) =>
{
if (!p.equals(pt2) && !p.equals(pt1))
{
arc.FromThreePoint(pt1, pt2, p);
arc.Update();
if (!arc.Id)
{
app.m_Database.ModelSpace.Append(arc);
}
}
}
let ptRes3 = await app.m_Editor.GetPoint({
Msg: "请输入第三个点:",
Callback: updateArc
});
if (ptRes.Status != PromptStatus.OK)
{
return;
}
app.m_Database.hm.EndCmd();
if (ptRes3.Status != PromptStatus.OK)
arc.Erase();
else
updateArc(ptRes3.Value);
}
}

@ -1,11 +1,9 @@
import * as THREE from 'three';
import { Box3, Vector3 } from 'three';
import { Vector3 } from 'three';
import { app } from '../ApplicationServices/Application';
import { Vec3DTo2D } from '../Common/CurveUtils';
import { Arc } from '../DatabaseServices/Arc';
import { Circle } from '../DatabaseServices/Circle';
import { Line } from '../DatabaseServices/Line';
import { Polyline } from '../DatabaseServices/Polyline';
import { Command } from '../Editor/CommandMachine';
import { PromptStatus } from '../Editor/PromptResult';
import { midPoint } from '../Geometry/GeUtils';
@ -134,56 +132,6 @@ void main() {
}
*/
export class DrawRect implements Command
{
async exec()
{
let ptRes = await app.m_Editor.GetPoint();
if (ptRes.Status != PromptStatus.OK)
{
return;
}
let p1: THREE.Vector3;
let p2: THREE.Vector3;
p1 = ptRes.Value;
let rec = new Polyline();
rec.CloseMark = true;
app.m_Database.ModelSpace.Append(rec);
app.m_Editor.AddNoSnapEntity(rec);
let box = new Box3();
let updateRect = (p1, p2) =>
{
box.setFromPoints([p2, p1]);
let px1 = Vec3DTo2D(box.min);
let px3 = Vec3DTo2D(box.max);
let px2 = new THREE.Vector2(px3.x, px1.y);
let px4 = new THREE.Vector2(px1.x, px3.y);
rec.LineData = [{ pt: px1, bul: 0 },
{ pt: px2, bul: 0 },
{ pt: px3, bul: 0 },
{ pt: px4, bul: 0 }];
}
ptRes = await app.m_Editor.GetPoint({
Callback: (p) =>
{
updateRect(p, p1);
}
});
if (ptRes.Status == PromptStatus.OK)
updateRect(ptRes.Value, p1);
else
rec.Erase();
}
}
export class DrawCircle implements Command
{
async exec()
@ -192,7 +140,6 @@ export class DrawCircle implements Command
Msg: "指定圆的圆心",
KeyWordList: [{ key: "3P", msg: "三点" }, { key: "2P", msg: "二点" }, { key: "T", msg: "切点、切点、半径" }]
});
switch (ptRes.Status)
{
case PromptStatus.Cancel:
@ -228,7 +175,10 @@ export class DrawCircle implements Command
async DrawCircleUseRadious(val: Vector3)
{
let cir = new Circle(val, 1e-3);
let cir = new Circle();
cir.ApplyMatrix(app.m_Editor.UCSMatrix);
cir.Center = val;
app.m_Database.ModelSpace.Append(cir);
app.m_Editor.AddNoSnapEntity(cir);
@ -246,22 +196,25 @@ export class DrawCircle implements Command
async DrawCicleUseTwoPoint()
{
let cir = new Circle(app.m_Editor.m_MouseCtrl.m_CurMousePointWCS.clone(), 1e-3);
let ptRes1 = await app.m_Editor.GetPoint({
Msg: "指定圆直径的第一个端点:",
});
if (ptRes1.Status != PromptStatus.OK)
return;
let cir = new Circle();
app.m_Database.ModelSpace.Append(cir);
app.m_Editor.AddNoSnapEntity(cir);
let ptRes2 = await app.m_Editor.GetPoint({
Msg: "指定圆直径的第二个端点:",
BasePoint: ptRes1.Value,
AllowDrawRubberBand: true,
Callback: (v) => { cir.Radius = v.distanceTo(ptRes1.Value) / 2; cir.Center = midPoint(v, ptRes1.Value) },
Callback: (v) =>
{
cir.Radius = v.distanceTo(ptRes1.Value) / 2;
cir.Center = midPoint(v, ptRes1.Value)
},
});
if (ptRes2.Status === PromptStatus.OK)
{
@ -269,22 +222,19 @@ export class DrawCircle implements Command
cir.Center = midPoint(ptRes2.Value, ptRes1.Value);
}
else
{
cir.Erase();
}
app.m_Editor.ClearSnapEntity();
}
async DrawCicleUseThreePoint()
{
let cir = new Circle(app.m_Editor.m_MouseCtrl.m_CurMousePointWCS.clone(), 1e-3);
let ar = new Arc();
let ptRes1 = await app.m_Editor.GetPoint({
Msg: "指定圆上第一个点:"
});
if (ptRes1.Status != PromptStatus.OK)
return;
let cir = new Circle();
let ar = new Arc();
app.m_Database.ModelSpace.Append(cir);
let ptRes2 = await app.m_Editor.GetPoint({
@ -300,7 +250,12 @@ export class DrawCircle implements Command
Msg: "指定圆上第三个点:",
BasePoint: ptRes2.Value,
AllowDrawRubberBand: true,
Callback: (v) => { ar.FromThreePoint(ptRes1.Value, ptRes2.Value, v); cir.Radius = ar.Radius; cir.Center = ar.Center },
Callback: (v) =>
{
ar.FromThreePoint(ptRes1.Value, ptRes2.Value, v);
cir.Radius = ar.Radius;
cir.Center = ar.Center
},
});
if (ptRes3.Status === PromptStatus.OK)
{
@ -309,12 +264,8 @@ export class DrawCircle implements Command
cir.Center = ar.Center;
}
else
{
cir.Erase();
}
app.m_Editor.ClearSnapEntity();
}
async DrawCicleUseCutoffPointAndRadious()
{
// let cir = new Circle(app.m_Editor.m_MouseCtrl.m_CurMousePointWCS.clone(), 1e-3);

@ -1,9 +1,11 @@
import { Vector3 } from 'three';
import { Matrix4, Vector3, Vector2 } from 'three';
import { app } from '../ApplicationServices/Application';
import { Vec2DTo3D, Vec3DTo2D, getCirAngleByChordAndTangent, rotateLine } from '../Common/CurveUtils';
import { Vec2DTo3D, Vec3DTo2D, getCirAngleByChordAndTangent } from '../Common/CurveUtils';
import { Polyline, PolylineProps } from '../DatabaseServices/Polyline';
import { Command } from '../Editor/CommandMachine';
import { PromptStatus } from '../Editor/PromptResult';
import { PromptStatus, PromptSsgetResult } from '../Editor/PromptResult';
import { rotatePoint } from '../Geometry/GeUtils';
import { GetPointPrompt } from '../Common/InputState';
enum PolylineModel
{
@ -11,157 +13,121 @@ enum PolylineModel
Line = 1
}
export class DrawPolyline implements Command
export class DrawPolyline
{
private m_Model;
model: PolylineModel = PolylineModel.Line;
async exec()
{
app.m_Editor.m_CommandStore.Prompt("请输入一个点:");
let ptRes = await app.m_Editor.GetPoint({ Msg: "请输入第一个点:" });
if (ptRes.Status != PromptStatus.OK)
{
return;
}
this.m_Model = PolylineModel.Line;
this.model = PolylineModel.Line;
let basePt = ptRes.Value;
//存储基点
let BasePts = [basePt];
//多段线最终点
let data: PolylineProps = {
pt: Vec3DTo2D(basePt),
bul: 0
}
//储存多段线数据
let lineProps = [data]
let pl = new Polyline();
pl.ApplyMatrix(app.m_Editor.UCSMatrix);
app.m_Database.ModelSpace.Append(pl);
app.m_Editor.AddNoSnapEntity(pl);
let polyline = new Polyline(lineProps);
let Callback = (p: Vector3) =>
this.UpdatePoint(pl, p);
app.m_Database.ModelSpace.Append(polyline);
// 切线
let tangentLine: Vector3;
// 弦
let chord: Vector3;
// 圆心角
let cirAng: number;
// 圆弧方向
let dir: Vector3;
let firstOps: GetPointPrompt = { Msg: "请输入第一个点:", Callback };
let keywords = [{ msg: "圆弧", key: "A" }, { msg: "直线", key: "L" }, { msg: "放弃", key: "U" }];
let keywords2 = keywords.concat([{ msg: "闭合", key: "C" }]);
let nextOps: GetPointPrompt = { Msg: "请点击下一个点或", Callback };
let KeyWordList = [{ msg: "圆弧", key: "A" }, { msg: "直线", key: "L" }, { msg: "放弃", key: "U" }];
//返回一步
let restore = () =>
{
lineProps.pop();
polyline.LineData = lineProps;
}
// 更新多段线凸度
let updateBul = (endPt: Vector3, startPt: Vector3) =>
{
// 弦长矢量
chord = endPt.clone().sub(startPt);
cirAng = getCirAngleByChordAndTangent(chord, tangentLine);
if (cirAng)
{
//凸度
let bul = Math.tan(cirAng / 4);
lineProps[lineProps.length - 2].bul = bul
}
}
while (true)
{
data = {
pt: Vec3DTo2D(basePt),
bul: 0
}
if (lineProps.length === 2)
let ops: GetPointPrompt;
if (pl.NumberOfVertices === 0)
ops = firstOps;
else
{
KeyWordList.push({ msg: "闭合", key: "C" })
ops = nextOps;
ops.BasePoint = pl.EndPoint;
if (pl.NumberOfVertices > 3)
nextOps.KeyWordList = keywords2;
else
nextOps.KeyWordList = keywords;
}
lineProps.push(data);
app.m_Editor.m_CommandStore.Prompt("请输入点2:");
ptRes = await app.m_Editor.GetPoint({
Msg: "请输入点2:",
BasePoint: basePt,
AllowDrawRubberBand: true,
KeyWordList,
Callback: (v) =>
pl.AddVertexAt(pl.NumberOfVertices, new Vector2());
let p = await app.m_Editor.GetPoint(ops);
if (p.Status === PromptStatus.OK)
this.UpdatePoint(pl, p.Value);
else if (p.Status === PromptStatus.Keyword)
{
if (this.m_Model === 0)
this.RemoveLastVertex(pl);
if (p.StringResult === "A")
{
if (!tangentLine) tangentLine = new Vector3(1, 0, 0);
data.pt.set(v.x, v.y);
updateBul(v, basePt);
polyline.LineData = lineProps;
this.model = PolylineModel.Arc;
}
else if (p.StringResult === "L")
{
this.model = PolylineModel.Line;
if (pl.NumberOfVertices > 0)
pl.SetBulgeAt(pl.NumberOfVertices - 1, 0);
}
});
if (ptRes.Status == PromptStatus.OK)
else if (p.StringResult === "U")
{
data.pt.set(ptRes.Value.x, ptRes.Value.y)
if (this.m_Model === 1)
this.RemoveLastVertex(pl);
if (pl.NumberOfVertices > 0)
{
//切线
tangentLine = ptRes.Value.clone().sub(basePt).normalize();
this.model = pl.GetBuilgeAt(pl.NumberOfVertices - 1) !== 0 ?
PolylineModel.Arc : PolylineModel.Line;
}
else
{
updateBul(ptRes.Value, basePt);
tangentLine = rotateLine(tangentLine, cirAng)
}
polyline.LineData = lineProps;
BasePts.push(basePt);
basePt = ptRes.Value;
continue;
}
else if (ptRes.Status == PromptStatus.Keyword)
{
//是否闭合曲线
if (ptRes.StringResult == "C")
else if (p.StringResult === "C")
{
data.pt = lineProps[0].pt;
let endPt = Vec2DTo3D(data.pt);
if (this.m_Model === PolylineModel.Arc)
if (this.model === PolylineModel.Arc)
{
polyline.CloseMark = true;
updateBul(endPt, basePt);
pl.AddVertexAt(pl.NumberOfVertices, new Vector2());
this.UpdatePoint(pl, pl.StartPoint);
this.RemoveLastVertex(pl);
}
polyline.LineData = lineProps;
pl.CloseMark = true;
break;
}
if (ptRes.StringResult == "U")
{
basePt = BasePts.pop();
lineProps.pop();
if (this.m_Model === 1)
tangentLine = basePt.clone().sub(BasePts[BasePts.length - 1]).normalize();
}
else
{
data = lineProps[lineProps.length - 2];
cirAng = Math.atan(data.bul) * 4;
tangentLine = rotateLine(tangentLine, -cirAng)
this.RemoveLastVertex(pl);
break;
}
}
else if (ptRes.StringResult == "A")
{
this.m_Model = PolylineModel.Arc;
if (pl.NumberOfVertices < 2)
pl.Erase();
}
else if (ptRes.StringResult == "L")
UpdatePoint(pl: Polyline, pt: Vector3)
{
lineProps[lineProps.length - 2].bul = 0;
this.m_Model = PolylineModel.Line;
}
restore();
}
else
let ptCout = pl.NumberOfVertices;
let p = pt.clone().applyMatrix4(pl.OCSInv);
pl.SetPointAt(ptCout - 1, Vec3DTo2D(p));
if (this.model === PolylineModel.Arc && ptCout > 1)
{
restore();
break;
let pLast = pl.GetPoint2dAt(ptCout - 2);
//弦长
let chord = p.clone().sub(Vec2DTo3D(pLast));
//切线
let tangent: Vector3;
if (ptCout > 2)
tangent = pl.GetCurveAtIndex(ptCout - 3).GetFistDeriv(1).applyMatrix4(pl.OCSInv);
else
tangent = new Vector3(1, 0, 0);
let cirAng = getCirAngleByChordAndTangent(chord, tangent);
if (cirAng)
pl.SetBulgeAt(ptCout - 2, Math.tan(cirAng * 0.25));
}
app.m_Editor.UpdateScreen();
}
RemoveLastVertex(pl: Polyline)
{
if (pl.NumberOfVertices > 0)
pl.RemoveVertexAt(pl.NumberOfVertices - 1);
}
}

@ -0,0 +1,53 @@
import * as THREE from 'three';
import { Box3, Vector3 } from 'three';
import { app } from '../ApplicationServices/Application';
import { Vec3DTo2D } from '../Common/CurveUtils';
import { Polyline } from '../DatabaseServices/Polyline';
import { Command } from '../Editor/CommandMachine';
import { PromptStatus } from '../Editor/PromptResult';
export class DrawRect implements Command
{
async exec()
{
let ptRes = await app.m_Editor.GetPoint();
if (ptRes.Status != PromptStatus.OK)
return;
let p1: THREE.Vector3;
let p2: THREE.Vector3;
p1 = ptRes.Value;
let rec = new Polyline();
rec.CloseMark = true;
rec.ApplyMatrix(app.m_Editor.UCSMatrix);
app.m_Database.ModelSpace.Append(rec);
app.m_Editor.AddNoSnapEntity(rec);
let box = new Box3();
let updateRect = (p1, p2) =>
{
box.setFromPoints([p2, p1].map((p: Vector3) => p.clone().applyMatrix4(rec.OCSInv)));
let px1 = Vec3DTo2D(box.min);
let px3 = Vec3DTo2D(box.max);
let px2 = new THREE.Vector2(px3.x, px1.y);
let px4 = new THREE.Vector2(px1.x, px3.y);
rec.LineData = [
{ pt: px1, bul: 0 },
{ pt: px2, bul: 0 },
{ pt: px3, bul: 0 },
{ pt: px4, bul: 0 }];
}
ptRes = await app.m_Editor.GetPoint({
Callback: (p) => updateRect(p, p1)
});
if (ptRes.Status == PromptStatus.OK)
updateRect(ptRes.Value, p1);
else
rec.Erase();
}
}

@ -1,6 +1,4 @@
import { Callback } from 'awesome-typescript-loader/dist/paths-plugin';
import * as THREE from 'three';
import { app } from '../ApplicationServices/Application';
import { CADFile } from '../DatabaseServices/CADFile';
import { Entity } from '../DatabaseServices/Entity';
@ -11,33 +9,33 @@ import { SelectPick } from '../Editor/SelectPick';
import { SelectSet, SelectType } from '../Editor/SelectSet';
import { MoveMatrix } from '../Geometry/GeUtils';
export class Stretch implements Command
//拉伸的解析数据
interface StretchData
{
moveEntityList: Entity[];//被移动的图元(所有点都被选中)
stretchEntityMap: Map<Entity, Array<number>>; //被拉伸的图元,对照被拉伸的点索引.
}
m_CacheEntity: Map<Entity, CADFile> = new Map<Entity, CADFile>();
async exec(ss: SelectSet)
export class Stretch implements Command
{
if (ss.SelectObjectList.length == 0)
m_CacheEntity: Map<Entity, CADFile> = new Map<Entity, CADFile>();
async exec()
{
let ssRes = await app.m_Editor.GetSelection();
if (ssRes.Status != PromptStatus.OK)
return;
let ssRes = await app.m_Editor.GetSelection({ UseSelect: true, Msg: "请选择拉伸对象:" });
if (ssRes.Status != PromptStatus.OK) return;
let ss = ssRes.SelectSet;
ss == ssRes.SelectSet;
if (ss.SelectEntityList.length === 0)
return;
}
let p1 = await app.m_Editor.GetPoint({ Msg: "请选择第一个拉伸点:" });
let p1 = await app.m_Editor.GetPoint({ Msg: "指定基点:" });//, KeyWordList: [{ msg: "位移", key: "D" }]
if (p1.Status != PromptStatus.OK) return;
let data = this.parse(ss);
for (let [obj] of data.str)
app.m_Editor.AddNoSnapEntity(obj.userData);
for (let [e] of data.stretchEntityMap)
app.m_Editor.AddNoSnapEntity(e);
let lastP = p1.Value.clone();
let p2 = await app.m_Editor.GetPoint(
{
BasePoint: p1.Value,
Msg: "请选择第二个拉伸点:",
Msg: "指定第二个点:",//或 <使用第一个点作为位移>
Callback: (p) =>
{
let v = p.clone().sub(lastP);
@ -52,42 +50,37 @@ export class Stretch implements Command
this.m_CacheEntity.clear();
}
parse(ss: SelectSet): { str: Map<THREE.Object3D, Array<number>>, move: Array<THREE.Object3D> }
parse(ss: SelectSet): StretchData
{
let stretchPtsIndexMap = new Map<THREE.Object3D, Array<number>>();
let move = [];
let data: StretchData =
{
stretchEntityMap: new Map<Entity, Array<number>>(),
moveEntityList: []
};
for (let set of ss.SelectSetList)
{
if (set instanceof SelectPick)
{
for (let obj of set.m_SelectList)
{
move.push(obj);
}
data.moveEntityList.push(obj.userData);
}
else if (set instanceof SelectBox)
{
if (set.m_SelectType == SelectType.W)
{
for (let obj of set.m_SelectList)
{
move.push(obj);
}
data.moveEntityList.push(obj.userData);
}
else
{
for (let obj of set.m_SelectList)
{
let indexArr = [];
stretchPtsIndexMap.set(obj, indexArr);
let en = obj.userData;
if (en && en instanceof Entity)
{
let f = new CADFile();
en.WriteFile(f);
this.m_CacheEntity.set(en, f);
this.CacheEntity(en);
data.stretchEntityMap.set(en, indexArr);
let pts = en.GetStretchPoints();
for (let i = pts.length; i--;)
{
@ -103,27 +96,37 @@ export class Stretch implements Command
}
}
}
return {
str: stretchPtsIndexMap,
move: move
}
for (let e of data.moveEntityList)
this.CacheEntity(e);
return data;
}
s(d: { str: Map<THREE.Object3D, Array<number>>, move: Array<THREE.Object3D> }, vec: THREE.Vector3)
s(d: StretchData, vec: THREE.Vector3)
{
let moveMat = MoveMatrix(vec);
for (let obj of d.move)
for (let e of d.moveEntityList)
{
obj.applyMatrix(moveMat);
this.RestoreEntity(e);
e.ApplyMatrix(moveMat);
}
for (let [obj, arr] of d.str)
{
if (obj.userData instanceof Entity)
for (let [e, arr] of d.stretchEntityMap)
{
let f = this.m_CacheEntity.get(obj.userData);
f.Reset();
obj.userData.ReadFile(f);
obj.userData.MoveStretchPoints(arr, vec);
this.RestoreEntity(e);
e.MoveStretchPoints(arr, vec);
}
}
CacheEntity(e: Entity)
{
let f = new CADFile();
e.WriteFile(f);
this.m_CacheEntity.set(e, f);
}
RestoreEntity(e: Entity)
{
let f = this.m_CacheEntity.get(e);
f.Reset();
e.ReadFile(f);
}
}

@ -70,7 +70,7 @@ export class Command_Trim implements Command
if (s instanceof SelectBox)
{
let set = s;
splitCus = splitCus.filter(cu => { return set.IntersectObject(cu.Draw(RenderType.Wireframe)) });
splitCus = splitCus.filter(c => set.IntersectObject(c.Draw(RenderType.Wireframe)));
let needBreakCus: Curve[] = [];
while (splitCus.length > 0)

@ -0,0 +1,89 @@
import { app } from "../../ApplicationServices/Application";
import { Circle } from "../../DatabaseServices/Circle";
import { Curve } from "../../DatabaseServices/Curve";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { IntersectLAndLFor3D, IntersectOption, IntersectCircleAndCircle } from "../../GraphicsSystem/IntersectWith";
import { Line } from "three";
import { Arc } from "../../DatabaseServices/Arc";
export class TestIntersect implements Command
{
async exec()
{
// this.testLineAndLine();
// this.testLineAndCirOrArc();
this.testCirAndCir()
app.m_Editor.UpdateScreen();
}
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 });
if (exRefSsRes.Status !== PromptStatus.OK) return;
let cus = exRefSsRes.SelectSet.SelectEntityList as Curve[];
if (cus.length > 1)
{
let [cu1, cu2] = cus[0] instanceof Line ? cus : cus.reverse();
let pts = cu1.IntersectWith(cu2, IntersectOption.ExtendBoth);
if (pts.length)
{
pts.forEach(p =>
{
let cir = new Circle(p, 0.2);
cir.ColorIndex = 2;
app.m_Database.ModelSpace.Append(cir);
})
} else
{
cu1.ColorIndex = 1;
cu2.ColorIndex = 1;
}
}
}
async testCirAndCir()
{
let exRefSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true });
if (exRefSsRes.Status !== PromptStatus.OK) return;
let cus = exRefSsRes.SelectSet.SelectEntityList as Array<Circle | Arc>;
if (cus.length > 1)
{
let pt = IntersectCircleAndCircle(cus[0], cus[1]);
console.log('pt: ', pt);
if (pt.length)
{
cus[0].ColorIndex = 7;
cus[1].ColorIndex = 7;
pt.forEach(p =>
{
let cir = new Circle(p, 0.1);
cir.ColorIndex = 2;
app.m_Database.ModelSpace.Append(cir);
})
} else
{
cus[0].ColorIndex = 1;
cus[1].ColorIndex = 1;
}
}
}
}

@ -67,6 +67,14 @@ export function arrayLast<T>(arr: Array<T>): T
return arr[arr.length - 1];
}
/**
*
*
* @export
* @template T
* @param {Array<T>} arr
* @returns {Array<T>}
*/
export function arraySortByNumber<T>(arr: Array<T>): Array<T>
{
arr.sort(sortNumberCompart);
@ -77,6 +85,7 @@ export function arraySortByNumber<T>(arr: Array<T>): Array<T>
*
*
* @param {(e1, e2) => boolean} [checkFuction]
* @returns {Array<T>}
*/
export function arrayRemoveDuplicateBySort<T>(arr: Array<T>, checkFuction?: (e1, e2) => boolean): Array<T>

@ -1,21 +1,13 @@
import { Vector2, Vector3 } from 'three';
import { Matrix3, Vector2, Vector3 } from 'three';
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 { equal, equaln } from '../Geometry/GeUtils';
import { Matrix2 } from '../Geometry/Matrix2';
import { Count } from '../Geometry/Count';
import { CurveMap } from '../Geometry/CurveMap';
import { equal, equaln } from '../Geometry/GeUtils';
import { Stand } from '../Geometry/RegionParse';
import { Count } from '../Geometry/Count';
//旋转矢量
export function rotateLine(l: Vector3, ang: number)
{
new Matrix2().setRotate(ang).applyVector(l);
return l;
}
//3点获取圆心
export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3)
@ -65,10 +57,16 @@ export function getCirAngleByChordAndTangent(chord: Vector3, tangentLine: Vector
return cirAng *= dir.z;
}
//行列式
export function getDeterminant(v1: Vector2, v2: Vector2): number
export function getDeterminantFor2V(v1: Vector2, v2: Vector2): number
{
return v1.x * v2.y - v1.y * v2.x;
}
export function getDeterminantFor3V(v1: Vector3, v2: Vector3, v3: Vector3)
{
let mat = new Matrix3();
mat.set(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z);
return mat.determinant();
}
// 2D 3D点转换
export function Vec2DTo3D(pt: Vector2)
{

@ -1,4 +1,5 @@
import { Matrix4, Vector3 } from 'three';
import { equaln, isParallelTo } from '../Geometry/GeUtils';
/**
*
@ -23,8 +24,9 @@ export function matrixSetVector(mat: Matrix4, col: number, v: Vector3)
* YZXAxisYAxisZAxis
*
* @export
* @returns {Matrix4}
*/
export function matrixAlignCoordSys(matrixFrom: Matrix4, matrixTo: Matrix4)
export function matrixAlignCoordSys(matrixFrom: Matrix4, matrixTo: Matrix4): Matrix4
{
let matrix = new Matrix4().getInverse(matrixFrom);
@ -32,3 +34,28 @@ export function matrixAlignCoordSys(matrixFrom: Matrix4, matrixTo: Matrix4)
return matrix;
}
/**
* 2
*
* @export
* @param {Matrix4} matrixFrom
* @param {Matrix4} matrixTo
* @returns {boolean} 2
*/
export function matrixIsCoplane(matrixFrom: Matrix4, matrixTo: Matrix4): boolean
{
let nor1 = new Vector3().setFromMatrixColumn(matrixFrom, 2);
let nor2 = new Vector3().setFromMatrixColumn(matrixFrom, 2);
//法线共面
if (!isParallelTo(nor1, nor2))
return false;
//高共面
let pt = new Vector3().setFromMatrixPosition(matrixTo);
//变换到自身对象坐标系.
pt.applyMatrix4(new Matrix4().getInverse(matrixFrom));
return equaln(pt.z, 0);
}

@ -3,7 +3,7 @@ import { Box3, Matrix4, Object3D, ShapeGeometry, Vector2, Vector3 } from 'three'
import { ColorMaterial } from '../Common/ColorPalette';
import { Vec2DTo3D, getCircleCenter } from '../Common/CurveUtils';
import { matrixSetVector } from '../Common/Matrix4Utils';
import { angle, angleTo2Pi, equal, equaln, midPoint, polar } from '../Geometry/GeUtils';
import { angle, angleTo2Pi, equal, equaln, midPoint, polar, MoveMatrix } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectArcAndArc, IntersectCircleAndArc, IntersectLineAndArc, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../GraphicsSystem/IntersectWith';
import { Factory } from './CADFactory';
@ -548,22 +548,18 @@ export class Arc extends Curve
this.UpdateGeometry(geo);
}
GetSnapPoints(): Array<THREE.Vector3>
{
return this.GetStretchPoints();
}
GetStretchPoints(): Array<Vector3>
{
return [
this.StartPoint,
this.GetPointAtParam(0.5),
this.EndPoint,
this.Center.clone(),
]
];
}
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
MoveSnapPoints(indexList: Array<number>, vec: Vector3)
{
let ptsArr = this.GetStretchPoints();
this.WriteAllObjectRecord();
let ptsArr = this.GetSnapPoints();
if (indexList.length > 0)
{
let index = indexList[0];
@ -583,6 +579,28 @@ export class Arc extends Curve
}
}
}
GetStretchPoints(): Array<Vector3>
{
return [this.StartPoint, this.EndPoint];
}
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
{
if (indexList.length === 0)
return;
this.WriteAllObjectRecord();
if (indexList.length === 2)
this.ApplyMatrix(MoveMatrix(vec));
else
for (let index of indexList)
{
if (index !== 0)
index = 2;
this.MoveSnapPoints([index], vec);
}
}
GetParamAtDist(d: number)
{
@ -597,7 +615,9 @@ export class Arc extends Curve
an = angle(pt.clone().applyMatrix4(this.OCSInv));
an += Math.PI * 0.5 * (this.m_Clockwise ? -1 : 1);
return polar(new Vector3(), an, this.m_Radius) as Vector3;
let ocs = new Matrix4().extractRotation(this.OCS);
return polar(new Vector3(), an, this.m_Radius).applyMatrix4(ocs);
}
GetClosestPointTo(pt: Vector3, extend: boolean): Vector3
{

@ -1,10 +1,10 @@
import * as THREE from 'three';
import { Box3, EllipseCurve, Geometry, Matrix4, Object3D, Vector3 } from 'three';
import { arrayFirst } from '../Common/ArrayExt';
import { arrayFirst, arraySortByNumber, arrayRemoveDuplicateBySort, arrayLast } from '../Common/ArrayExt';
import { ColorMaterial } from '../Common/ColorPalette';
import { clamp } from '../Common/Utils';
import { Arc } from '../DatabaseServices/Arc';
import { angle, equaln, polar } from '../Geometry/GeUtils';
import { angle, equaln, polar, MoveMatrix } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectCircleAndArc, IntersectCircleAndCircle, IntersectLineAndCircle, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../GraphicsSystem/IntersectWith';
import { Factory } from './CADFactory';
@ -113,12 +113,19 @@ export class Circle extends Curve
GetSplitCurves(param: number[] | number)
{
let params = this.SplitParamSort(param);
params.shift();
params.pop();
let params: number[];
if (param instanceof Array)
{
params = param.filter(p => this.ParamOnCurve(p));
params.sort((a1, a2) => a2 - a1);//从大到小
arrayRemoveDuplicateBySort(params);
if (params.length < 2) return [];
params.push(arrayFirst(params));
params.reverse();
}
else //圆不能被单个参数切割
return [];
//补上最后一个到第一个的弧
params.unshift(arrayLast(params));
let anglelist = params.map(param => Math.PI * 2 * param);
@ -129,7 +136,8 @@ export class Circle extends Curve
let ea = anglelist[i + 1];
if (!equaln(sa, ea))
{
let arc = new Arc(this.Center, this.m_Radius, sa, ea);
let arc = new Arc(new Vector3(), this.m_Radius, sa, ea);
arc.ApplyMatrix(this.OCS);
curvelist.push(arc);
}
}
@ -142,7 +150,7 @@ export class Circle extends Curve
{
return NaN;
}
return angle(pt.clone().sub(this.Center)) / (Math.PI * 2);
return angle(pt.clone().applyMatrix4(this.OCSInv)) / (Math.PI * 2);
}
PtOnCurve(pt: Vector3)
@ -220,10 +228,6 @@ export class Circle extends Curve
}
GetSnapPoints(): Array<THREE.Vector3>
{
return this.GetStretchPoints();
}
GetStretchPoints(): Array<Vector3>
{
let pts = [
new Vector3(),
@ -237,14 +241,10 @@ export class Circle extends Curve
pts.forEach(p => p.applyMatrix4(ocs));
return pts;
}
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
MoveSnapPoints(indexList: Array<number>, vec: Vector3)
{
let ocs = this.OCS;
ocs.setPosition(new Vector3());
let ocsInv = new Matrix4().getInverse(ocs);
vec = vec.clone().applyMatrix4(ocsInv);
let pts = this.GetStretchPoints();
let pts = this.GetSnapPoints();
if (indexList.length > 0)
{
let index = indexList[0];
@ -263,12 +263,25 @@ export class Circle extends Curve
}
}
}
GetStretchPoints(): Array<Vector3>
{
let pts = [new Vector3()];
let ocs = this.OCS;
pts.forEach(p => p.applyMatrix4(ocs));
return pts;
}
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
{
if (indexList.length > 0)
{
let mat = MoveMatrix(vec);
this.ApplyMatrix(mat);
}
}
GetFistDeriv(pt: number | Vector3)
{
if (typeof pt === "number")
{
pt = this.GetPointAtParam(pt);
}
else
pt = pt.clone();

@ -87,7 +87,7 @@ export abstract class Curve extends Entity
{
//切割参数列表
let params: number[];
if (param instanceof Array)
if (Array.isArray(param))
{
params = param.filter(param => this.ParamOnCurve(param));
params.push(0, this.EndParam);

@ -2,10 +2,10 @@ import { Geometry, Mesh, Object3D, Quaternion, ShapeGeometry, Vector3 } from 'th
import * as THREE from 'three';
import { ColorMaterial } from '../../Common/ColorPalette';
import { rotateLine } from '../../Common/CurveUtils';
import { Factory } from '../CADFactory';
import { Entity } from '../Entity';
import { Text } from '../Text/Text';
import { rotatePoint } from '../../Geometry/GeUtils';
/**
*
@ -124,14 +124,14 @@ export class Dimension extends Entity
}
reviseTextPosition(v: Vector3)
{
let reviseLine = rotateLine(new Vector3(1), this.TextRotation + Math.PI / 2).multiplyScalar(this.m_Text.Height / 2 + this.FONTTODIMDIST);
let reviseLine = rotatePoint(new Vector3(1), this.TextRotation + Math.PI / 2).multiplyScalar(this.m_Text.Height / 2 + this.FONTTODIMDIST);
v.add(reviseLine);
}
updateText(text: THREE.Mesh, pos: Vector3, ro: number)
{
this.reviseTextPosition(pos);
let moveVecX = rotateLine(new Vector3(1), this.TextRotation).negate().multiplyScalar(this.m_Text.Width / 2);
let moveVecY = rotateLine(new Vector3(0, -1), this.TextRotation).multiplyScalar(this.m_Text.Height / 2);
let moveVecX = rotatePoint(new Vector3(1), this.TextRotation).negate().multiplyScalar(this.m_Text.Width / 2);
let moveVecY = rotatePoint(new Vector3(0, -1), this.TextRotation).multiplyScalar(this.m_Text.Height / 2);
let p = pos.clone().add(moveVecX);
p.add(moveVecY);

@ -1,19 +1,17 @@
import * as THREE from 'three';
import { Geometry, Group, Object3D, Shape, Vector3, Matrix4 } from 'three';
import { Geometry, Group, Object3D, Shape, Vector3 } from 'three';
import { ColorMaterial } from '../../Common/ColorPalette';
import { rotateLine } from '../../Common/CurveUtils';
import { angleAndX, angleTo, getPtPostion, updateGeometry } from '../../Geometry/GeUtils';
import { angleAndX, angleTo, getPtPostion, updateGeometry, rotatePoint } from '../../Geometry/GeUtils';
import { RenderType } from '../../GraphicsSystem/Enum';
import { IntersectLAndL } from '../../GraphicsSystem/IntersectWith';
import { IntersectLAndLFor3D } from '../../GraphicsSystem/IntersectWith';
import { Arc } from '../Arc';
import { Factory } from '../CADFactory';
import { CADFile } from '../CADFile';
import { Entity } from '../Entity';
import { Line } from '../Line';
import { Dimension } from './Dim';
import { Curve } from '../Curve';
import { Text } from '../Text/Text';
import { Entity } from '../Entity';
import { CADFile } from '../CADFile';
import { Dimension } from './Dim';
@Factory
export class LineAngularDimension extends Dimension
@ -118,7 +116,7 @@ export class LineAngularDimension extends Dimension
private getCaclSPtAndEPt()
{
// 2线交点即为圆心
let center = IntersectLAndL(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);
// 获取实际的首尾点,离圆心近的的为起始点
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];
@ -128,7 +126,7 @@ export class LineAngularDimension extends Dimension
private getDimArcData()
{
// 2线交点即为圆心
let center = IntersectLAndL(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);
let rad = this.m_ArcPoint.distanceTo(center);
let { ept1, ept2 } = this.getCaclSPtAndEPt();
//标注线段的起始端点
@ -229,8 +227,8 @@ export class LineAngularDimension extends Dimension
let line1 = ept1.clone().sub(spt1);
let line2 = ept2.clone().sub(spt2);
rotateLine(line1, -Math.PI / 2);
rotateLine(line2, Math.PI / 2);
rotatePoint(line1, -Math.PI / 2);
rotatePoint(line2, Math.PI / 2);
let angle = angleTo(originLine, line1);
let angle1 = angleTo(originLine.negate(), line2);
if (Math.abs(angle) >= Math.PI / 2)

@ -6,7 +6,7 @@ import { RenderType } from '../GraphicsSystem/Enum';
import { Factory } from './CADFactory';
import { CADFile } from './CADFile';
import { Curve } from './Curve';
import { rotateLine } from '../Common/CurveUtils';
import { rotatePoint } from '../Geometry/GeUtils';
@Factory
export class Ellipse extends Curve
@ -65,7 +65,7 @@ export class Ellipse extends Curve
}
PtInCurve(pt: Vector3)
{
let p = rotateLine(pt.clone().sub(this.Center), -this.Angle);
let p = rotatePoint(pt.clone().sub(this.Center), -this.Angle);
let a = this.RadX;
let b = this.RadY;
return Math.pow(p.x, 2) / Math.pow(a, 2) + Math.pow(p.y, 2) / Math.pow(b, 2) < 1

@ -1,5 +1,6 @@
import * as THREE from 'three';
import { Box3, Geometry, Matrix4, Object3D, Vector3 } from 'three';
import { matrixIsCoplane } from '../Common/Matrix4Utils';
import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectOption } from '../GraphicsSystem/IntersectWith';
import { Factory } from './CADFactory';
@ -7,7 +8,6 @@ import { CADFile } from './CADFile';
import { CADObject } from './CADObject';
import { ObjectId } from './ObjectId';
/**
* Entity ,.
*
@ -41,7 +41,6 @@ export class Entity extends CADObject
{
return this.m_Color;
}
/**
*
*
@ -80,6 +79,18 @@ export class Entity extends CADObject
return new Matrix4().getInverse(this.m_Matrix);
}
/**
* .
*
* @param {Entity} e
* @returns {boolean}
* @memberof Entity
*/
IsCoplaneTo(e: Entity): boolean
{
return matrixIsCoplane(this.m_Matrix, e.OCS);
}
/**
* .
*
@ -150,7 +161,6 @@ export class Entity extends CADObject
*/
Update()
{
let ocs = this.OCS;
for (let [type, en] of this.m_DrawEntity)
{

@ -1,4 +1,3 @@
//直线对象
import * as THREE from 'three';
import { Box3, Geometry, Object3D, Vector3 } from 'three';
import { arraySortByNumber } from '../Common/ArrayExt';

@ -1,11 +1,11 @@
import * as THREE from 'three';
import { Box3, Geometry, Matrix4, Object3D, Vector2, Vector3 } from 'three';
import { CreateBoardUtil } from '../ApplicationServices/mesh/createBoard';
import { arrayLast } from '../Common/ArrayExt';
import { arrayLast, arrayRemove } from '../Common/ArrayExt';
import { ColorMaterial } from '../Common/ColorPalette';
import { Vec2DTo3D, Vec3DTo2D, getDeterminant, rotateLine } from '../Common/CurveUtils';
import { Vec2DTo3D, Vec3DTo2D, getDeterminantFor2V } from '../Common/CurveUtils';
import { FixIndex } from '../Common/Utils';
import { equal, equaln, updateGeometry } from '../Geometry/GeUtils';
import { equal, equaln, updateGeometry, rotatePoint } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectOption, IntersectPolylineAndCurve } from '../GraphicsSystem/IntersectWith';
import { angleTo } from './../Geometry/GeUtils';
@ -75,6 +75,78 @@ export class Polyline extends Curve
{
return this.m_LineData;
}
get NumberOfVertices(): number
{
return this.m_LineData.length;
}
/**
* .
* :
* pl.AddVertexAt(pl.NumberOfVerticesk,p);//在末尾插入一个点
*
* @param {number} index
* @param {Vector2} pt
* @returns {this}
* @memberof Polyline
*/
AddVertexAt(index: number, pt: Vector2): this
{
this.WriteAllObjectRecord();
this.m_LineData.splice(index, 0, { pt: pt.clone(), bul: 0 });
this.Update();
return this;
}
RemoveVertexAt(index: number): this
{
if (index < this.m_LineData.length)
{
this.m_LineData.splice(index, 1);
this.Update();
}
return this;
}
GetPoint2dAt(index: number): Vector2 | undefined
{
if (index >= 0 && this.m_LineData.length > index)
return this.m_LineData[index].pt.clone();
}
/**
*
*
* @param {number} index
* @param {Vector2} pt
* @memberof Polyline
*/
SetPointAt(index: number, pt: Vector2): this
{
let d = this.m_LineData[index];
if (d)
{
this.WriteAllObjectRecord();
d.pt.copy(pt);
this.Update();
}
return this;
}
SetBulgeAt(index: number, bul: number): this
{
let d = this.m_LineData[index];
if (d)
{
this.WriteAllObjectRecord();
d.bul = bul;
this.Update();
}
return this;
}
GetBuilgeAt(index: number): number
{
return this.m_LineData[index].bul;
}
//多段线起点
get StartPoint()
{
@ -120,7 +192,7 @@ export class Polyline extends Curve
let startV = this.m_LineData[i];
let endV = this.m_LineData[i + 1];
area += getDeterminant(startV.pt, endV.pt) / 2;
area += getDeterminantFor2V(startV.pt, endV.pt) / 2;
if (startV.bul != 0)
{
@ -132,7 +204,7 @@ export class Polyline extends Curve
{
let startV = arrayLast(this.m_LineData);
let endV = this.m_LineData[0];
area += getDeterminant(startV.pt, endV.pt) / 2
area += getDeterminantFor2V(startV.pt, endV.pt) / 2
}
return area;
}
@ -670,7 +742,7 @@ export class Polyline extends Curve
if (equaln(startV.pt.distanceTo(endV.pt), 0)) return;
let tarLine = this.GetFistDeriv(param).normalize();
//偏移向量
let moveVec = rotateLine(tarLine, Math.PI / 2).multiplyScalar(-dist);
let moveVec = rotatePoint(tarLine, Math.PI / 2).multiplyScalar(-dist);
//偏移矩阵
let mat = new Matrix4().makeTranslation(moveVec.x, moveVec.y, moveVec.z);
let originLine = Vec2DTo3D(endV.pt.clone().sub(startV.pt));
@ -678,7 +750,7 @@ export class Polyline extends Curve
startV.pt = Vec3DTo2D(Vec2DTo3D(startV.pt).applyMatrix4(mat));
if (startV.bul !== 0)
{
moveVec = rotateLine(moveVec, Math.atan(startV.bul) * 4);
moveVec = rotatePoint(moveVec, Math.atan(startV.bul) * 4);
}
mat.makeTranslation(moveVec.x, moveVec.y, moveVec.z);
endV.pt = Vec3DTo2D(Vec2DTo3D(endV.pt).applyMatrix4(mat));
@ -1352,7 +1424,7 @@ export class Polyline extends Curve
return { pts, buls };
}
CreateCurve()
private CreateCurve()
{
let { pts, buls } = this.PtsBuls;
let curve = CreateBoardUtil.createPath(pts, buls);
@ -1391,7 +1463,7 @@ export class Polyline extends Curve
{
this.WriteAllObjectRecord();
let vLoc = Vec3DTo2D(moveVec.clone().applyMatrix4(this.OCSInv));
let moveVLoc = Vec3DTo2D(moveVec.clone().applyMatrix4(new Matrix4().extractRotation(this.OCSInv)));
for (let index of indexList)
{
@ -1404,18 +1476,14 @@ export class Polyline extends Curve
let d = this.m_LineData[ptIndex];
if (d.bul == 0)
{
this.m_LineData[ptIndex].pt.add(vLoc);
this.m_LineData[nextIndex].pt.add(vLoc);
this.m_LineData[ptIndex].pt.add(moveVLoc);
this.m_LineData[nextIndex].pt.add(moveVLoc);
}
else
{
// 以下代码保证了中心点不变
let arcStartPoint = this.GetPointAtParam(ptIndex);
let arcMidP = this.GetPointAtParam(ptIndex + 0.5).add(moveVec);
let arcEndPoint = this.GetPointAtParam(nextIndex);
let arc = new Arc().FromThreePoint(arcStartPoint, arcMidP, arcEndPoint);
this.m_LineData[ptIndex].bul = Math.tan(arc.AllAngle * 0.25) * (equal(arc.StartPoint, arcStartPoint) && arc.IsClockWise ? -1 : 1);
let arc = this.GetCurveAtIndex(ptIndex) as Arc;
arc.MoveSnapPoints([1], moveVec);
this.m_LineData[ptIndex].bul = Math.tan(arc.AllAngle * 0.25) * (arc.IsClockWise ? -1 : 1);
}
}
}
@ -1444,7 +1512,9 @@ export class Polyline extends Curve
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
{
this.WriteAllObjectRecord();
let moveVc = new Vector2(vec.x, vec.y);
//本地坐标系移动向量
let moveVLoc = vec.clone().applyMatrix4(new Matrix4().extractRotation(this.OCSInv));
let ptCout = this.m_LineData.length;
@ -1495,7 +1565,7 @@ export class Polyline extends Curve
ChangeBul(nextIndex, index);
//修改顶点
this.m_LineData[index].pt.add(Vec3DTo2D(vec));
this.m_LineData[index].pt.add(Vec3DTo2D(moveVLoc));
}
this.Update();
}

@ -59,29 +59,13 @@ export class Region extends Entity
}
BooleanOper(otherRegion: Region, boolType: BoolOpeartionType)
{
this.WriteAllObjectRecord();
//法线共面
if (!isParallelTo(this.Normal, otherRegion.Normal))
{
console.log("对象不共面1");
return;
}
//高共面
let pt = otherRegion.Position;
//变换到自身对象坐标系.
pt.applyMatrix4(this.OCSInv);
if (!equaln(pt.z, 0))
if (this.IsCoplaneTo(otherRegion))
{
console.log("对象不共面2");
return;
}
this.WriteAllObjectRecord();
this.m_ShapeManager.BoolOper(otherRegion.m_ShapeManager, boolType);
this.Update();
}
}
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
{
let regionGroup = new Group();

@ -32,7 +32,6 @@ export class Text extends Entity
protected FONTSIZE = 0.2;
//字体粗细
protected PROVISITION = -0.1;
Normal: Vector3 = new Vector3(0, 0, 1);
m_fontWidth: number;
textArea: HTMLTextAreaElement;
constructor(pos?: Vector3, str?: string, h?: number, ro?: number)

@ -12,7 +12,7 @@ import { DrawLinearDimension } from '../Add-on/DrawDim/DrawLinearDimension';
import { DrawEllipse } from '../Add-on/DrawEllipse';
import { DrawFloor } from '../Add-on/DrawFloor';
import { DrawGripStretch } from '../Add-on/DrawGripStretch';
import { DrawCircle, DrawLine, DrawRect, DrawSphere, DrawTest, ZoomE } from '../Add-on/DrawLine';
import { DrawCircle, DrawLine, DrawSphere, DrawTest, ZoomE } from '../Add-on/DrawLine';
import { DrawPolyline } from '../Add-on/DrawPolyline';
import { DrawRegion } from '../Add-on/DrawRegion';
import { DrawSky } from '../Add-on/DrawSky';
@ -52,12 +52,14 @@ import { Fbx } from '../Add-on/loadfbx';
import { Command_PLTest } from '../Add-on/polytest';
import { Command_PtInCu } from '../Add-on/ptincu';
import { Command_Ssget } from '../Add-on/ssget';
// import { DrawFloor } from '../Add-on/DrawFloor';
// import { RevTarget, SaveTarget } from '../Add-on/RenderTarget';
import { TestIntersect } from '../Add-on/test/testIntersect';
import { TestBoolOperationUtil } from '../Add-on/testEntity/TestBoolOperation';
import { Command_DimTest } from '../DatabaseServices/Dimension/dimTest';
import { commandMachine } from './CommandMachine';
import { TestBoolOperationUtil } from '../Add-on/testEntity/TestBoolOperation';
import { DrawRect } from '../Add-on/DrawRec';
// import { DrawFloor } from '../Add-on/DrawFloor';
// import { RevTarget, SaveTarget } from '../Add-on/RenderTarget';
export function registerCommand()
{
commandMachine.RegisterCommand("l", new DrawLine())
@ -170,6 +172,8 @@ export function registerCommand()
commandMachine.RegisterCommand("testbool", new TestBoolOperationUtil());
commandMachine.RegisterCommand("join", new Command_Join());
commandMachine.RegisterCommand("testInt", new TestIntersect());
// commandMachine.RegisterCommand("st", new SaveTarget())
// commandMachine.RegisterCommand("rt", new RevTarget())

@ -40,7 +40,6 @@ export class Editor
m_KeywordsServices: GetKeyWordsServices;
//用户坐标系
private m_UCSMatrix = new THREE.Matrix4();
constructor(app: ApplicationService)
{
this.m_App = app;

@ -11,7 +11,6 @@ import { Editor, EditorService } from './Editor';
import { MouseControls } from './MouseControls';
import { commandMachine } from './CommandMachine';
export class SnapDragServices implements EditorService
{

@ -1,14 +1,14 @@
import * as THREE from 'three';
import { app } from '../ApplicationServices/Application';
import { ColorMaterial } from '../Common/ColorPalette';
import { GetPointPrompt } from '../Common/InputState';
import { Entity } from '../DatabaseServices/Entity';
import { equaln, fixAngle, polar } from '../Geometry/GeUtils';
import { IntersectLAndL } from '../GraphicsSystem/IntersectWith';
import { IntersectLAndLFor3D } from '../GraphicsSystem/IntersectWith';
import { PreViewer } from '../GraphicsSystem/PreViewer';
//捕捉轴
interface SnapAxis
{
@ -104,7 +104,7 @@ export class SnapServices
for (let j = i + 1; j < snapAxisList.length; j++)
{
let axis2 = snapAxisList[j];
let insP = IntersectLAndL(axis1.BasePoint, axis1.SnapPoint, axis2.BasePoint, axis2.SnapPoint);
let insP = IntersectLAndLFor3D(axis1.BasePoint, axis1.SnapPoint, axis2.BasePoint, axis2.SnapPoint);
if (insP)
axisIntersectList.push({
IntersectPoint: insP,

@ -1,6 +1,6 @@
import * as THREE from 'three';
import { Geometry, Vector, Vector2, Vector3 } from 'three';
import { rotateLine } from '../Common/CurveUtils';
import { Matrix2 } from './Matrix2';
export const cZeroVec = new THREE.Vector3();
@ -8,6 +8,20 @@ export const cXAxis = new THREE.Vector3(1, 0, 0);
export const cYAxis = new THREE.Vector3(0, 1, 0);
export const cZAxis = new THREE.Vector3(0, 0, 1);
/**
* ,
*
* @export
* @param {Vector3} pt
* @param {number} ang .
* @returns {Vector3} pt.
*/
export function rotatePoint(pt: Vector3, ang: number): Vector3
{
new Matrix2().setRotate(ang).applyVector(pt);
return pt;
}
export function equaln(v1: number, v2: number, fuzz = 1e-3)
{
return Math.abs(v1 - v2) < fuzz;
@ -150,7 +164,7 @@ export function midPtCir(v1: THREE.Vector3, v2: THREE.Vector3)
let baseline = new Vector3(1, 0, 0);
let outLine = v2.clone().sub(v1);
let ang = angleTo(baseline, outLine) / 2;
let midLine = rotateLine(outLine, -ang);
let midLine = rotatePoint(outLine, -ang);
return v1.clone().add(midLine);
}

@ -1,6 +1,5 @@
import { Vector3 } from 'three';
import { Vec2DTo3D, Vec3DTo2D } from '../Common/CurveUtils';
import { getDeterminantFor3V } from '../Common/CurveUtils';
import { Arc } from '../DatabaseServices/Arc';
import { Circle } from '../DatabaseServices/Circle';
import { Curve } from '../DatabaseServices/Curve';
@ -8,6 +7,7 @@ import { Line } from '../DatabaseServices/Line';
import { Polyline } from '../DatabaseServices/Polyline';
import { equal, equaln, midPoint } from '../Geometry/GeUtils';
/**
* .
*
@ -60,28 +60,23 @@ function CheckPointOnCurve(intPts: Vector3[], c1: Curve, c2: Curve, extType: Int
})
}
/**
* ,,.
*
* @export
* @param {(Circle | Arc)} c1
* @param {(Circle | Arc)} c2
* @returns
*/
export function IntersectCircleAndCircle(c1: Circle | Arc, c2: Circle | Arc)
export function IntersectCircleAndCircle(cu1: Circle | Arc, cu2: Circle | Arc)
{
let center1 = c1.Center;
let center2 = c2.Center;
let radius1 = c1.Radius;
let radius2 = c2.Radius;
if (!cu1.IsCoplaneTo(cu2)) return [];
let c1OcsInv = cu1.OCSInv;
let c1Ocs = cu1.OCS;
let center1 = cu1.Center.applyMatrix4(c1OcsInv);
let center2 = cu2.Center.applyMatrix4(c1OcsInv);
let radius1 = cu1.Radius;
let radius2 = cu2.Radius;
let pts: Vector3[] = [];
let dist = center2.distanceTo(center1);
if (dist > (radius1 + radius2 + 1e-3))
{
return pts;
}
let dstsqr = dist * dist;
let r1sqr = radius1 * radius1;
@ -99,21 +94,20 @@ export function IntersectCircleAndCircle(c1: Circle | Arc, c2: Circle | Arc)
let phix = center1.x + (ratio_a * dx);
let phiy = center1.y + (ratio_a * dy);
dx = dx * ratio_h;
dy = dy * ratio_h;
dx *= ratio_h;
dy *= ratio_h;
let pt = new Vector3(phix + dy, phiy - dx);
let p1 = new Vector3(phix + dy, phiy - dx);
let p2 = new Vector3(phix - dy, phiy + dx);
p1.applyMatrix4(c1Ocs);
p2.applyMatrix4(c1Ocs);
pts.push(pt);
if (!equal(pt, p2))//防止点重复
{
pts.push(p1);
if (!equal(p1, p2))//防止点重复
pts.push(p2);
}
return pts;
}
/**
* .
*
@ -154,9 +148,9 @@ export function IntersectArcAndArc(arc1: Arc, arc2: Arc, extType: IntersectOptio
*/
function IntersectLineAndCircleOrArc(line: Line, circle: Circle | Arc)
{
let startPoint = Vec3DTo2D(line.StartPoint);
let endPoint = Vec3DTo2D(line.EndPoint);
let center = Vec3DTo2D(circle.Center);
let startPoint = line.StartPoint;
let endPoint = line.EndPoint;
let center = circle.Center;
let radius = circle.Radius;
let a = endPoint.distanceToSquared(startPoint);
@ -171,16 +165,16 @@ function IntersectLineAndCircleOrArc(line: Line, circle: Circle | Arc)
if (equaln(det, 0, 1e-5))
{
let delta = -b / (2 * a);
return [Vec2DTo3D(startPoint.add(lineV.multiplyScalar(delta)))];
return [startPoint.add(lineV.multiplyScalar(delta))];
}
else if (det > 0)
{
let sqrt_det = Math.sqrt(det);
let delta = (-b + sqrt_det) / (2 * a);
let p2 = Vec2DTo3D(startPoint.clone().add(lineV.clone().multiplyScalar(delta)));
let p2 = startPoint.clone().add(lineV.clone().multiplyScalar(delta));
delta = (-b - sqrt_det) / (2 * a);
let p3 = Vec2DTo3D(startPoint.clone().add(lineV.multiplyScalar(delta)));
let p3 = startPoint.clone().add(lineV.multiplyScalar(delta));
return [p2, p3];
}
@ -200,7 +194,7 @@ export function IntersectLineAndArc(line: Line, arc: Arc, extType: IntersectOpti
return CheckPointOnCurve(ptArr, line, arc, extType);
}
//直线和直线
export function IntersectLAndL(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3): Vector3
export function IntersectLAndLFor2D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3): Vector3
{
let dx1 = p1.x - p2.x;
let dx2 = p3.x - p4.x;
@ -227,11 +221,55 @@ export function IntersectLAndL(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector
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 pt: Vector3;
let v1 = p2.clone().sub(p1).normalize();
let v2 = p4.clone().sub(p3).normalize();
let w = p3.clone().sub(p1);
if (Math.abs(v1.dot(v2)) === 1)
{
let tmpLine = new Line(p1, p2);
let par = tmpLine.GetParamAtPoint(p3);
if (par)
{
pt = midPoint(midPoint(p1, p2), midPoint(p3, p4));
}
}
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);
}
pt = new Vector3(x12 * t + p2.x, y12 * t + p2.y, z12 * t + p2.z);
}
return pt;
}
//直线和直线
export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOption)
{
let pt = IntersectLAndL(l1.StartPoint, l1.EndPoint, l2.StartPoint, l2.EndPoint);
let pt = IntersectLAndLFor3D(l1.StartPoint, l1.EndPoint, l2.StartPoint, l2.EndPoint);
return pt ? CheckPointOnCurve([pt], l1, l2, extType) : [];
}

Loading…
Cancel
Save