diff --git a/web/app/math/math.js b/web/app/math/math.js index bd1b3e0f..23917a58 100644 --- a/web/app/math/math.js +++ b/web/app/math/math.js @@ -259,6 +259,31 @@ export function radiusOfCurvature(d1, d2) { return r1lsq * r1l / vec.length(vec.cross(d1, d2)); } +export function pointToLineSignedDistance(ax, ay, bx, by, px, py) { + let nx = - (by - ay); + let ny = bx - ax; + + const d = distance(ax, ay, bx, by); + + nx /= d; + ny /= d; + + let vx = px - ax; + let vy = py - ay; + + const proj = vx * ny + vy * (-nx); + + //Check if vector b lays on the vector ab + if (proj > d) { + return Number.NaN; + } + + if (proj < 0) { + return Number.NaN; + } + return vx * nx + vy * ny; +} + export const DEG_RAD = Math.PI / 180.0; export const sq = (a) => a * a; diff --git a/web/app/sketcher/io.js b/web/app/sketcher/io.js index acfa381a..fde26fe9 100644 --- a/web/app/sketcher/io.js +++ b/web/app/sketcher/io.js @@ -152,13 +152,13 @@ IO.prototype._loadSketch = function(sketch) { skobj = new BezierCurve(a, b, cp1, cp2); } else if (_class === T.HDIM) { skobj = new HDimension(obj.a, obj.b); - skobj.flip = obj.flip; + obj.offset !== undefined && (skobj.offset = obj.offset); } else if (_class === T.VDIM) { skobj = new VDimension(obj.a, obj.b); - skobj.flip = obj.flip; + obj.offset !== undefined && (skobj.offset = obj.offset); } else if (_class === T.DIM) { skobj = new Dimension(obj.a, obj.b); - skobj.flip = obj.flip; + obj.offset !== undefined && (skobj.offset = obj.offset); } else if (_class === T.DDIM) { skobj = new DiameterDimension(obj.obj); } @@ -388,7 +388,7 @@ IO.prototype._serializeSketch = function(metadata) { } else if (obj._class === T.DIM || obj._class === T.HDIM || obj._class === T.VDIM) { to.a = obj.a.id; to.b = obj.b.id; - to.flip = obj.flip; + to.offset = obj.offset; } else if (obj._class === T.DDIM) { to.obj = obj.obj.id; } diff --git a/web/app/sketcher/shapes/dim.js b/web/app/sketcher/shapes/dim.js index c089faee..35cd8ad1 100644 --- a/web/app/sketcher/shapes/dim.js +++ b/web/app/sketcher/shapes/dim.js @@ -5,6 +5,8 @@ import {Styles} from "../styles"; import {_90} from "../../math/math"; import {_270} from "../../math/math"; import {makeAngle0_360} from "../../math/math"; +import {pointToLineSignedDistance} from "../../math/math"; +import {_negate} from "../../math/vec"; class LinearDimension extends SketchObject { @@ -12,10 +14,11 @@ class LinearDimension extends SketchObject { super(); this.a = a; this.b = b; - this.flip = false; - this.offset = 15; + this.fontSize = 12; + this.offset = 20; this.pickA = []; this.pickB = []; + this.textRect = []; } visitParams(callback) { @@ -132,7 +135,7 @@ class LinearDimension extends SketchObject { ctx.stroke(); } - ctx.font = (12) + "px Arial"; + ctx.font = (this.fontSize) + "px Arial"; const txt = d.toFixed(2); const textMetrics = ctx.measureText(txt); @@ -175,11 +178,29 @@ class LinearDimension extends SketchObject { } ctx.save(); - ctx.translate(tx, ty); + + const modelTextHeight = viewer.screenToModelDistance(this.fontSize); + + let dtx = [modelTextWidth * _vyn, -_vxn * modelTextWidth]; + let dty = [modelTextHeight * _vxn, _vyn * modelTextHeight]; + if (flip) { - ctx.translate(_vyn * modelTextWidth - _vxn * 2 *textOff, -_vxn * modelTextWidth - _vyn * 2*textOff); + const dx = _vyn * modelTextWidth - _vxn * 2 *textOff; + const dy = -_vxn * modelTextWidth - _vyn * 2*textOff; + tx += dx; + ty += dy; + _negate(dtx); + _negate(dty); } + this.saveTextRect(tx, ty, + tx + dtx[0], ty + dtx[1], + tx + dtx[0] + dty[0], ty + dtx[1] + dty[1], + tx + dty[0], ty + dty[1], + ); + + ctx.translate(tx, ty); + ctx.rotate(rot); ctx.scale(unscale, -unscale); ctx.fillText(txt, 0, 0); @@ -190,36 +211,46 @@ class LinearDimension extends SketchObject { } } - + + saveTextRect(ax, ay, bx, by, cx, cy, dx, dy) { + this.textRect[0] = ax; + this.textRect[1] = ay; + this.textRect[2] = bx; + this.textRect[3] = by; + this.textRect[4] = cx; + this.textRect[5] = cy; + this.textRect[6] = dx; + this.textRect[7] = dy; + } + normalDistance(aim, scale) { + + const [ax, ay, bx, by, cx, cy, dx, dy] = this.textRect; + + let d1 = pointToLineSignedDistance(ax, ay, bx, by, aim.x, aim.y); + if (d1 >= 0) { + const d2 = pointToLineSignedDistance(bx, by, cx, cy, aim.x, aim.y); + if (d2 >= 0) { + const d3 = pointToLineSignedDistance(cx, cy, dx, dy, aim.x, aim.y); + if (d3 >= 0) { + const d4 = pointToLineSignedDistance(dx, dy, ax, ay, aim.x, aim.y); + if (d4 >= 0) { + return 0; + } + } + } + } + const [_ax, _ay] = this.pickA; const [_bx, _by] = this.pickB; - let _vx = - (_by - _ay); - let _vy = _bx - _ax; - - const d = math.distance(_ax, _ay, _bx, _by); - - //normalize - let _vxn = _vx / d; - let _vyn = _vy / d; - - let avx = aim.x - _ax; - let avy = aim.y - _ay; - - const proj = avx * _vyn + avy * (-_vxn); - - //Check if vector b lays on the vector ab - if (proj > d) { + const sdist = pointToLineSignedDistance(_ax, _ay, _bx, _by, aim.x, aim.y); + if (sdist !== sdist) { return -1; } + return Math.abs(sdist); - if (proj < 0) { - return -1; - } - - return Math.abs(avx * _vxn + avy * _vyn); } } diff --git a/web/app/sketcher/tools/dim.js b/web/app/sketcher/tools/dim.js index a58fc4f6..ccc6f73f 100644 --- a/web/app/sketcher/tools/dim.js +++ b/web/app/sketcher/tools/dim.js @@ -2,6 +2,7 @@ import {HDimension, VDimension, Dimension, DiameterDimension} from '../shapes/di import Vector from 'math/vector'; import {EndPoint} from '../shapes/point' import {Tool} from './tool' +import {DragTool} from "./drag"; export class AddDimTool extends Tool { @@ -25,12 +26,6 @@ export class AddDimTool extends Tool { mouseup(e) { - if (e.button > 0 && this.dim != null) { - this.dim.flip = !this.dim.flip; - this.viewer.refresh(); - return; - } - if (this.viewer.snapped == null) { return; } @@ -41,11 +36,13 @@ export class AddDimTool extends Tool { if (this.dim == null) { this.viewer.historyManager.checkpoint(); this.dim = this.dimCreation(p, new EndPoint(p.x, p.y)); + this.dim.offset = 0; this.layer.add(this.dim); this.viewer.refresh(); } else { this.dim.b = p; - this.viewer.toolManager.releaseControl(); + this.viewer.toolManager.switchTool(new DragTool(this.dim, this.viewer)); + this.viewer.toolManager.tool.mousedown(e); this.viewer.refresh(); } } diff --git a/web/app/sketcher/tools/drag.js b/web/app/sketcher/tools/drag.js index bd1f200b..434ececd 100644 --- a/web/app/sketcher/tools/drag.js +++ b/web/app/sketcher/tools/drag.js @@ -19,11 +19,6 @@ export class DragTool extends Tool { this.viewer.screenToModel2(e.offsetX, e.offsetY, this._point); let dx = this._point.x - x; let dy = this._point.y - y; - // for (let i = 0; i < this.lockedShifts.length; i += 2) { - // this.lockedValues[i] = this._point.x - this.lockedShifts[i]; - // this.lockedValues[i + 1] = this._point.y - this.lockedShifts[i + 1]; - // } - this.obj.translate(dx, dy); // this.viewer.parametricManager.setConstantsFromGeometry(this.obj); if (!Tool.dumbMode(e) || this.obj.constraints.length !== 0) { @@ -47,15 +42,16 @@ export class DragTool extends Tool { } mouseup(e) { - this.viewer.parametricManager.solve(false); + if (this.obj.constraints.length !== 0) { + this.viewer.parametricManager.solve(false); + this.viewer.parametricManager.algNumSystem.controlBounds = false; + } this.viewer.refresh(); - this.viewer.parametricManager.algNumSystem.controlBounds = false; this.viewer.toolManager.releaseControl(); let traveled = math.distance(this.origin.x, this.origin.y, e.offsetX, e.offsetY); if (traveled >= 10) { this.viewer.historyManager.lightCheckpoint(10); } - //this.animateSolution(); } mousewheel(e) {