jsketcher/web/app/sketcher/tools/arc.js
2022-08-15 23:47:20 -07:00

125 lines
3.6 KiB
JavaScript

import {Arc} from '../shapes/arc'
import {Tool} from './tool'
import Vector from 'math/vector';
import {distance} from "math/distance";
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) {
const 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.arc.syncGeometry();
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(
p.x, p.y,
p.x, p.y,
p.x, p.y
);
this.point = this.arc.a;
this.viewer.activeLayer.add(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.parametricManager.refresh();
this.viewer.toolManager.releaseControl();
}
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 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();
}
}
}