添加偏移测试

pull/68/head
Zoe 6 years ago
parent ed5b68c11c
commit 6535725d78

@ -90,7 +90,19 @@ test('三维空间直线和圆相交测试', () =>
testLineAndCirIntersect(data); testLineAndCirIntersect(data);
}) })
test('补充相交测试', () =>
{
let data = [["Line", 1, 1, 2308, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.3934337707580937, 0.039495588796686576, 0, 1], 1, [12.270990240675426, 8.520323796959827, 0], [12.270990240675426, 4.4951100391838885, 0]], ["Arc", 1, 1, 2313, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 13.662687223232803, 4.584664645783669, 0, 1], 2, 0.003163048700428762, 6.156784789283385, 3.3367334474492862, true]]
let cus = loadFile(data);
let [cu1, cu2] = cus[0] instanceof Line ? cus : cus.reverse();
let pts = cu1.IntersectWith(cu2, 0);
expect(pts.length).toBe(1);
data = [["Line", 1, 1, 2308, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.3934337707580937, 0.039495588796686576, 0, 1], 1, [12.270990240675426, 8.520323796959827, 0], [12.270990240675426, 4.4951100391838885, 0]], ["Circle", 1, 1, 2320, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 13.662687223232803, 4.584664645783669, 0, 1], 1, 0.0031630487004287015]];
cus = loadFile(data);
[cu1, cu2] = cus[0] instanceof Line ? cus : cus.reverse();
pts = cu1.IntersectWith(cu2, 0);
expect(pts.length).toBe(2);
})
function loadFile(data) function loadFile(data)
{ {
let file = new CADFile(); let file = new CADFile();

@ -1,8 +1,21 @@
import { Factory } from "../../src/DatabaseServices/CADFactory"; import { Factory } from "../../src/DatabaseServices/CADFactory";
import { CADFile } from "../../src/DatabaseServices/CADFile"; import { CADFile } from "../../src/DatabaseServices/CADFile";
import { Polyline } from "../../src/DatabaseServices/Polyline"; import { Polyline } from "../../src/DatabaseServices/Polyline";
import { Curve } from "../../src/DatabaseServices/Curve";
Factory(Polyline); Factory(Polyline);
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;
}
test('IKKGK圆与直线补圆弧', () => test('IKKGK圆与直线补圆弧', () =>
{ {
let f = new CADFile(); let f = new CADFile();
@ -37,3 +50,57 @@ test('IKKGK圆与直线补圆弧', () =>
cus = pl.GetOffsetCurves(-1.926388985025112); cus = pl.GetOffsetCurves(-1.926388985025112);
expect(cus.length).toBe(1); expect(cus.length).toBe(1);
}); });
test('多段线偏移测试1', () =>
{
let data = [["Polyline", 1, 1, 3, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [6.059716713881022, 3.983456090651555], 1.1217395195062214, [6.383002832861191, 4.064022662889515], 0, [4.929178470254959, 8.399433427762037], 1.2642365052895204, [5.750708215297452, 4.050991501416427], 0.7171789779484218, true]];
let cus = loadFile(data);
for (let i = 0; i < 10; i += 0.01)
{
expect(cus[0].GetOffsetCurves(i).length).toBe(1);
}
for (let i = -1.5; i < 0; i += 0.01)
{
expect(cus[0].GetOffsetCurves(i).length).toBe(1);
}
for (let i = 2; i < 10; i += 0.01)
{
expect(cus[0].GetOffsetCurves(-i).length).toBe(0);
}
})
test('多段线偏移测试2', () =>
{
let data = [["Polyline", 1, 1, 734, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [8.176442643449754, 4.003694129881114], 0.6482011490054378, [8.554554536583165, 4.090460859042256], 0, [7.7292787370841225, 8.733182129315965], 0, [7.8227800907745895, 4.037582052934876], 1.223388515290821, true]];
let cus = loadFile(data);
expect(cus[0].GetOffsetCurves(-0.1799).length).toBe(2);
for (let i = 0; i < 10; i += 1)
{
expect(cus[0].GetOffsetCurves(i).length).toBe(1);
}
for (let i = -0.17; i < 0; i += 0.01)
{
expect(cus[0].GetOffsetCurves(i).length).toBe(1);
}
for (let i = -0.18; i < -0.34; i -= 0.01)
{
expect(cus[0].GetOffsetCurves(i).length).toBe(1);
}
for (let i = 0.35; i < 3; i += 0.01)
{
expect(cus[0].GetOffsetCurves(-i).length).toBe(0);
}
})
test('多段线偏移测试3', () =>
{
let data = [["Polyline", 1, 1, 1172, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 5, [12.52535684411379, 4.512623511896158], 0.39558516940595195, [13.121416971132648, 4.487590129452889], 0, [12.414545456418505, 8.796498405316765], 0, [12.015990240675425, 8.743859037199755], 0, [12.015990240675425, 4.4951100391838885], 0.8508932598252141, true]];
let cus = loadFile(data);
for (let i = 0; i < 10; i += 1)
{
expect(cus[0].GetOffsetCurves(i).length).toBe(1);
}
})

@ -74,10 +74,6 @@ export class Command_TestOffset implements Command
let dir = GetPointAtCurveDir(cu, p) ? 1 : -1 let dir = GetPointAtCurveDir(cu, p) ? 1 : -1
lastpls = cu.GetOffsetCurves(p.distanceTo(cu.GetClosestPointTo(p, !cu.IsClose)) * dir); lastpls = cu.GetOffsetCurves(p.distanceTo(cu.GetClosestPointTo(p, !cu.IsClose)) * dir);
// let a = cu.GetOffsetCurves(p.distanceTo(cu.GetClosestPointTo(p, !cu.IsClose)) * -dir);
// a.forEach(c => c.ColorIndex = 2);
// lastpls.push(...a);
lastpls.forEach((offCur) => lastpls.forEach((offCur) =>
{ {
app.m_Database.ModelSpace.Append(offCur); app.m_Database.ModelSpace.Append(offCur);

@ -94,7 +94,7 @@ export class TestIntersect implements Command
let cus = exRefSsRes.SelectSet.SelectEntityList as Curve[]; let cus = exRefSsRes.SelectSet.SelectEntityList as Curve[];
if (cus.length === 2) if (cus.length === 2)
{ {
let pt = cus[0].IntersectWith(cus[1], IntersectOption.ExtendBoth); let pt = cus[0].IntersectWith(cus[1], 0);
console.log('pt: ', pt); console.log('pt: ', pt);
if (pt.length) if (pt.length)
{ {

@ -6,6 +6,9 @@ import { Curve } from "../../DatabaseServices/Curve";
import { Polyline } from "../../DatabaseServices/Polyline"; import { Polyline } from "../../DatabaseServices/Polyline";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { arraySortByNumber, arrayLast, arrayRemoveIf } from "../../Common/ArrayExt";
import { equaln } from "../../Geometry/GeUtils";
import { IsPtsAllOutOrOnReg } from "../../GraphicsSystem/BoolOperateUtils";
export class TestTargeOnCurve implements Command export class TestTargeOnCurve implements Command
{ {
@ -29,14 +32,19 @@ export class TestTargeOnCurve implements Command
{ {
let target = ssRes.SelectSet.SelectEntityList[0] as Curve; let target = ssRes.SelectSet.SelectEntityList[0] as Curve;
let con1 = Contour.CreateContour([source]); // let con1 = Contour.CreateContour([source]);
let con2 = Contour.CreateContour([target]); // let con2 = Contour.CreateContour([target]);
let res = con1.getOperatedCurves(con2); // let res = con1.getOperatedCurves(con2);
testCurve(res.unionList, 1); // testCurve(res.unionList, 1);
testCurve(res.intersectionList, 2); // testCurve(res.intersectionList, 2);
testCurve(res.subtractList, 3); // testCurve(res.subtractList, 3);
target.Erase(); this.testClip(source as Polyline, target).forEach((c, i) =>
source.Erase(); {
c.ColorIndex = i + 1;
app.m_Database.ModelSpace.Append(c);
})
// target.Erase();
// source.Erase();
} }
} catch (err) } catch (err)
@ -44,7 +52,45 @@ export class TestTargeOnCurve implements Command
console.log(err); console.log(err);
} }
} }
testClip(outline: Polyline, l: Curve)
{
let tmpCus = [];
//交点参数列表
let iParams = l.IntersectWith(outline, 0)
.map(p => l.GetParamAtPoint(p));
arraySortByNumber(iParams);
//需要计算的点列表
let needCaclPts: Vector3[] = [];
for (let i = 0; i < iParams.length - 1; i++)
{
needCaclPts.push(l.GetPointAtParam((iParams[i] + iParams[i + 1]) / 2));
}
//如果交点不是首尾点,就加入首尾点
if (!equaln(iParams[0], 0, 1e-6))
needCaclPts.unshift(l.StartPoint);
if (!equaln(arrayLast(iParams), 1, 1e-6))
needCaclPts.push(l.EndPoint);
//切割曲线,缓存切割后曲线包围盒
if (IsPtsAllOutOrOnReg(outline, needCaclPts))
{
tmpCus.push(l);
}
else
{
let cus = l.GetSplitCurves(iParams);
//移除0长度线和在轮廓内的线.
arrayRemoveIf(cus, cu => equaln(cu.Length, 0, 1e-6)
|| outline.PtInCurve(cu.GetPointAtParam(0.5))
);
tmpCus.push(...cus);
}
return tmpCus;
}
} }
export function testPts(pts: Vector3[], color = 2) export function testPts(pts: Vector3[], color = 2)
{ {
pts.forEach(p => pts.forEach(p =>

@ -165,7 +165,7 @@ function IntersectLineAndCircleOrArc(line: Line, circle: Circle | Arc)
let c = center.lengthSq() + startPoint.lengthSq() - 2 * center.dot(startPoint) - radius * radius; let c = center.lengthSq() + startPoint.lengthSq() - 2 * center.dot(startPoint) - radius * radius;
let det = b * b - 4 * a * c; let det = b * b - 4 * a * c;
if (equaln(det, 0)) if (equaln(det, 0, 1e-4))
{ {
let delta = -b / (2 * a); let delta = -b / (2 * a);
return [startPoint.add(lineV.multiplyScalar(delta))]; return [startPoint.add(lineV.multiplyScalar(delta))];

@ -12,6 +12,7 @@ import { equal, equaln } from "../Geometry/GeUtils";
import { EBox, SortEntityByBox } from "../Geometry/SortEntityByBox"; import { EBox, SortEntityByBox } from "../Geometry/SortEntityByBox";
import { IsPtsAllOutOrOnReg } from "./BoolOperateUtils"; import { IsPtsAllOutOrOnReg } from "./BoolOperateUtils";
import { IntersectOption } from "./IntersectWith"; import { IntersectOption } from "./IntersectWith";
import { testContours } from "../Add-on/testEntity/TestCurve";
interface offestRes interface offestRes
{ {
@ -52,14 +53,18 @@ export class PolyOffestUtil
// console.time("join") // console.time("join")
this.TrimAndBuildContour(offres); this.TrimAndBuildContour(offres);
// console.timeEnd("join") // console.timeEnd("join")
// testContours(this.m_Contours); testContours(this.m_Contours);
//裁剪 //裁剪
let { boxCurves, outputCus } = this.trimByContours(this.m_RetCurves); let { boxCurves, outputCus } = this.trimByContours(this.m_RetCurves);
// // 优化裁剪后的曲线
// 优化裁剪后的曲线 // this.m_RetCurves = this.optimizeCus(boxCurves, outputCus);
outputCus = this.optimizeCus(boxCurves, outputCus); // this.m_RetCurves.push(...this.unNeedCutCus);
outputCus.push(...this.unNeedCutCus);
return this.linkCurves(outputCus); // this.m_RetCurves = this.linkCurves(this.m_RetCurves);
// // 如果源线段闭合只保留闭合的部分
// if (this.m_Polyline.IsClose)
// return this.m_RetCurves.filter(c => c.IsClose);
return this.m_RetCurves;
} }
/** /**
@ -84,18 +89,22 @@ export class PolyOffestUtil
} }
private optimizeCus(boxCurves: Map<EBox, Box3>, outputCus: Curve[]) private optimizeCus(boxCurves: Map<EBox, Box3>, outputCus: Curve[])
{ {
//过滤掉无效的线段 if (!this.m_Polyline.IsClose)
outputCus = outputCus.filter(c =>
{ {
//与源线段自交 //过滤掉无效的线段
if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0) outputCus = outputCus.filter(c =>
return false; {
//删除在反方向的无效线段 //与源线段自交
return this.CheckPointDir(c.StartPoint); if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0)
// return this.CheckPointDist(c.StartPoint) && this.CheckPointDist(c.EndPoint) return false;
// return (this.CheckPointDist(c.StartPoint) && this.CheckPointDist(c.EndPoint)) //删除在反方向的无效线段
// && this.CheckPointDir(c.StartPoint); return this.CheckPointDir(c.StartPoint) || this.CheckPointDir(c.EndPoint);
}); // return this.CheckPointDist(c.StartPoint) && this.CheckPointDist(c.EndPoint)
// return (this.CheckPointDist(c.StartPoint) && this.CheckPointDist(c.EndPoint))
// && this.CheckPointDir(c.StartPoint);
});
}
//处理自交的线段 //处理自交的线段
let count = outputCus.length; let count = outputCus.length;
@ -358,7 +367,7 @@ export class PolyOffestUtil
{ {
this.appendNewCuAndContour(frontLine, nextPt, intPt, startIndex); this.appendNewCuAndContour(frontLine, nextPt, intPt, startIndex);
} }
else if (frontLine instanceof Arc && par1 < 0 && par2 < 1) else if (frontLine instanceof Arc && par1 < 0 && par2 < 0)
{ {
this.appendNewCuAndContour(frontLine, nextPt, intPt, startIndex); this.appendNewCuAndContour(frontLine, nextPt, intPt, startIndex);
} }

Loading…
Cancel
Save