jsketcher/web/app/sketcher/tools/ellipse.js
2016-12-01 00:19:31 -08:00

92 lines
No EOL
2.7 KiB
JavaScript

import {Tool} from './tool'
import {EndPoint} from '../shapes/point'
import {Ellipse} from '../shapes/ellipse'
import Vector from '../../math/vector'
export const STATE_POINT1 = 0;
export const STATE_POINT2 = 1;
export const STATE_RADIUS = 2;
export class EllipseTool extends Tool {
constructor(viewer) {
super('ellipse', viewer);
this.ellipse = null;
this.state = STATE_POINT1;
}
restart() {
this.ellipse = null;
this.state = STATE_POINT1;
this.sendHint('specify first major axis point')
}
cleanup(e) {
this.viewer.cleanSnap();
}
point(e) {
return this.viewer.snapped ? this.viewer.snapped : this.viewer.screenToModel(e);
}
mouseup(e) {
switch (this.state) {
case STATE_POINT1: {
const p = this.point(e);
this.ellipse = new Ellipse(new EndPoint(p.x, p.y), new EndPoint(p.x, p.y));
this.snapIfNeed(this.ellipse.ep1);
this.viewer.activeLayer.objects.push(this.ellipse);
this.viewer.refresh();
this.state = STATE_POINT2;
this.sendHint('specify second major axis point');
break;
}
case STATE_POINT2: {
const p = this.point(e);
this.ellipse.ep2.setFromPoint(p);
this.snapIfNeed(this.ellipse.ep2);
this.viewer.refresh();
this.state = STATE_RADIUS;
this.sendHint('specify minor axis radius');
break;
}
case STATE_RADIUS:
this.viewer.toolManager.releaseControl();
}
}
mousemove(e) {
const p = this.viewer.screenToModel(e);
switch (this.state) {
case STATE_POINT1:
this.viewer.snap(p.x, p.y, []);
break;
case STATE_POINT2:
this.ellipse.ep2.setFromPoint(this.viewer.screenToModel(e));
this.ellipse.r.value = this.ellipse.radiusX * 0.5;
this.viewer.snap(p.x, p.y, [this.ellipse.ep1, this.ellipse.ep2]);
break;
case STATE_RADIUS:
const polarPoint = this.ellipse.toEllipseCoordinateSystem(p);
let minorRadius = Ellipse.findMinorRadius(this.ellipse.radiusX, polarPoint.radius, polarPoint.angle);
if (isNaN(minorRadius)) {
const projAxis = new Vector(-(this.ellipse.ep2.y - this.ellipse.ep1.y), this.ellipse.ep2.x - this.ellipse.ep1.x);
projAxis._normalize();
const v = new Vector(this.ellipse.ep2.x - p.x, this.ellipse.ep2.y - p.y);
minorRadius = Math.abs(projAxis.dot(v));
}
this.ellipse.r.set(minorRadius);
if (!Tool.dumbMode(e)) {
this.solveRequest(true);
}
break;
}
this.viewer.refresh();
}
solveRequest(rough) {
this.solver = this.viewer.parametricManager.prepare([this.ellipse.r]);
this.solver.solve(rough, 1);
this.solver.sync();
}
}