From 0340fc7f0da91ad32c97a5c9f46ceccd8f601b6d Mon Sep 17 00:00:00 2001 From: Val Erastov Date: Thu, 19 Oct 2017 21:27:01 -0700 Subject: [PATCH] use squared tolerance for vector equality test --- web/app/3d/modeler-app.js | 6 ++--- web/app/brep/geom/impl/nurbs.js | 4 ++-- web/app/brep/geom/impl/plane.js | 13 +++++----- web/app/brep/geom/tolerance.js | 18 ++++++++++++-- web/app/brep/operations/boolean.js | 38 ++++++++++++------------------ web/app/math/math.js | 23 +++++++++++------- 6 files changed, 57 insertions(+), 45 deletions(-) diff --git a/web/app/3d/modeler-app.js b/web/app/3d/modeler-app.js index 201dd452..f38fc719 100644 --- a/web/app/3d/modeler-app.js +++ b/web/app/3d/modeler-app.js @@ -235,10 +235,10 @@ App.prototype.test5 = function() { App.prototype.scratchCode = function() { // const app = this; - // this.test5(); - this.cylTest(); + // this.test3(); + // this.cylTest(); -return +// return // let curve1 = new NurbsCurve(new verb.geom.NurbsCurve({"degree":6,"controlPoints":[[150,149.99999999999997,-249.99999999999994,1],[108.33333333333051,150.00000000000907,-250.00000000001975,1],[66.6666666666712,149.99999999998562,-249.99999999996987,1],[24.99999999999545,150.00000000001364,-250.00000000002711,1],[-16.66666666666362,149.99999999999145,-249.9999999999837,1],[-58.33333333333436,150.0000000000029,-250.00000000000531,1],[-99.99999999999997,150,-250,1]],"knots":[0,0,0,0,0,0,0,1,1,1,1,1,1,1]})); // let curve2 = new NurbsCurve(new verb.geom.NurbsCurve({"degree":9,"controlPoints":[[100,-250,-250,1],[99.9999999999927,-194.44444444444687,-250.00000000000028,1],[100.00000000002228,-138.8888888888811,-249.99999999999838,1],[99.99999999995923,-83.33333333334777,-250.00000000000287,1],[100.00000000005268,-27.77777777775936,-249.99999999999744,1],[99.9999999999493,27.777777777760704,-250.0000000000008,1],[100.00000000003591,83.33333333334477,-250.00000000000063,1],[99.99999999998269,138.88888888888374,-249.99999999999966,1],[100.00000000000443,194.44444444444562,-249.99999999999986,1],[100,250,-250,1]],"knots":[0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1]})); diff --git a/web/app/brep/geom/impl/nurbs.js b/web/app/brep/geom/impl/nurbs.js index 08efb23f..5c0c3a56 100644 --- a/web/app/brep/geom/impl/nurbs.js +++ b/web/app/brep/geom/impl/nurbs.js @@ -4,7 +4,7 @@ import {Point} from '../point' import {Surface} from "../surface"; import Vector from "../../../math/vector"; import * as ext from "./nurbs-ext"; -import {EPSILON, eqEps, TOLERANCE} from "../tolerance"; +import {EPSILON, eqEps, TOLERANCE, TOLERANCE_SQ, veq, veq3} from "../tolerance"; import curveIntersect from "./curve/curves-isec"; import curveTess from "./curve/curve-tess"; import {areEqual} from "../../../math/math"; @@ -189,7 +189,7 @@ export class NurbsCurve { //TODO: rename to BrepCurve intersectCurve(other) { let isecs = []; - const eq = (v1, v2) => math.areVectorsEqual3(v1, v2, TOLERANCE); + const eq = veq3; function add(i0) { for (let i1 of isecs) { diff --git a/web/app/brep/geom/impl/plane.js b/web/app/brep/geom/impl/plane.js index 78561958..ea27cc78 100644 --- a/web/app/brep/geom/impl/plane.js +++ b/web/app/brep/geom/impl/plane.js @@ -2,7 +2,7 @@ import {Surface} from '../surface' import {Point} from '../point' import {Line} from './line' import {Matrix3, AXIS, BasisForPlane} from '../../../math/l3space' -import * as math from '../../../math/math' +import {eqTol, veq} from "../tolerance"; export class Plane extends Surface { @@ -53,14 +53,13 @@ export class Plane extends Surface { return this.__3dTr; } - coplanarUnsignedForSameClass(other, tol) { - return math.areVectorsEqual(this.normal.multiply(this.w), other.normal.multiply(other.w), tol); - //TODO: store this.normal.multiply(this.w) in a field since it's constant value + coplanarUnsignedForSameClass(other) { + return veq(this.normal.multiply(this.w), other.normal.multiply(other.w)); } - equalsForSameClass(other, tol) { - return math.areVectorsEqual(this.normal, other.normal, tol) && - math.areEqual(this.w, other.w, tol); + equalsForSameClass(other) { + return veq(this.normal, other.normal) && + eqTol(this.w, other.w); } toParametricForm() { diff --git a/web/app/brep/geom/tolerance.js b/web/app/brep/geom/tolerance.js index d69638e8..67fe7163 100644 --- a/web/app/brep/geom/tolerance.js +++ b/web/app/brep/geom/tolerance.js @@ -1,4 +1,4 @@ -import {areEqual} from "../../math/math"; +import {areEqual, areVectorsEqual, areVectorsEqual3} from "../../math/math"; export const TOLERANCE = 1e-5; export const TOLERANCE_SQ = TOLERANCE * TOLERANCE; @@ -17,4 +17,18 @@ export function eqTol(a, b) { export function eqEps(a, b) { return areEqual(a, b, EPSILON); -} \ No newline at end of file +} + +export function veq(a, b) { + return areVectorsEqual(a, b, TOLERANCE_SQ); +} + +export function veq3(a, b) { + return areVectorsEqual3(a, b, TOLERANCE_SQ); +} + + +export function ueq(a, b) { + return areEqual(a, b, TOLERANCE_01); +} + diff --git a/web/app/brep/operations/boolean.js b/web/app/brep/operations/boolean.js index ad2c1b7e..581829bc 100644 --- a/web/app/brep/operations/boolean.js +++ b/web/app/brep/operations/boolean.js @@ -1,13 +1,11 @@ import {BREPValidator} from '../brep-validator'; import {Edge} from '../topo/edge'; import {Loop} from '../topo/loop'; -import {Face} from '../topo/face'; import {Shell} from '../topo/shell'; import {Vertex} from '../topo/vertex'; import {evolveFace} from './evolve-face' -import Vector from '../../math/vector'; import * as math from '../../math/math'; -import {TOLERANCE} from '../geom/tolerance'; +import {eqTol, TOLERANCE, ueq, veq} from '../geom/tolerance'; @@ -293,11 +291,11 @@ function intersectEdges(shell1, shell2) { points.sort((p1, p2) => p1.u - p2.u); let first = points[0]; let last = points[points.length - 1]; - if (eq(first.u, 0) && !first.vertexHolder[0]) { + if (ueq(first.u, 0) && !first.vertexHolder[0]) { first.vertexHolder[0] = e.halfEdge1.vertexA; first.skip = true; } - if (eq(last.u, 1) && !last.vertexHolder[0]) { + if (ueq(last.u, 1) && !last.vertexHolder[0]) { last.vertexHolder[0] = e.halfEdge1.vertexB; last.skip = true; } @@ -354,7 +352,7 @@ function intersectFaces(shell1, shell2, operationType) { for (let i = 0; i < shell1.faces.length; i++) { const face1 = shell1.faces[i]; if (DEBUG.FACE_FACE_INTERSECTION) { - __DEBUG__.Clear(); + __DEBUG__.Clear(); __DEBUG__.AddFace(face1, 0x00ff00); DEBUG.NOOP(); } @@ -421,7 +419,7 @@ function filterNodes(nodes) { if (i === j) continue; const node2 = nodes[j]; if (node2 !== null) { - if (eq(node2.u, node1.u)) { + if (ueq(node2.u, node1.u)) { if (node1.normal + node2.normal === 0) { nodes[i] = null } @@ -452,9 +450,9 @@ function intersectCurveWithEdge(curve, edge, result) { const {u0, u1} = point; let vertex; - if (eq(u0, 0)) { + if (ueq(u0, 0)) { vertex = edge.edge.halfEdge1.vertexA; - } else if (eq(u0, 1)) { + } else if (ueq(u0, 1)) { vertex = edge.edge.halfEdge1.vertexB; } else { vertex = vertexFactory.create(point.p0); @@ -476,10 +474,10 @@ function split(nodes, curve, result) { continue } let edgeCurve = curve; - if (!eq(inNode.u, 0)) { + if (!ueq(inNode.u, 0)) { [,edgeCurve] = edgeCurve.split(inNode.vertex.point); } - if (!eq(outNode.u, 1)) { + if (!ueq(outNode.u, 1)) { [edgeCurve] = edgeCurve.split(outNode.vertex.point); } const edge = new Edge(edgeCurve, inNode.vertex, outNode.vertex); @@ -528,9 +526,9 @@ function nodeNormal(point, edge, curve) { if (eq(dot, 0)) { dot = 0; } else { - if (dot < 0) + if (dot < 0) dot = -1; - else + else dot = 1; } return dot; @@ -590,7 +588,7 @@ class VertexFactory { this.vertices = []; } - addVertices(vertices) { + addVertices(vertices) { for (let v of vertices) { this.vertices.push(v); } @@ -602,11 +600,11 @@ class VertexFactory { return vertex; } } - return null; + return null; } create(point) { - + let vertex = this.find(point); if (vertex === null) { vertex = new Vertex(point); @@ -670,13 +668,7 @@ function $DEBUG_OPERANDS(shell1, shell2) { } } -function eq(v1, v2) { - return math.areEqual(v1, v2, TOLERANCE); -} - -function veq(v1, v2) { - return math.areVectorsEqual(v1, v2, TOLERANCE); -} +const eq = eqTol; function assert(name, cond) { if (!cond) { diff --git a/web/app/math/math.js b/web/app/math/math.js index d89f711d..739a0d08 100644 --- a/web/app/math/math.js +++ b/web/app/math/math.js @@ -2,6 +2,7 @@ import Vector from './vector' import BBox from './bbox' export const TOLERANCE = 1E-6; +export const TOLERANCE_SQ = TOLERANCE * TOLERANCE; export function distanceAB(a, b) { return distance(a.x, a.y, b.x, b.y); @@ -18,10 +19,18 @@ export function distanceAB3(a, b) { } export function distance3(x1, y1, z1, x2, y2, z2) { + return Math.sqrt(distanceSquared3(x1, y1, z1, x2, y2, z2)); +} + +export function distanceSquaredAB3(a, b) { + return distanceSquared3(a.x, a.y, a.z, b.x, b.y, b.z); +} + +export function distanceSquared3(x1, y1, z1, x2, y2, z2) { var dx = x1 - x2; var dy = y1 - y2; var dz = z1 - z2; - return Math.sqrt(dx * dx + dy * dy + dz * dz); + return dx * dx + dy * dy + dz * dz; } export function circleFromPoints(p1, p2, p3) { @@ -52,18 +61,16 @@ export function areEqual(v1, v2, tolerance) { return Math.abs(v1 - v2) < tolerance; } -export function areVectorsEqual(v1, v2, tolerance) { - //TODO: use tolerance_SQ and length_SQ - return areEqual(distanceAB3(v1, v2), 0, tolerance); +export function areVectorsEqual(v1, v2, toleranceSQ) { + return areEqual(distanceSquaredAB3(v1, v2), 0, toleranceSQ); } -export function areVectorsEqual3(v1, v2, tolerance) { - //TODO: use tolerance_SQ and length_SQ - return areEqual(distance3(v1[0], v1[1], v1[2], v2[0], v2[1], v2[2]), 0, tolerance); +export function areVectorsEqual3(v1, v2, toleranceSQ) { + return areEqual(distanceSquared3(v1[0], v1[1], v1[2], v2[0], v2[1], v2[2]), 0, toleranceSQ); } export function vectorsEqual(v1, v2) { - return areVectorsEqual(v1, v2, TOLERANCE); + return areVectorsEqual(v1, v2, TOLERANCE_SQ); } export function equal(v1, v2) {