improving dimensions - make them draggable

This commit is contained in:
Val Erastov (xibyte) 2020-03-25 21:54:30 -07:00
parent 11c37cb8b9
commit 5dc7c3f52b
4 changed files with 144 additions and 158 deletions

View file

@ -39,6 +39,12 @@ export function distanceSquared3(x1, y1, z1, x2, y2, z2) {
return dx * dx + dy * dy + dz * dz;
}
export function distanceSquared(x1, y1, x2, y2) {
const dx = x1 - x2;
const dy = y1 - y2;
return dx * dx + dy * dy;
}
export function circleFromPoints(p1, p2, p3) {
var center = new Vector();
var offset = p2.x*p2.x + p2.y*p2.y;

View file

@ -1,7 +1,10 @@
import * as utils from '../../utils/utils'
import * as math from '../../math/math'
import Vector from 'math/vector';
import {SketchObject} from './sketch-object'
import {Styles} from "../styles";
import {_90} from "../../math/math";
import {_270} from "../../math/math";
import {makeAngle0_360} from "../../math/math";
class LinearDimension extends SketchObject {
@ -10,6 +13,9 @@ class LinearDimension extends SketchObject {
this.a = a;
this.b = b;
this.flip = false;
this.offset = 15;
this.pickA = [];
this.pickB = [];
}
visitParams(callback) {
@ -20,6 +26,20 @@ class LinearDimension extends SketchObject {
}
translateImpl(dx, dy) {
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;
this.offset += (dx * _vxn + dy * _vyn) * this.unscale;
}
getA() { return this.a }
@ -27,43 +47,45 @@ class LinearDimension extends SketchObject {
drawImpl(ctx, scale, viewer) {
const marked = this.markers.length !== 0;
if (marked) {
ctx.save();
viewer.setStyle(Styles.HIGHLIGHT, ctx);
}
const dimScale = viewer.dimScale;
const unscale = 1 /scale;
const off = unscale * 15;
const off = unscale * this.offset;
const textOff = unscale * 3; // getTextOff(dimScale);
var a, b, startA, startB;
if (this.flip) {
a = this.getB();
b = this.getA();
startA = this.b;
startB = this.a;
} else {
a = this.getA();
b = this.getB();
startA = this.a;
startB = this.b;
}
this.unscale = scale;
let a, b, startA, startB;
a = this.getB();
b = this.getA();
startA = this.b;
startB = this.a;
const d = math.distanceAB(a, b);
var _vx = - (b.y - a.y);
var _vy = b.x - a.x;
let _vx = - (b.y - a.y);
let _vy = b.x - a.x;
//normalize
var _vxn = _vx / d;
var _vyn = _vy / d;
let _vxn = _vx / d;
let _vyn = _vy / d;
_vx = _vxn * off;
_vy = _vyn * off;
ctx.beginPath();
var _ax = a.x + _vx;
var _ay = a.y + _vy;
var _bx = b.x + _vx;
var _by = b.y + _vy;
let _ax = a.x + _vx;
let _ay = a.y + _vy;
let _bx = b.x + _vx;
let _by = b.y + _vy;
ctx.moveTo(_ax, _ay);
ctx.lineTo(_bx, _by);
@ -98,10 +120,14 @@ class LinearDimension extends SketchObject {
ctx.fill();
}
function drawExtensionLine(x, y, nx, ny, width) {
function drawExtensionLine(x, y, nx, ny, width, tip) {
ctx.beginPath();
ctx.moveTo(x + ny * arrowW, y + -nx * arrowW);
ctx.lineTo(x + ny * (arrowW + width), y + -nx * (arrowW + width));
tip[0] = x + ny * (arrowW + width);
tip[1] = y + -nx * (arrowW + width);
ctx.lineTo(tip[0], tip[1]);
ctx.closePath();
ctx.stroke();
}
@ -119,12 +145,20 @@ class LinearDimension extends SketchObject {
const innerMode = modelTextWidth <= availableArea;
let rot = makeAngle0_360(Math.atan2(-_vxn, _vyn));
const flip = rot > _90 && rot < _270;
if (flip) {
rot += Math.PI;
}
let tx, ty;
if (innerMode) {
drawArrow(_ax, _ay, _vxn, _vyn);
drawArrow(_bx, _by, -_vxn, -_vyn);
this.pickA[0] = _ax; this.pickA[1] = _ay;
this.pickB[0] = _bx; this.pickB[1] = _by;
const h = d/2 - modelTextWidth/2;
tx = (_ax + _vxn * textOff) - (- _vyn) * h;
ty = (_ay + _vyn * textOff) - ( _vxn) * h;
@ -133,24 +167,59 @@ class LinearDimension extends SketchObject {
drawArrow(_bx, _by, _vxn, _vyn);
const outerArrowToTextPaddingPx = 6;
drawExtensionLine(_bx, _by, _vxn, _vyn, modelTextWidth + 2 * outerArrowToTextPaddingPx * unscale);
drawExtensionLine(_ax, _ay, -_vxn, -_vyn, outerArrowToTextPaddingPx * unscale);
drawExtensionLine(_ax, _ay, -_vxn, -_vyn, outerArrowToTextPaddingPx * unscale, this.pickA);
drawExtensionLine(_bx, _by, _vxn, _vyn, modelTextWidth + 2 * outerArrowToTextPaddingPx * unscale, this.pickB);
tx = (_bx + _vxn * textOff) - (- _vyn) * (arrowWpx + outerArrowToTextPaddingPx) * unscale;
ty = (_by + _vyn * textOff) - ( _vxn) * (arrowWpx + outerArrowToTextPaddingPx) * unscale;
}
ctx.save();
ctx.translate(tx, ty);
ctx.rotate( - Math.atan2(_vxn, _vyn));
if (flip) {
ctx.translate(_vyn * modelTextWidth - _vxn * 2 *textOff, -_vxn * modelTextWidth - _vyn * 2*textOff);
}
ctx.rotate(rot);
ctx.scale(unscale, -unscale);
ctx.fillText(txt, 0, 0);
ctx.restore();
if (marked) {
ctx.restore();
}
}
normalDistance(aim) {
return -1;
normalDistance(aim, scale) {
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) {
return -1;
}
if (proj < 0) {
return -1;
}
return Math.abs(avx * _vxn + avy * _vyn);
}
}

View file

@ -14,19 +14,19 @@ export class DragTool extends Tool {
}
mousemove(e) {
var x = this._point.x;
var y = this._point.y;
let x = this._point.x;
let y = this._point.y;
this.viewer.screenToModel2(e.offsetX, e.offsetY, this._point);
var dx = this._point.x - x;
var dy = this._point.y - y;
// for (var i = 0; i < this.lockedShifts.length; i += 2) {
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)) {
if (!Tool.dumbMode(e) || this.obj.constraints.length !== 0) {
// this.viewer.parametricManager.prepare();
this.viewer.parametricManager.solve(true);
}
@ -40,9 +40,10 @@ export class DragTool extends Tool {
this.origin.x = e.offsetX;
this.origin.y = e.offsetY;
this.viewer.screenToModel2(e.offsetX, e.offsetY, this._point);
this.viewer.parametricManager.algNumSystem.controlBounds = true;
this.viewer.parametricManager.prepare([this.obj]);
if (this.obj.constraints.length !== 0) {
this.viewer.parametricManager.algNumSystem.controlBounds = true;
this.viewer.parametricManager.prepare([this.obj]);
}
}
mouseup(e) {
@ -50,7 +51,7 @@ export class DragTool extends Tool {
this.viewer.refresh();
this.viewer.parametricManager.algNumSystem.controlBounds = false;
this.viewer.toolManager.releaseControl();
var traveled = math.distance(this.origin.x, this.origin.y, e.offsetX, e.offsetY);
let traveled = math.distance(this.origin.x, this.origin.y, e.offsetX, e.offsetY);
if (traveled >= 10) {
this.viewer.historyManager.lightCheckpoint(10);
}
@ -60,96 +61,4 @@ export class DragTool extends Tool {
mousewheel(e) {
}
solveRequest(rough) {
var paramsToUpdate = [];
this.viewer.accept(function (obj) {
if (obj.aux !== true) {
if (obj.recoverIfNecessary()){
obj.collectParams(paramsToUpdate);
}
}
return true;
});
if (paramsToUpdate.length != 0) {
for (var i = 0; i < paramsToUpdate.length; i++) {
this.solver.updateParameter(paramsToUpdate[i]);
}
this.solver.solve(rough, 1);
}
}
getParamsToLock() {
var params = [];
this.obj.accept(function (obj) {
if (obj._class === 'TCAD.TWO.EndPoint' && !obj.fullyConstrained) {
params.push(obj._x);
params.push(obj._y);
}
return true;
});
return params;
}
prepareSolver(extraConstraints) {
var locked = this.getParamsToLock();
this.lockedShifts = [];
this.lockedValues = [];
for (var i = 0; i < locked.length; i += 2) {
this.lockedShifts[i] = this._point.x - locked[i].get();
this.lockedShifts[i + 1] = this._point.y - locked[i + 1].get();
}
this.solver = this.viewer.parametricManager.prepare(locked, extraConstraints);
//this.enableRecording();
}
enableRecording() {
var solver = this.solver;
DragTool.snapshots = [];
optim.DEBUG_HANDLER = () => {
DragTool.snapshots.push([]);
for (var i = 0; i < solver.solvers.length; i++) {
var sys = solver.solvers[i].system;
DragTool.snapshots[i].push(sys.params.map(function (p) {
return p.get()
}))
}
}
}
animateSolution() {
if (DragTool.snapshots.length === 0) return;
var stepNum = 0;
var scope = this;
var then = Date.now();
var speed = 500;
function step() {
var now = Date.now();
var elapsed = now - then;
if (elapsed > speed) {
for (var i = 0; i < scope.solver.solvers.length; i++) {
var sys = scope.solver.solvers[i].system;
if (stepNum >= DragTool.snapshots[i].length) continue;
var values = DragTool.snapshots[i][stepNum];
for (var k = 0; k < values.length; k++) {
sys.params[k]._backingParam.set(values[k]);
}
}
stepNum++;
then = now;
scope.viewer.repaint();
}
if (DragTool.snapshots.length != 0 && stepNum < DragTool.snapshots[0].length) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
}
}
DragTool.snapshots = [];

View file

@ -163,29 +163,31 @@ class Viewer {
return false;
}
for (var i = 0; i < this.layers.length; i++) {
var objs = this.layers[i].objects;
for (var j = 0; j < objs.length; j++) {
var l = unreachable + 1;
var before = pickResult.length;
objs[j].accept((o) => {
if (!o.visible) return true;
if (onlyPoints && !isEndPoint(o)) {
for (let layers of this._workspace) {
for (let i = 0; i < layers.length; i++) {
var objs = layers[i].objects;
for (var j = 0; j < objs.length; j++) {
var l = unreachable + 1;
var before = pickResult.length;
objs[j].accept((o) => {
if (!o.visible) return true;
if (onlyPoints && !isEndPoint(o)) {
return true;
}
l = o.normalDistance(aim, this.scale / this.retinaPxielRatio);
if (l >= 0 && l <= buffer && !isFiltered(o)) {
pickResult.push(o);
return false;
}
return true;
}
l = o.normalDistance(aim, this.scale);
if (l >= 0 && l <= buffer && !isFiltered(o)) {
pickResult.push(o);
return false;
}
return true;
});
var hit = before - pickResult.length != 0;
if (hit) {
if (!deep && pickResult.length != 0) return pickResult;
if (l >= 0 && l < heroLength) {
heroLength = l;
heroIdx = pickResult.length - 1;
});
var hit = before - pickResult.length != 0;
if (hit) {
if (!deep && pickResult.length != 0) return pickResult;
if (l >= 0 && l < heroLength) {
heroLength = l;
heroIdx = pickResult.length - 1;
}
}
}
}