diff --git a/web/app/cad/sketch/sketchBoundaries.js b/web/app/cad/sketch/sketchBoundaries.js index 1454b9cf..9766ce61 100644 --- a/web/app/cad/sketch/sketchBoundaries.js +++ b/web/app/cad/sketch/sketchBoundaries.js @@ -1,6 +1,8 @@ -import {circleFromPoints, distanceAB, TOLERANCE} from '../../math/math'; +import {areEqual, circleFromPoints, distanceAB, radiusOfCurvature, TOLERANCE} from '../../math/math'; +import * as vec from '../../math/vec'; import {iteratePath} from '../cad-utils'; import NurbsCurve from '../../brep/geom/curves/nurbsCurve'; +import {veqXYZ} from '../../brep/geom/tolerance'; export function getSketchBoundaries(sceneFace) { const boundary = {lines: [], arcs: [], circles: [], nurbses: []}; @@ -8,8 +10,41 @@ export function getSketchBoundaries(sceneFace) { let _w2sTrArr = null; let w2sTrArr = () => _w2sTrArr || (_w2sTrArr = w2sTr.toArray()); for (let he of sceneFace.brepFace.edges) { - if (he.edge.curve.impl.constructor.name === 'NurbsCurve' && he.edge.curve.impl.degree() !== 1) { - boundary.nurbses.push(he.edge.curve.impl.transform(w2sTrArr()).serialize()) + let curve = he.edge.curve.impl; + if (curve.constructor.name === 'NurbsCurve' && curve.degree() !== 1) { + let curve2d = curve.transform(w2sTrArr()); + let arcRadius = findArcRadius(curve2d); + if (arcRadius !== null){ + let [from, to] = curve2d.domain(); + let [A, DA] = curve2d.eval(from, 1); + let [B, DB] = curve2d.eval(to, 1); + + let mA = vec.normalize(DA); + + if (veqXYZ(A[0], A[1], 0, B[0], B[1], 0)) { + let c = vec.mul(mA, arcRadius); + boundary.circles.push({ + c: {x: c[0], y: c[1]}, + r: arcRadius + }); + continue; + } + + let centripetalB = vec.normalize(DB); + perpXY(centripetalB); + + let proj = vec.dot(mA, vec.sub(A, B)); + let u = proj / vec.dot(mA, centripetalB); + + let C = vec._add(vec._mul(centripetalB, u), B); + boundary.arcs.push({ + a: {x: A[0], y: A[1]}, + b: {x: B[0], y: B[1]}, + c: {x: C[0], y: C[1]} + }); + } else { + boundary.nurbses.push(curve.transform(w2sTrArr()).serialize()) + } } else { addSegment(w2sTr.apply(he.vertexA.point), w2sTr.apply(he.vertexB.point)); } @@ -168,3 +203,27 @@ export function getSketchBoundaries(sceneFace) { } return boundary; } + +function findArcRadius(curve) { + if (curve.degree() !== 2) { + return null; + } + let knots = curve.knots(); + let prevRadCur = null; + for (let knot of knots) { + let [P, D, DD] = curve.eval(knot, 2); + let radCur = radiusOfCurvature(D, DD); + if (prevRadCur !== null && !areEqual(radCur, prevRadCur, 0.1)) { + return null; + } + prevRadCur = radCur; + } + return prevRadCur; +} + +function perpXY(v) { + let [x, y] = v; + + v[0] = - y; + v[1] = x; +} \ No newline at end of file