jsketcher/web/app/sketcher/shapes/elliptical-arc.js
2020-05-14 03:49:53 -07:00

81 lines
2.2 KiB
JavaScript

import {Ellipse} from './ellipse'
import {Constraints} from '../parametric'
import * as math from '../../math/math';
import {swap} from '../../utils/utils'
import {EndPoint} from "./point";
export class EllipticalArc extends Ellipse {
constructor(x1, y1, x2, y2, ax, ay, bx, by, r, id) {
super(x1, y1, x2, y2, r, id);
this.a = new EndPoint(ax, ay, this.id + ':A');
this.b = new EndPoint(bx, by, this.id + ':B');
this.addChild(this.a);
this.addChild(this.b);
//we'd like to have angles points have higher selection order
swap(this.children, 0, this.children.length - 2);
swap(this.children, 1, this.children.length - 1);
}
stabilize(viewer) {
this.stage.addConstraint(new Constraints.PointOnEllipseInternal(this.b, this));
this.stage.addConstraint(new Constraints.PointOnEllipseInternal(this.a, this));
}
drawImpl(ctx, scale) {
ctx.beginPath();
const radiusX = Math.max(this.radiusX, 1e-8);
const radiusY = Math.max(this.radiusY, 1e-8);
let aAngle = this.drawAngle(this.a);
let bAngle;
if (math.areEqual(this.a.x, this.b.x, math.TOLERANCE) &&
math.areEqual(this.a.y, this.b.y, math.TOLERANCE)) {
bAngle = aAngle + 2 * Math.PI;
} else {
bAngle = this.drawAngle(this.b)
}
ctx.ellipse(this.centerX, this.centerY, radiusX, radiusY, this.rotation, aAngle, bAngle );
ctx.stroke();
}
drawAngle(point) {
let deformScale = this.radiusY / this.radiusX;
let x = point.x - this.centerX;
let y = point.y - this.centerY;
const rotation = - this.rotation;
let xx = x * Math.cos(rotation) - y * Math.sin(rotation);
let yy = x * Math.sin(rotation) + y * Math.cos(rotation);
xx *= deformScale;
return Math.atan2(yy, xx);
}
write() {
return {
ep1: this.ep1.write(),
ep2: this.ep2.write(),
a: this.a.write(),
b: this.b.write(),
r: this.r.get()
}
}
static read(id, data) {
return new EllipticalArc(
data.ep1.x,
data.ep1.y,
data.ep2.x,
data.ep2.y,
data.a.x,
data.a.y,
data.b.x,
data.b.y,
data.r,
id
);
}
}
EllipticalArc.prototype._class = 'TCAD.TWO.EllipticalArc';
EllipticalArc.prototype.TYPE = 'EllipticalArc';