优化:统一精度,避免布尔运算失败

pull/2171/head
ChenX 1 year ago
parent 9a0ef8b41d
commit e27633536c

@ -11,3 +11,5 @@ exports[`交点大于等于2_但是还是分离 1`] = `310430.5057844047`;
exports[`交点大于等于2_但是还是分离 2`] = `40090.549687200226`;
exports[`共线多余点 1`] = `618903.9999999995`;
exports[`精度问题,导致的曲线合并失败,导致的无法重新生成轮廓 1`] = `8207.998897234036`;

@ -1,5 +1,5 @@
import { LoadRegionsFromFileData } from "../Utils/LoadEntity.util";
import { BoolOpeartionType } from "../../src/GraphicsSystem/BoolOperateUtils";
import { LoadRegionsFromFileData } from "../Utils/LoadEntity.util";
test('交点大于等于2_但是还是分离', () =>
{
@ -19,7 +19,8 @@ test('交点大于等于2_但是还是分离', () =>
test(`#I118PO`, () =>
{
let d = [2, "Region", 5, 2, 109, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 1, 1, 1, "Polyline", 5, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 4, [0, 0], 0, [349.99999999999983, 0], 0, [349.99999999999983, 18], 0, [0, 18], 0, true, 0, "Region", 5, 2, 110, false, 1, 7, 0, [-0.6481962787933795, -0.7614732983883384, -3.969057490217688e-17, 0, 0.7614732983883384, -0.6481962787933795, 4.66267918753728e-17, 0, 6.123233995736766e-17, 0, -1, 0, -507.79108398045344, 1098.4374795109752, -4.082417520817821e-14, 1], 0, 0, 1, 1, 1, 1, "Polyline", 5, 2, 0, false, 0, 7, 0, [-0.6481962787933795, -0.7614732983883384, -3.969057490217688e-17, 0, -0.7614732983883384, 0.6481962787933795, -4.66267918753728e-17, 0, 6.123233995736766e-17, 0, -1, 0, -507.79108398045344, 1098.4374795109752, -4.082417520817821e-14, 1], 0, 0, 2, 4, [9.993381848422814, -884.0586414166524], 0.17863084838388266, [280.4138219783257, -1365.1880927528969], 0, [507.2825195560087, -1098.6724383169787], -0.09662306706998787, [400.5809327775901, -964.8005274526736], 0, true, 0];
let d =
[2, "Region", 5, 2, 109, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 1, 1, 1, "Polyline", 5, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 4, [0, 0], 0, [349.99999999999983, 0], 0, [349.99999999999983, 18], 0, [0, 18], 0, true, 0, "Region", 5, 2, 110, false, 1, 7, 0, [-0.6481962787933795, -0.7614732983883384, -3.969057490217688e-17, 0, 0.7614732983883384, -0.6481962787933795, 4.66267918753728e-17, 0, 6.123233995736766e-17, 0, -1, 0, -507.79108398045344, 1098.4374795109752, -4.082417520817821e-14, 1], 0, 0, 1, 1, 1, 1, "Polyline", 5, 2, 0, false, 0, 7, 0, [-0.6481962787933795, -0.7614732983883384, -3.969057490217688e-17, 0, -0.7614732983883384, 0.6481962787933795, -4.66267918753728e-17, 0, 6.123233995736766e-17, 0, -1, 0, -507.79108398045344, 1098.4374795109752, -4.082417520817821e-14, 1], 0, 0, 2, 4, [9.993381848422814, -884.0586414166524], 0.17863084838388266, [280.4138219783257, -1365.1880927528969], 0, [507.2825195560087, -1098.6724383169787], -0.09662306706998787, [400.5809327775901, -964.8005274526736], 0, true, 0];
let [reg1, reg2] = LoadRegionsFromFileData(d);
let reg = reg1.Clone();
@ -54,3 +55,12 @@ test('共线多余点', () =>
reg1.BooleanOper(reg2.Clone(), BoolOpeartionType.Subtract);
expect(reg1.Area).toMatchSnapshot();
});
test('精度问题,导致的曲线合并失败,导致的无法重新生成轮廓', () =>
{
let d =
{ "file": [2, "Region", 10, 2, 110, 0, 1, 7, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 1, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 2, 4, [100, 0], 0, [400, 0], 0, [400, 864], 0, [100, 864], 0, true, 0, "Region", 10, 2, 111, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 2, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -614.9118387909318, -117.20906801007538, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [1728.0001196034718, 0], 0, [1728.0001196034718, 9.5], 0, [0, 9.5], 0, true, 0], "basePt": { "x": -0.00023216125555336475, "y": -100, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let [reg1, reg2] = LoadRegionsFromFileData(d);
reg1.BooleanOper(reg2.Clone(), BoolOpeartionType.Intersection);
expect(reg1.Area).toMatchSnapshot();
});

@ -72,18 +72,21 @@ export class Command_Join implements Command
}
else
remCurves = curveCol;
const fuzz = 0.01;
//连接成多段线
let groups = curveLinkGroup(remCurves);
let groups = curveLinkGroup(remCurves, -Math.log10(fuzz));
for (let g of groups)
{
if (g.length === 1)
continue;
let pl = new Polyline();
pl.ColorIndex = g[0].ColorIndex;
pl.OCS = ComputerCurvesNormalOCS(g);
for (let cu of g)
{
pl.Join(cu);
if (pl.Join(cu, false, fuzz) === Status.True)
cu.Erase();
}

@ -3,10 +3,10 @@ import { app } from "../../ApplicationServices/Application";
import { Arc } from "../../DatabaseServices/Entity/Arc";
import { Circle } from "../../DatabaseServices/Entity/Circle";
import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Point } from "../../DatabaseServices/Entity/Point";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { IntersectCircleAndCircle, IntersectOption } from "../../GraphicsSystem/IntersectWith";
import { Point } from "../../DatabaseServices/Entity/Point";
export class TestIntersect implements Command
{

@ -1,20 +1,25 @@
import { CADFiler } from "../../DatabaseServices/CADFiler";
import { Ellipse } from "../../DatabaseServices/Entity/Ellipse";
import { Region } from "../../DatabaseServices/Entity/Region";
import { Command } from "../../Editor/CommandMachine";
import { BoolOpeartionType } from "../../GraphicsSystem/BoolOperateUtils";
import { HotCMD } from "../../Hot/HotCommand";
import { TestDraw } from "../test/TestUtil";
@HotCMD
export class Test implements Command
{
async exec()
{
let d = { "file": [2, "Ellipse", 10, 2, 103, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 983.9770911100416, 940.0742538149107, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1926.3535339862863, 877.8288804632223, 0, 1], 0, 0, 1, 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 6.343188564109003, 7.616407379765725, "Ellipse", 10, 2, 104, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 983.9770911100406, 940.0742538149093, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1926.3535339862863, 877.8288804632223, 0, 1], 0, 0, 1, 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 3.934994981148553, 6.34318856410901], "basePt": { "x": 655.8960059049625, "y": 620.7541549379562, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let d = { "file": [2, "Region", 10, 2, 110, 0, 1, 7, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 1, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 2, 4, [100, 0], 0, [400, 0], 0, [400, 864], 0, [100, 864], 0, true, 0, "Region", 10, 2, 111, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 2, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -614.9118387909318, -117.20906801007538, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [1728.0001196034718, 0], 0, [1728.0001196034718, 9.5], 0, [0, 9.5], 0, true, 0], "basePt": { "x": -0.00023216125555336475, "y": -100, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let f = new CADFiler(d.file);
f.Read();
let el1 = f.ReadObject() as Ellipse;
let el2 = f.ReadObject() as Ellipse;
let el1 = f.ReadObject() as Region;
let el2 = f.ReadObject() as Region;
el1.Join(el2);
TestDraw(el1.Clone());
TestDraw(el2.Clone());
el1.BooleanOper(el2, BoolOpeartionType.Intersection);
}
}

@ -86,7 +86,7 @@ export function getDeterminantFor3V(v1: Vector3, v2: Vector3, v3: Vector3)
* [c1,c2,c3...],
* ]
*/
export function curveLinkGroup(cus: Curve[]): Array<Array<Curve>>
export function curveLinkGroup(cus: Curve[], numdimensions = 4): Array<Array<Curve>>
{
//返回的曲线组
let groupCus = new Array<Array<Curve>>();
@ -100,8 +100,9 @@ export function curveLinkGroup(cus: Curve[]): Array<Array<Curve>>
return !isClose;
});
if (cus.length === 0) return groupCus;
const fuzz = 5 * Math.pow(0.1, numdimensions);
//曲线节点图
let cuMap = new CurveMap();
let cuMap = new CurveMap(numdimensions);
cus.forEach(c => cuMap.AddCurveToMap(c));
//曲线站点表
@ -126,14 +127,14 @@ export function curveLinkGroup(cus: Curve[]): Array<Array<Curve>>
if (isEndSeach)
{
//保证曲线总是从起点连接到终点
if (!equalv3(cu.StartPoint, stand.position))
if (!equalv3(cu.StartPoint, stand.position, fuzz))
cu.Reverse();
cus.push(cu);
}
else
{
//保证曲线总是从起点连接到终点
if (!equalv3(cu.EndPoint, stand.position))
if (!equalv3(cu.EndPoint, stand.position, fuzz))
cu.Reverse();
cus.unshift(cu);
}

@ -523,7 +523,7 @@ export class Contour
if (Array.isArray(cus[0]))
cuGroups = cus as Curve[][];
else
cuGroups = curveLinkGroup(cus as Curve[]);
cuGroups = curveLinkGroup(cus as Curve[], -Math.log10(COMBINE_FUZZ));
let contours: Contour[] = [];
@ -541,7 +541,7 @@ export class Contour
{
if (cus.length === 0) return undefined;
let groups = needLink ? curveLinkGroup(cus) : [cus];
let groups = needLink ? curveLinkGroup(cus, -Math.log10(tolerance)) : [cus];
for (let g of groups)
{
if (g.length === 1)

Loading…
Cancel
Save