import {Axis, Plane, Vector} from "../math";
import {Line, BezierCurve, ThreePointsArc, TangentArc} from "../primitives-1d";
import {Face, Wire} from "../modeling";
/**
* Represents a 2D sketch on a specified plane.
* @memberof sketch
* @alias Sketch
*/
export class Sketch {
#plane;
#pointer;
#edges = [];
/**
* Creates a new Sketch on the given plane.
* @param {Plane} [plane=Plane.XY] - The sketch plane.
*/
constructor(plane = Plane.XY) {
this.#plane = plane;
this.#pointer = plane.origin;
}
/**
* Returns the current pointer position.
* @returns {Vector} The pointer position.
*/
get pointer() {
return this.#pointer;
}
/**
* Moves the pointer to a given point (only if no edges exist).
* @param {Vector} point - The new pointer position.
* @returns {Sketch} The current `Sketch` instance.
*/
movePointerTo(point) {
if (!this.#edges.length) {
this.#pointer = point;
}
return this;
}
/**
* Adds a line from the current pointer to the given point.
* @param {Vector} point - The end point of the line.
* @returns {Sketch} The current `Sketch` instance.
*/
lineTo(point) {
const line = Line({plane: this.#plane, start: this.#pointer, end: point});
this.#edges.push(line);
this.#pointer = point;
return this;
}
/**
* Adds a line from the pointer by the given offset.
* @param {Vector} offset - The offset vector.
* @returns {Sketch} The current `Sketch` instance.
*/
line(offset) {
return this.lineTo(this.#pointer.add(offset));
}
/**
* Adds a line at a given angle and length from the pointer.
* @param {Object} params - Parameters.
* @param {number} params.length - The line length.
* @param {number} params.angle - The angle in radians.
* @returns {Sketch} The current `Sketch` instance.
*/
lineAtAngle({length, angle}) {
return this.lineTo(
this.#pointer
.add(this.#plane.xDirection.scale(length))
.rotate({axis: new Axis({origin: this.#pointer, direction: this.#plane.normal}), angle: angle})
);
}
/**
* Adds a line tangent to the last edge, with the given length.
* @param {number} length - The tangent line length.
* @returns {Sketch} The current `Sketch` instance.
*/
tangentLine(length) {
const tangent = this.#edges[this.#edges.length - 1].tangentAt(1);
return this.lineTo(this.#pointer.add(tangent.scale(length)));
}
/**
* Adds a tangent arc from the last edge to the given point.
* @param {Vector} point - The arc end point.
* @returns {Sketch} The current `Sketch` instance.
*/
tangentArcTo(point) {
const previousEdge = this.#edges[this.#edges.length - 1];
const arc = TangentArc({plane: this.#plane, start: previousEdge.pointAt(1), tangent: previousEdge.tangentAt(1), end: point});
this.#edges.push(arc);
this.#pointer = point;
return this;
}
/**
* Adds a tangent arc from the pointer by the given offset.
* @param {Vector} offset - The offset vector.
* @returns {Sketch} The current `Sketch` instance.
*/
tangentArc(offset) {
return this.tangentArcTo(this.#pointer.add(offset));
}
/**
* Adds a three-point arc from the pointer, through a point, to an end point.
* @param {Object} params - Parameters.
* @param {Vector} params.through - The through point.
* @param {Vector} params.end - The arc end point.
* @returns {Sketch} The current `Sketch` instance.
*/
threePointsArcTo({through, end}) {
const arc = ThreePointsArc({plane: this.#plane, start: this.#pointer, through: through, end: end});
this.#edges.push(arc);
this.#pointer = end;
return this;
}
/**
* Adds a Bezier curve from the pointer through the given points.
* @param {Vector[]} points - Control points (excluding start).
* @returns {Sketch} The current `Sketch` instance.
*/
bezierCurveTo(points) {
const curve = BezierCurve({plane: this.#plane, points: [this.#pointer, ...points]});
this.#edges.push(curve);
this.#pointer = points[points.length - 1];
return this;
}
/**
* Converts the sketch to a planar face.
* @returns {Face} The resulting `Face`.
*/
toFace() {
return Face.fromWire(Wire.fromEdges(...this.#edges));
}
/**
* Converts the sketch to a Wire.
* @returns {Wire} The resulting `Wire`.
*/
toWire() {
return Wire.fromEdges(...this.#edges);
}
}