还原交点,优化轮廓切割

pull/68/head
Zoe 6 years ago
parent b6221e128b
commit 730268591e

@ -123,66 +123,49 @@ Array [
`; `;
exports[`三维空间直线相交测试 1`] = ` exports[`三维空间直线相交测试 1`] = `
Array [ Vector3 {
Vector3 { "x": 5,
"x": 5, "y": 5,
"y": 5, "z": 5,
"z": 5, }
},
]
`; `;
exports[`三维空间直线相交测试 2`] = ` exports[`三维空间直线相交测试 2`] = `
Array [ Vector3 {
Vector3 { "x": 4.5,
"x": 3, "y": 4.5,
"y": 3, "z": 4.5,
"z": 3, }
},
Vector3 {
"x": 6,
"y": 6,
"z": 6,
},
]
`; `;
exports[`三维空间直线相交测试 3`] = ` exports[`三维空间直线相交测试 3`] = `
Array [ Vector3 {
Vector3 { "x": 5,
"x": 5, "y": 5,
"y": 5, "z": 5,
"z": 5, }
},
]
`; `;
exports[`相交测试 1`] = ` exports[`相交测试 1`] = `
Array [ Vector3 {
Vector3 { "x": 0.5,
"x": 0.5, "y": 0,
"y": 0, "z": 0,
"z": 0, }
},
]
`; `;
exports[`相交测试 2`] = ` exports[`相交测试 2`] = `
Array [ Vector3 {
Vector3 { "x": 2,
"x": 2, "y": 0,
"y": 0, "z": 0,
"z": 0, }
},
]
`; `;
exports[`相交测试 3`] = ` exports[`相交测试 3`] = `
Array [ Vector3 {
Vector3 { "x": 0.5,
"x": 0.5, "y": 5,
"y": 5, "z": 0,
"z": 0, }
},
]
`; `;

@ -56,14 +56,14 @@ test('三维空间直线相交测试', () =>
new Vector3(2, 2, 2), new Vector3(2, 2, 2),
new Vector3(2, 2, 10) new Vector3(2, 2, 10)
) )
expect(res.length).toBe(0); expect(res).toBeUndefined();
res = IntersectLAndLFor3D( res = IntersectLAndLFor3D(
new Vector3(1, 0, 1), new Vector3(1, 0, 1),
new Vector3(1, 0, 4), new Vector3(1, 0, 4),
new Vector3(0.5, 0, 3), new Vector3(0.5, 0, 3),
new Vector3(0.5, 0, 10) new Vector3(0.5, 0, 10)
) )
expect(res.length).toBe(0); expect(res).toBeUndefined();
}) })
test('三维空间圆圆相交测试', () => test('三维空间圆圆相交测试', () =>
{ {

@ -21,7 +21,7 @@ export class TestIntersect implements Command
let exRefSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true }); let exRefSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true });
if (exRefSsRes.Status !== PromptStatus.OK) return; if (exRefSsRes.Status !== PromptStatus.OK) return;
let cus = exRefSsRes.SelectSet.SelectEntityList as Curve[]; let cus = exRefSsRes.SelectSet.SelectEntityList as Curve[];
let pt = IntersectLAndLFor3D(cus[0].StartPoint, cus[0].EndPoint, cus[1].StartPoint, cus[1].EndPoint)[0]; let pt = IntersectLAndLFor3D(cus[0].StartPoint, cus[0].EndPoint, cus[1].StartPoint, cus[1].EndPoint);
console.log('pt: ', pt); console.log('pt: ', pt);
if (pt) if (pt)
{ {

@ -116,7 +116,7 @@ export class LineAngularDimension extends Dimension
private getCaclSPtAndEPt() private getCaclSPtAndEPt()
{ {
// 2线交点即为圆心 // 2线交点即为圆心
let center = IntersectLAndLFor3D(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2)[0]; 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 [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]; let [spt2, ept2] = this.StartPoint2.distanceTo(center) < this.EndPoint2.distanceTo(center) ? [this.StartPoint2, this.EndPoint2] : [this.EndPoint2, this.StartPoint2];
@ -126,7 +126,7 @@ export class LineAngularDimension extends Dimension
private getDimArcData() private getDimArcData()
{ {
// 2线交点即为圆心 // 2线交点即为圆心
let center = IntersectLAndLFor3D(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2)[0]; let center = IntersectLAndLFor3D(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2);
let rad = this.m_ArcPoint.distanceTo(center); let rad = this.m_ArcPoint.distanceTo(center);
let { ept1, ept2 } = this.getCaclSPtAndEPt(); let { ept1, ept2 } = this.getCaclSPtAndEPt();
//标注线段的起始端点 //标注线段的起始端点

@ -104,7 +104,7 @@ export class SnapServices
for (let j = i + 1; j < snapAxisList.length; j++) for (let j = i + 1; j < snapAxisList.length; j++)
{ {
let axis2 = snapAxisList[j]; let axis2 = snapAxisList[j];
let insP = IntersectLAndLFor3D(axis1.BasePoint, axis1.SnapPoint, axis2.BasePoint, axis2.SnapPoint)[0]; let insP = IntersectLAndLFor3D(axis1.BasePoint, axis1.SnapPoint, axis2.BasePoint, axis2.SnapPoint);
if (insP) if (insP)
axisIntersectList.push({ axisIntersectList.push({
IntersectPoint: insP, IntersectPoint: insP,

@ -43,6 +43,19 @@ function getIntPtContextPts(sourceCur: Curve, cu: Curve, pts: Vector3[])
}) })
} }
}
function getIntPtContextPts2(cu: Curve, interPts: Vector3[], pts: Vector3[])
{
if (interPts.length > 0)
{
let pars = interPts.map(pt => cu.GetParamAtPoint(pt));
pars.forEach(par =>
{
par >= 0.02 && pts.push(cu.GetPointAtParam(par - 0.01));
par <= (cu.EndParam - 0.02) && pts.push(cu.GetPointAtParam(par + 0.01));
})
}
} }
//判断点点是否全部都在封闭区域内或者在曲线上 //判断点点是否全部都在封闭区域内或者在曲线上
function IsPtsAllInOrOnReg(sourceReg: Polyline | Circle | Ellipse, pts: Vector3[]) function IsPtsAllInOrOnReg(sourceReg: Polyline | Circle | Ellipse, pts: Vector3[])
@ -55,7 +68,7 @@ function IsPtsAllInOrOnReg(sourceReg: Polyline | Circle | Ellipse, pts: Vector3[
} }
//TODO:把线 on in out三种状态分开写 //TODO:把线 on in out三种状态分开写
//判断曲线是否在源封闭曲线外或者上 //判断曲线是否在源封闭曲线外或者上
export function isTargetCurOutOrOnSourceCur(sourceCur: Polyline | Circle | Ellipse, targetCur: Curve) export function isTargetCurOutOrOnSourceCur(sourceCur: Polyline | Circle, targetCur: Curve)
{ {
let pts = []; let pts = [];
getIntPtContextPts(sourceCur, targetCur, pts); getIntPtContextPts(sourceCur, targetCur, pts);
@ -65,6 +78,16 @@ export function isTargetCurOutOrOnSourceCur(sourceCur: Polyline | Circle | Ellip
} }
return IsPtsAllOutOrOnReg(sourceCur, pts); return IsPtsAllOutOrOnReg(sourceCur, pts);
} }
export function isTargetCurOutOrOnSourceCur2(sourceCur: Polyline | Circle, targetCur: Curve, interPts: Vector3[])
{
let pts = [];
getIntPtContextPts2(targetCur, interPts, pts);
if (pts.length <= 1)
{
pts.push(targetCur.StartPoint, targetCur.EndPoint);
}
return IsPtsAllOutOrOnReg(sourceCur, pts);
}
//判断点点是否全部都在封闭区域外或者在曲线上 //判断点点是否全部都在封闭区域外或者在曲线上
function IsPtsAllOutOrOnReg(sourceReg: Polyline | Circle | Ellipse, pts: Vector3[]) function IsPtsAllOutOrOnReg(sourceReg: Polyline | Circle | Ellipse, pts: Vector3[])
{ {

@ -0,0 +1,113 @@
import { Polyline } from "../DatabaseServices/Polyline";
// // Cyrus-Beck 2-D Line Clipping algorithm
// // for ease of coding we will treat a 2D point and a 2D vector
// // as the same
// struct Point2D
// {
// float x, y;
// }
// // for simplicity we set an upper bound on the number of
// // points allowed to define a polygon - by moving to a class
// // with a constructor we could make the array any size we wanted
// const int MAXP = 100;
// struct Polygon
// {
// int nPoints;
// Point2D v[MAXP];
// }
// const int MAXN = 100;
// typedef Point2D Normal[MAXN];
// // compute the outer normals.
// // note that this requires that the polygon be convex
// // to always work
function caclNomals(pl: Polyline)
{
}
// void CalcNormals(Polygon p, Normal & n)
// {
// int i, j, k;
// point2D v;
// for (i = 0; i < p.nPoints; i++)
// {
// j = (i + 1) % p.nPoints;
// k = (i + 2) % p.nPoints;
// // make vector be -1/mI + 1J
// n[i].x = -(p.v[j].y - p.v[i].y) / (p.v[j].x - p.v[i].x);
// n[i].y = 1.0;
// v.x = p.v[k].x - p.v[i].x;
// v.y = p.v[k].y - p.v[i].y;
// if (DotProduct(n[i], v) > 0) // inner normal
// {
// n[i].x *= -1;
// n[i].y = -1;
// }
// }
// }
// float DotProduct(Point2D v1, Point2D v2)
// {
// return v1.x * v2.x + v1.y * v2 * y;
// }
// void CBClip(Point2D p1, Point2D p2, Normal n, Polygon p, Boolean & visible,
// Point2D & rp, Point2D & q)
// {
// float t1, t2, t, num, den;
// Point2D dirV, F; // vectors
// int I;
// // start largest at smallest legal value and smallest
// // at largest legal value
// t1 = 0.0;
// t2 = 1.0;
// // compute the direction vector
// dirV.x = p2.x - p1.x;
// dirV.y = p2.y - p1.y;
// visible = TRUE;
// i = 0;
// while ((i < p.nPoints) && visible)
// {
// F.x = p1.x - p.v[i].x;
// F.y = p1.y - p.v[i].y;
// num = DotProduct(n[i], F);
// den = DotProduct(n[i], dirV);
// if (den == 0.0) // Parallel or Point
// { // parallel - if outside then forget the line; if inside then there are no
// // intersections with this side
// // but there may be with other edges, so in this case just keep going
// if (num > 0.0)
// visible = FALSE; // Parallel and outside or point (p1 == p2) and outside
// }
// else
// {
// t = -(num / den);
// if (den < 0.0) // entering
// {
// if (t <= 1.0)
// if (t > t1)
// t1 = t;
// }
// else if (t >= 0.0) //exiting
// if (t < t2)
// t2 = t;
// }
// i++;
// }
// if (t1 <= t2)
// {
// rp.x = p1.x + t1 * dirV.x;
// rp.y = p1.y + t1 * dirV.y;
// q.x = p1.x + t2.dirV.x
// q.y = p1.y + t2 * dirV.y
// }
// else
// visible = FALSE;
// }

@ -224,7 +224,7 @@ export function IntersectLAndLFor2D(p1: Vector3, p2: Vector3, p3: Vector3, p4: V
return pt; return pt;
} }
export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3) export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3)
{ {
let x12 = p1.x - p2.x; let x12 = p1.x - p2.x;
let x43 = p4.x - p3.x; let x43 = p4.x - p3.x;
@ -272,7 +272,7 @@ export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4:
} }
return pt; return pt;
} }
export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3) export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3)
{ {
let x12 = p1.x - p2.x; let x12 = p1.x - p2.x;
let x43 = p4.x - p3.x; let x43 = p4.x - p3.x;
@ -330,7 +330,7 @@ export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOptio
{ {
let pt = IntersectLAndLFor3D(l1.StartPoint, l1.EndPoint, l2.StartPoint, l2.EndPoint); let pt = IntersectLAndLFor3D(l1.StartPoint, l1.EndPoint, l2.StartPoint, l2.EndPoint);
return CheckPointOnCurve(pt, l1, l2, extType); return pt ? CheckPointOnCurve([pt], l1, l2, extType) : [];
} }
export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: IntersectOption): Vector3[] export function IntersectPolylineAndCurve(pl: Polyline, cu: Curve, extType: IntersectOption): Vector3[]

@ -8,8 +8,8 @@ import { Contour } from "../DatabaseServices/Contour";
import { Curve } from "../DatabaseServices/Curve"; import { Curve } from "../DatabaseServices/Curve";
import { Line } from "../DatabaseServices/Line"; import { Line } from "../DatabaseServices/Line";
import { Polyline } from '../DatabaseServices/Polyline'; import { Polyline } from '../DatabaseServices/Polyline';
import { equal, equaln } from "../Geometry/GeUtils"; import { equal, equaln, greater } from "../Geometry/GeUtils";
import { isTargetCurInOrOnSourceCur, isTargetCurOutOrOnSourceCur, TargetCurPosForSourceCur } from "./BoolOperateUtils"; import { isTargetCurInOrOnSourceCur, isTargetCurOutOrOnSourceCur, TargetCurPosForSourceCur, isTargetCurOutOrOnSourceCur2 } from "./BoolOperateUtils";
import { IntersectOption } from "./IntersectWith"; import { IntersectOption } from "./IntersectWith";
import { LinkSelf } from "./LinkSelft"; import { LinkSelf } from "./LinkSelft";
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
@ -719,8 +719,8 @@ export class PolyOffestUtil1
// c.Outline.ColorIndex = 2; // c.Outline.ColorIndex = 2;
// app.m_Database.ModelSpace.Append(c.Outline); // app.m_Database.ModelSpace.Append(c.Outline);
// }) // })
console.time("trim")
cus = this.trimByContours(cus, contours).filter(c => cus = this.trimByContours2(cus, contours).filter(c =>
{ {
if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0) return false; if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0) return false;
let dist1 = this.m_Polyline.GetClosestPointTo(c.StartPoint, false).distanceToSquared(c.StartPoint); let dist1 = this.m_Polyline.GetClosestPointTo(c.StartPoint, false).distanceToSquared(c.StartPoint);
@ -728,6 +728,8 @@ export class PolyOffestUtil1
let rad2 = Math.pow(this.m_OffestDist, 2); let rad2 = Math.pow(this.m_OffestDist, 2);
return (dist1 - rad2 >= -1e-3 || dist2 - rad2 >= -1e-3); return (dist1 - rad2 >= -1e-3 || dist2 - rad2 >= -1e-3);
}); });
console.timeEnd("trim")
return this.linkCurves(cus); return this.linkCurves(cus);
} }
//偏移曲线 //偏移曲线
@ -1028,29 +1030,6 @@ export class PolyOffestUtil1
let outline = c.Outline; let outline = c.Outline;
for (let l of needCutCus) for (let l of needCutCus)
{ {
// let posSrcForTar = TargetCurPosForSourceCur(outline, l as Arc | Line);
// if (posSrcForTar.onSrc || posSrcForTar.outSrc)
// {
// tmpCus.push(l);
// }
// else if (posSrcForTar.throughSrc)
// {
// let par = posSrcForTar.pts.map(p => l.GetParamAtPoint(p));
// let cus = l.GetSplitCurves(par);
// if (cus.length === 0)
// {
// tmpCus.push(l);
// }
// else
// {
// tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && isTargetCurOutOrOnSourceCur(outline, cu)));
// }
// }
// else
// {
// l instanceof Arc && tmpCus.push(l);
// }
// 在上面或者在外面 // 在上面或者在外面
if (isTargetCurOutOrOnSourceCur(outline, l)) if (isTargetCurOutOrOnSourceCur(outline, l))
{ {
@ -1072,9 +1051,48 @@ export class PolyOffestUtil1
} }
} }
} }
}
needCutCus = tmpCus;
})
return needCutCus;
}
private trimByContours2(needCutCus: Curve[], cons: Contour[]): Curve[]
{
cons.sort((c1, c2) => c1.BoundingBox.min.x - c2.BoundingBox.min.x);
needCutCus.sort((c1, c2) => c1.BoundingBox.min.x - c2.BoundingBox.min.x);
cons.forEach(c =>
{
let tmpCus: Curve[] = [];
let outline = c.Outline;
for (let l of needCutCus)
{
if (l.BoundingBox.min.x > c.BoundingBox.max.x || l.BoundingBox.max.x < c.BoundingBox.min.x)
{
tmpCus[tmpCus.length] = l;
continue;
}
let pts = l.IntersectWith(outline, IntersectOption.OnBothOperands);
// 在上面或者在外面
if (isTargetCurOutOrOnSourceCur2(outline, l, pts))
{
tmpCus[tmpCus.length] = l;
}
else else
{ {
// l instanceof Arc && tmpCus.push(l); if (pts.length > 0)
{
let par = pts.map(p => l.GetParamAtPoint(p));
let cus = l.GetSplitCurves(par);
if (cus.length > 0)
tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && !isTargetCurInOrOnSourceCur(outline, cu)));
else if (isTargetCurOutOrOnSourceCur2(outline, l, pts))
{
console.warn('不正常情况')
tmpCus.push(l);
}
}
} }
} }
needCutCus = tmpCus; needCutCus = tmpCus;

Loading…
Cancel
Save