还原交点,优化轮廓切割

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

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

@ -56,14 +56,14 @@ test('三维空间直线相交测试', () =>
new Vector3(2, 2, 2),
new Vector3(2, 2, 10)
)
expect(res.length).toBe(0);
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.length).toBe(0);
expect(res).toBeUndefined();
})
test('三维空间圆圆相交测试', () =>
{

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

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

@ -104,7 +104,7 @@ export class SnapServices
for (let j = i + 1; j < snapAxisList.length; j++)
{
let axis2 = snapAxisList[j];
let insP = IntersectLAndLFor3D(axis1.BasePoint, axis1.SnapPoint, axis2.BasePoint, axis2.SnapPoint)[0];
let insP = IntersectLAndLFor3D(axis1.BasePoint, axis1.SnapPoint, axis2.BasePoint, axis2.SnapPoint);
if (insP)
axisIntersectList.push({
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[])
@ -55,7 +68,7 @@ function IsPtsAllInOrOnReg(sourceReg: Polyline | Circle | Ellipse, pts: Vector3[
}
//TODO:把线 on in out三种状态分开写
//判断曲线是否在源封闭曲线外或者上
export function isTargetCurOutOrOnSourceCur(sourceCur: Polyline | Circle | Ellipse, targetCur: Curve)
export function isTargetCurOutOrOnSourceCur(sourceCur: Polyline | Circle, targetCur: Curve)
{
let pts = [];
getIntPtContextPts(sourceCur, targetCur, pts);
@ -65,6 +78,16 @@ export function isTargetCurOutOrOnSourceCur(sourceCur: Polyline | Circle | Ellip
}
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[])
{

@ -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;
}
export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3)
export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3)
{
let x12 = p1.x - p2.x;
let x43 = p4.x - p3.x;
@ -272,7 +272,7 @@ export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4:
}
return pt;
}
export function IntersectLAndLFor3D(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3)
export function IntersectLAndLFor3D1(p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3)
{
let x12 = p1.x - p2.x;
let x43 = p4.x - p3.x;
@ -330,7 +330,7 @@ export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOptio
{
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[]

@ -8,8 +8,8 @@ import { Contour } from "../DatabaseServices/Contour";
import { Curve } from "../DatabaseServices/Curve";
import { Line } from "../DatabaseServices/Line";
import { Polyline } from '../DatabaseServices/Polyline';
import { equal, equaln } from "../Geometry/GeUtils";
import { isTargetCurInOrOnSourceCur, isTargetCurOutOrOnSourceCur, TargetCurPosForSourceCur } from "./BoolOperateUtils";
import { equal, equaln, greater } from "../Geometry/GeUtils";
import { isTargetCurInOrOnSourceCur, isTargetCurOutOrOnSourceCur, TargetCurPosForSourceCur, isTargetCurOutOrOnSourceCur2 } from "./BoolOperateUtils";
import { IntersectOption } from "./IntersectWith";
import { LinkSelf } from "./LinkSelft";
import { app } from "../ApplicationServices/Application";
@ -719,8 +719,8 @@ export class PolyOffestUtil1
// c.Outline.ColorIndex = 2;
// app.m_Database.ModelSpace.Append(c.Outline);
// })
cus = this.trimByContours(cus, contours).filter(c =>
console.time("trim")
cus = this.trimByContours2(cus, contours).filter(c =>
{
if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0) return false;
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);
return (dist1 - rad2 >= -1e-3 || dist2 - rad2 >= -1e-3);
});
console.timeEnd("trim")
return this.linkCurves(cus);
}
//偏移曲线
@ -1028,29 +1030,6 @@ export class PolyOffestUtil1
let outline = c.Outline;
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))
{
@ -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
{
// 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;

Loading…
Cancel
Save