add terminal support for arcs

This commit is contained in:
Val Erastov 2016-11-27 23:27:55 -08:00
parent 85bc6cd711
commit 3bce2d9862
4 changed files with 171 additions and 90 deletions

View file

@ -1,11 +1,11 @@
import * as utils from '../../utils/utils';
import * as math from '../../math/math';
import Vector from '../../math/vector'
import {SketchObject, EndPoint, Ref} from '../viewer2d'
import {SketchObject, Ref} from '../viewer2d'
import {Constraints} from '../parametric'
/** @constructor */
function Arc(a, b, c) {
export function Arc(a, b, c) {
SketchObject.call(this);
this.a = a;
this.b = b;
@ -130,86 +130,3 @@ Arc.prototype.stabilize = function(viewer) {
viewer.parametricManager._add(new Constraints.P2PDistanceV(this.a, this.c, this.r));
};
/** @constructor */
function AddArcTool(viewer) {
this.viewer = viewer;
this.arc = null;
this.point = null;
this._v = new Vector(0, 0, 0);
}
AddArcTool.prototype.keydown = function(e) {};
AddArcTool.prototype.keypress = function(e) {};
AddArcTool.prototype.keyup = function(e) {};
AddArcTool.prototype.cleanup = function(e) {};
AddArcTool.prototype.mousemove = function(e) {
var p = this.viewer.screenToModel(e);
if (this.point != null) {
this.point.x = p.x;
this.point.y = p.y;
var r = math.distance(this.arc.a.x, this.arc.a.y, this.arc.c.x, this.arc.c.y);
if (this.point.id === this.arc.b.id) {
//force placement second point on the arc
var v = this._v;
v.set(this.arc.b.x - this.arc.c.x, this.arc.b.y - this.arc.c.y, 0);
v._normalize()._multiply(r);
this.arc.b.x = v.x + this.arc.c.x;
this.arc.b.y = v.y + this.arc.c.y;
} else {
var ang = Math.atan2(this.point.y - this.arc.c.y, this.point.x - this.arc.c.x) + (2 * Math.PI - 0.3);
ang %= 2 * Math.PI;
this.arc.b.x = this.arc.c.x + r * Math.cos(ang);
this.arc.b.y = this.arc.c.y + r * Math.sin(ang);
}
this.viewer.snap(p.x, p.y, [this.arc.a, this.arc.b, this.arc.c]);
this.viewer.refresh();
} else {
this.viewer.snap(p.x, p.y, []);
this.viewer.refresh();
}
};
AddArcTool.prototype.mouseup = function(e) {
if (this.arc == null) {
this.viewer.historyManager.checkpoint();
var p = this.viewer.screenToModel(e);
this.arc = new Arc(
new EndPoint(p.x, p.y),
new EndPoint(p.x, p.y),
new EndPoint(p.x, p.y)
);
this.point = this.arc.a;
this.viewer.activeLayer.objects.push(this.arc);
this.snapIfNeed(this.arc.c);
this.viewer.refresh();
} else if (this.point.id === this.arc.a.id) {
this.snapIfNeed(this.arc.a);
this.point = this.arc.b;
} else {
this.snapIfNeed(this.arc.b);
this.arc.stabilize(this.viewer);
this.viewer.toolManager.releaseControl();
}
};
AddArcTool.prototype.snapIfNeed = function(p) {
if (this.viewer.snapped.length != 0) {
var snapWith = this.viewer.snapped.pop();
this.viewer.cleanSnap();
this.viewer.parametricManager.linkObjects([p, snapWith]);
this.viewer.parametricManager.refresh();
}
};
AddArcTool.prototype.mousedown = function(e) {
};
AddArcTool.prototype.mousewheel = function(e) {
};
export {Arc, AddArcTool}

View file

@ -5,7 +5,7 @@ import {IO, BBox} from './io'
import {AddDimTool, AddCircleDimTool, HDimension, VDimension, Dimension, DiameterDimension} from './shapes/dim'
import {AddPointTool} from './tools/point'
import {AddSegmentTool} from './tools/segment'
import {AddArcTool} from './shapes/arc'
import {AddArcTool} from './tools/arc'
import {EditCircleTool} from './tools/circle'
import {FilletTool} from './helpers'
import {ReferencePointTool} from './tools/origin'

View file

@ -0,0 +1,134 @@
import {Arc} from '../shapes/arc'
import {EndPoint} from '../viewer2d'
import {Tool} from './tool'
import Vector from '../../math/vector'
import * as math from '../../math/math';
export class AddArcTool extends Tool{
constructor(viewer) {
super('arc', viewer);
this.arc = null;
this.point = null;
this._v = new Vector(0, 0, 0);
}
restart() {
this.sendHint('specify center');
}
mousemove(e) {
var p = this.viewer.screenToModel(e);
if (this.point != null) {
this.point.x = p.x;
this.point.y = p.y;
if (this.point.id === this.arc.b.id) {
//force placement second point on the arc
const r = this.radiusOfFirstPoint();
const v = this._v;
v.set(this.arc.b.x - this.arc.c.x, this.arc.b.y - this.arc.c.y, 0);
v._normalize()._multiply(r);
this.arc.b.x = v.x + this.arc.c.x;
this.arc.b.y = v.y + this.arc.c.y;
} else {
this.demoSecondPoint();
}
this.viewer.snap(p.x, p.y, [this.arc.a, this.arc.b, this.arc.c]);
this.viewer.refresh();
} else {
this.viewer.snap(p.x, p.y, []);
this.viewer.refresh();
}
}
mouseup(e) {
if (this.arc == null) {
const center = this.viewer.screenToModel(e);
this.createArcStep(center);
} else if (this.point.id === this.arc.a.id) {
this.snapIfNeed(this.arc.a);
this.startingPointSetStep();
} else {
this.snapIfNeed(this.arc.b);
this.finishStep();
}
}
createArcStep(p) {
this.viewer.historyManager.checkpoint();
this.arc = new Arc(
new EndPoint(p.x, p.y),
new EndPoint(p.x, p.y),
new EndPoint(p.x, p.y)
);
this.point = this.arc.a;
this.viewer.activeLayer.objects.push(this.arc);
this.snapIfNeed(this.arc.c);
this.pointPicked(p.x, p.y);
this.sendHint('specify arc starting point');
this.viewer.refresh();
}
startingPointSetStep() {
this.point = this.arc.b;
this.pointPicked(this.arc.a.x, this.arc.a.y);
this.sendHint('specify angle')
}
finishStep() {
this.arc.stabilize(this.viewer);
this.pointPicked(this.arc.b.x, this.arc.b.y);
this.viewer.refresh();
this.viewer.toolManager.releaseControl();
}
snapIfNeed(p) {
if (this.viewer.snapped.length != 0) {
var snapWith = this.viewer.snapped.pop();
this.viewer.cleanSnap();
this.viewer.parametricManager.linkObjects([p, snapWith]);
this.viewer.parametricManager.refresh();
}
}
demoSecondPoint() {
const r = this.radiusOfFirstPoint();
let ang = Math.atan2(this.arc.a.y - this.arc.c.y, this.arc.a.x - this.arc.c.x) + (2 * Math.PI - 0.3);
ang %= 2 * Math.PI;
this.arc.b.x = this.arc.c.x + r * Math.cos(ang);
this.arc.b.y = this.arc.c.y + r * Math.sin(ang);
}
radiusOfFirstPoint() {
return math.distance(this.arc.a.x, this.arc.a.y, this.arc.c.x, this.arc.c.y);
}
processCommand(command) {
if (this.arc == null) {
const result = Tool.ParseVector(this.viewer.referencePoint, command);
if(typeof result === 'string') return result;
this.viewer.cleanSnap();
this.createArcStep(result);
} else if (this.point.id === this.arc.a.id) {
const result = Tool.ParseVector(this.viewer.referencePoint, command);
if(typeof result === 'string') return result;
this.arc.a.x = result.x;
this.arc.a.y = result.y;
this.startingPointSetStep();
this.demoSecondPoint();
this.viewer.refresh();
} else {
const startingAngle = Math.atan2(this.point.y - this.arc.c.y, this.point.x - this.arc.c.x);
const result = Tool.ParseNumberWithRef(command, startingAngle); // treated as radius and angle
const r = this.radiusOfFirstPoint();
if(typeof result === 'string') return result;
let angle = result / 180 * Math.PI;
angle %= 2 * Math.PI;
this.arc.b.x = this.arc.c.x + r * Math.cos(angle);
this.arc.b.y = this.arc.c.y + r * Math.sin(angle);
this.finishStep();
}
}
}

View file

@ -43,11 +43,9 @@ export class Tool {
};
}
const VECTOR_PATTERNS = /^(@)?(.+)(,|<)(.+)$/;
Tool.ParseNumber = function(str) {
let val;
try {
try {
val = eval(str);
} catch(e) {
return e.toString();
@ -57,10 +55,26 @@ Tool.ParseNumber = function(str) {
return valNumber;
};
Tool.ParseNumberWithRef = function(str, ref) {
const rel = str.startsWith('@');
if (rel) {
str = str.substring(1);
}
let val = Tool.ParseNumber(str);
if(typeof val === 'string') return val;
if (rel) {
val += ref;
}
return val;
};
const VECTOR_PATTERN = /^(@)?(.+)(,|<)(.+)$/;
Tool.ParseVector = function(referencePoint, command) {
command = command.replace(/\s+/g, '');
const match = command.match(VECTOR_PATTERNS);
const match = command.match(VECTOR_PATTERN);
if (match) {
const ref = match[1] !== undefined;
let x = Tool.ParseNumber(match[2]);
@ -84,4 +98,20 @@ Tool.ParseVector = function(referencePoint, command) {
return "wrong input, point is expected: x,y | @x,y | r<polar | @r<polar ";
};
Tool.ParseNumberSequence = function(command, refs, length) {
command = command.replace(/\s+/g, '');
const parts = command.split(',');
const result = [];
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
let val = refs && refs[i] ? Tool.ParseNumberWithRef(part, refs[i]) : Tool.ParseNumberWithRef(part);
result.push(val);
}
if (length !== undefined && result.length != length) {
return "wrong input, sequence of length " + length + " is expected: x1,x2...";
}
return result;
};