UNPKG

@mlightcad/geometry-engine

Version:

The geometry-engine package provides comprehensive geometric entities, mathematical operations, and transformations for 2D and 3D space. This package mimics AutoCAD ObjectARX's AcGe (Geometry) classes and provides the mathematical foundation for CAD opera

298 lines 12.3 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { AcGeBox3d, AcGePoint3d, AcGeVector3d } from '../math'; import { AcGeMathUtil } from '../util'; import { AcGeCurve3d } from './AcGeCurve3d'; /** * The class represents one 3d line geometry specified by its start point and end point. */ var AcGeLine3d = /** @class */ (function (_super) { __extends(AcGeLine3d, _super); /** * This constructor initializes the line object to use start as the start point, and end * as the endpoint. Both points must be in WCS coordinates. */ function AcGeLine3d(start, end) { var _this = _super.call(this) || this; _this._start = new AcGePoint3d(start); _this._end = new AcGePoint3d(end); return _this; } Object.defineProperty(AcGeLine3d.prototype, "startPoint", { /** * The line's startpoint in WCS coordinates */ get: function () { return this._start; }, set: function (value) { this._start.copy(value); this._boundingBoxNeedsUpdate = true; }, enumerable: false, configurable: true }); Object.defineProperty(AcGeLine3d.prototype, "endPoint", { /** * The line's endpoint in WCS coordinates */ get: function () { return this._end; }, set: function (value) { this._end.copy(value); this._boundingBoxNeedsUpdate = true; }, enumerable: false, configurable: true }); Object.defineProperty(AcGeLine3d.prototype, "direction", { /** * Normalized direction vector of this line */ get: function () { return new AcGeVector3d() .subVectors(this.endPoint, this.startPoint) .normalize(); }, enumerable: false, configurable: true }); Object.defineProperty(AcGeLine3d.prototype, "midPoint", { /** * The middle point of this line. */ get: function () { return new AcGePoint3d((this._start.x + this._end.x) / 2, (this._start.y + this._end.y) / 2, (this._start.z + this._end.z) / 2); }, enumerable: false, configurable: true }); /** * Returns the nerest point on this line to the given point. * @param point Input point */ AcGeLine3d.prototype.nearestPoint = function (point) { return this.project(point); }; Object.defineProperty(AcGeLine3d.prototype, "length", { /** * @inheritdoc */ get: function () { return this.startPoint.distanceTo(this.endPoint); }, enumerable: false, configurable: true }); /** * Check whether the specified point is on this line. * @param point Input point to check * @returns Return true if the specified point is on this line. Otherwise, return false. */ AcGeLine3d.prototype.isPointOnLine = function (point) { // Compute the projected point on the line var projectedPoint = this.project(point); var tolerance = 1e-6; return projectedPoint.distanceTo(point) < tolerance; }; /** * Return a point at a certain position along the line. When t = 0, it returns the start point, * and when t = 1 it returns the end point. * @param t Use values 0-1 to return a position along the line. * @param target The result will be copied into this point. * @returns Return a point at a certain position along the line. */ AcGeLine3d.prototype.at = function (t, target) { return this.delta(target).multiplyScalar(t).add(this._start); }; /** * Return a point at a certain position along the line. * - If `flag` is false, use the length from start point to determinate the point * - If `flag` is true, use the length from end point to determinate the point * @param length Use this length value to return a position along the line. * @returns Return a point at a certain position along the line. */ AcGeLine3d.prototype.atLength = function (length, flag) { if (flag === void 0) { flag = false; } if (flag) { var direction = this.delta(_vector).normalize(); return new AcGePoint3d(this._start).addScaledVector(direction, length); } else { var direction = this.delta(_vector).normalize(); return new AcGePoint3d(this._end).addScaledVector(direction, length); } }; /** * Extend this line with the specified length * @param length Input the length of extension * @param inversed Input the flag to determinate which point is used to calculate the length * - ture: start point is used as the start point of the line extension * - false: end point is used as the start point of the line extension */ AcGeLine3d.prototype.extend = function (length, inversed) { if (inversed === void 0) { inversed = false; } if (inversed) { var direction = _vector.subVectors(this._start, this._end).normalize(); this._start = new AcGePoint3d(this._start).addScaledVector(direction, length); } else { var direction = this.delta(_vector).normalize(); this._end = new AcGePoint3d(this._end).addScaledVector(direction, length); } this._boundingBoxNeedsUpdate = true; return this; }; /** * Return a point parameter based on the closest point as projected on the line segment. If clampToLine * is true, then the returned value will be between 0 and 1. * @param point Input the point for which to return a point parameter. * @param clampToLine Whether to clamp the result to the range [0, 1]. * @returns Return a point parameter based on the closest point as projected on the line segment. */ AcGeLine3d.prototype.closestPointToPointParameter = function (point, clampToLine) { _startP.subVectors(point, this._start); _startEnd.subVectors(this.endPoint, this.startPoint); var startEnd2 = _startEnd.dot(_startEnd); var startEnd_startP = _startEnd.dot(_startP); var t = startEnd_startP / startEnd2; if (clampToLine) { t = AcGeMathUtil.clamp(t, 0, 1); } return t; }; /** * Return the closets point on the line. If clampToLine is true, then the returned value will be * clamped to the line segment. * @param point Return the closest point on the line to this point. * @param clampToLine Whether to clamp the returned value to the line segment. * @param target The result will be copied into this point. * @returns Return the closets point on the line. */ AcGeLine3d.prototype.closestPointToPoint = function (point, clampToLine, target) { var t = this.closestPointToPointParameter(point, clampToLine); return this.delta(target).multiplyScalar(t).add(this._start); }; /** * Returns the delta vector of the line segment (end vector minus the start vector). * @param target The result will be copied into this vector. * @returns Return the delta vector of the line segment (end vector minus the start vector). */ AcGeLine3d.prototype.delta = function (target) { return target.subVectors(this._end, this._start); }; /** * Return the square of the Euclidean distance (straight-line distance) between the line's start and * end point. * @returns Return the square of the Euclidean distance (straight-line distance) between the line's * start and end point. */ AcGeLine3d.prototype.distanceSq = function () { return this._start.distanceToSquared(this._end); }; /** * Return the Euclidean distance (straight-line distance) between the line's start and end points. * @returns Return the Euclidean distance (straight-line distance) between the line's start and end points. */ AcGeLine3d.prototype.distance = function () { return this._start.distanceTo(this._end); }; /** * Project a 3d point onto this line */ AcGeLine3d.prototype.project = function (pt) { var lineDirection = this.direction; // Create the vector from the start point to the point to project var pointDirection = _vector.subVectors(pt, this.startPoint); // Project the point onto the line using the dot product var projectionLength = pointDirection.dot(lineDirection); // Calculate the projected point return new AcGePoint3d() .copy(lineDirection) .multiplyScalar(projectionLength) .add(this.startPoint); }; /** * Finds the point on the line that is perpendicular to the given point. When you need the shortest distance * between the given point and the line, perpPoint gives the point on the line that is the closest to the * given point. * @param point Input one point to calculate the point on the line that is the closest to this point * @returns Return the point on the line that is the closest to the given point. */ AcGeLine3d.prototype.perpPoint = function (point) { var lineDirection = this.direction; var lineStart = this.startPoint; // Create a vector from the line start to the given point var pointToLineStart = _vector.subVectors(point, lineStart); // Project the point-to-line-start vector onto the line direction var projectionLength = pointToLineStart.dot(lineDirection); // Calculate the projected point on the line var projectedVector = _vector .copy(lineDirection) .multiplyScalar(projectionLength); // The perpendicular point on the line return new AcGePoint3d().addVectors(lineStart, projectedVector); }; /** * @inheritdoc */ AcGeLine3d.prototype.calculateBoundingBox = function () { var min = new AcGePoint3d(Math.min(this._start.x, this._end.x), Math.min(this._start.y, this._end.y), Math.min(this._start.z, this._end.z)); var max = new AcGePoint3d(Math.max(this._start.x, this._end.x), Math.max(this._start.y, this._end.y), Math.max(this._start.z, this._end.z)); return new AcGeBox3d(min, max); }; /** * @inheritdoc */ AcGeLine3d.prototype.transform = function (matrix) { this._start.applyMatrix4(matrix); this._end.applyMatrix4(matrix); this._boundingBoxNeedsUpdate = true; return this; }; Object.defineProperty(AcGeLine3d.prototype, "closed", { /** * @inheritdoc */ get: function () { return false; }, enumerable: false, configurable: true }); /** * @inheritdoc */ AcGeLine3d.prototype.copy = function (value) { this.startPoint = value.startPoint; this.endPoint = value.endPoint; this._boundingBoxNeedsUpdate = true; return this; }; /** * @inheritdoc */ AcGeLine3d.prototype.clone = function () { return new AcGeLine3d(this._start.clone(), this._end.clone()); }; return AcGeLine3d; }(AcGeCurve3d)); export { AcGeLine3d }; var _vector = /*@__PURE__*/ new AcGeVector3d(); var _startP = /*@__PURE__*/ new AcGeVector3d(); var _startEnd = /*@__PURE__*/ new AcGeVector3d(); //# sourceMappingURL=AcGeLine3d.js.map