@cantoo/pdf-lib
Version:
Create and modify PDF files with JavaScript
108 lines (93 loc) • 2.48 kB
text/typescript
import { angleABC, distance, distanceCoords, rotate, vector } from '../maths';
import Circle from './Circle';
import GraphElement from './GraphElement';
import Point from './Point';
export default class Arc extends GraphElement {
O: Point;
A: Point;
B: Point;
/** Last sweep. Used to deduce the angle orientation */
lastSweep: number;
constructor(
O: Point = new Point(),
A: Point = new Point(),
B: Point = new Point(),
lastSweep = 0,
) {
super();
this.O = O;
this.A = A;
this.B = B;
this.lastSweep = lastSweep;
}
center() {
return this.O;
}
origin() {
return this.A;
}
destination() {
return this.getCircle().orthoProjection(this.B);
}
sweep() {
this.lastSweep = angleABC(
this.origin(),
this.center(),
this.destination(),
this.lastSweep,
);
return this.lastSweep;
}
ray() {
return distance(this.center(), this.origin());
}
isEqual(element: GraphElement): boolean {
if (!(element instanceof Arc)) return false;
const dest = this.destination();
const o = this.origin();
const eDest = element.destination();
const eO = element.origin();
return (
this.getCircle().isEqual(element.getCircle()) &&
((dest.isEqual(eDest) && o.isEqual(eO)) ||
(dest.isEqual(eO) && o.isEqual(eDest)))
);
}
getCircle() {
const circle = new Circle(this.center(), this.ray());
return circle;
}
originVect() {
return vector(this.center(), this.origin());
}
middle() {
const halfSweep = this.sweep() / 2;
const mid = this.center().plus(
rotate(vector(this.center(), this.origin()), halfSweep),
);
return mid;
}
includes(P: Point) {
// As angles are returned between -π and π, we need the middle of the arc
return (
this.getCircle().includes(P) &&
Math.abs(angleABC(this.middle(), this.center(), P)) <=
Math.abs(this.sweep() / 2)
);
}
orthoProjection(P: Point) {
const H = this.getCircle().orthoProjection(P);
if (this.includes(H)) return H;
else {
const origin = this.origin().toCoords();
const destination = this.destination().toCoords();
// Returns the closest between origin and destination
const coords =
distanceCoords(H.toCoords(), origin) <
distanceCoords(H.toCoords(), destination)
? origin
: destination;
return new Point(coords);
}
}
}