@numericelements/knot-sequence
Version:
A library for generating and manipulating knot sequences for b-spline curves and surfaces
134 lines (131 loc) • 5.37 kB
JavaScript
import { EM_KNOT_CONSTRUCTOR_KNOT_ABSCISSA, EM_KNOT_CONSTRUCTOR_KNOT_MULTIPLICITY, EM_KNOT_INCREMENT_DECREMENT, EM_KNOT_DECREMENT_KNOT_MULTIPLICITY } from './ErrorMessages/Knots.js';
import { ErrorLog } from './errorProcessing/ErrorLoging.js';
import { DEFAULT_KNOT_ABSCISSA_VALUE, DEFAULT_MULTIPLICITY_VALUE } from './namedConstants/Knots.js';
/**
* Represents a knot in a B-spline knot sequence with its location (abscissa) along the axis of reals and its multiplicity.
*
* @description
* The Knot class encapsulates the concept of a knot in a B-spline knot sequence.
* The abscissa and/or multiplicity default to Infinity. This is a special value indicating that the abscissa and/or multiplicity
* is not yet defined since an abscissa value of 0 or a multiplicity of 0 can be regarded as a valid.
*
*
*/
class Knot {
/**
* Creates a new knot.
*
* @param abscissa - Position value of the knot along the axis of reals (default: Infinity)
* @param multiplicity - Number of times the knot is repeated (default: 1 when abscissa is not Infinity, otherwise Infinity)
* @throws {RangeError} If multiplicity is less than 1
* @throws {RangeError} If abscissa is less than 1
*
* @example
* const knot = new Knot(1.5, 2); // Knot at u=1.5 with multiplicity 2
* const knot = new Knot(1.5); // Knot at u=1.5 with multiplicity that defaults to 1
* const knot = new Knot(); // Knot at default value (Infinity) with multiplicity that defaults to Infinity
*/
constructor(abscissa, multiplicity) {
if (abscissa !== undefined) {
if (abscissa === DEFAULT_KNOT_ABSCISSA_VALUE) {
this.throwRangeErrorMessage("constructor", EM_KNOT_CONSTRUCTOR_KNOT_ABSCISSA);
}
this._abscissa = abscissa;
}
else {
this._abscissa = DEFAULT_KNOT_ABSCISSA_VALUE;
}
if (multiplicity !== undefined) {
if (multiplicity < 1) {
this.throwRangeErrorMessage("constructor", EM_KNOT_CONSTRUCTOR_KNOT_MULTIPLICITY);
}
this._multiplicity = multiplicity;
}
else if (this._abscissa !== DEFAULT_KNOT_ABSCISSA_VALUE) {
this._multiplicity = 1;
}
else {
this._multiplicity = DEFAULT_MULTIPLICITY_VALUE;
}
}
/**
* Gets the abscissa (position) value of the knot
* @returns The abscissa value along the axis of reals
*/
get abscissa() {
return this._abscissa;
}
/**
* Gets the multiplicity (number of repetitions) of the knot
* @returns The multiplicity value
*/
get multiplicity() {
return this._multiplicity;
}
/**
* Sets the abscissa (position) value of the knot
* @param abscissa - The new abscissa value to set
* @throws {RangeError} If abscissa equals DEFAULT_KNOT_ABSCISSA_VALUE
*/
set abscissa(abscissa) {
if (abscissa === DEFAULT_KNOT_ABSCISSA_VALUE) {
this.throwRangeErrorMessage("abscissa_setter", EM_KNOT_CONSTRUCTOR_KNOT_ABSCISSA);
}
else {
this._abscissa = abscissa;
}
}
/**
* Sets the multiplicity (number of repetitions) of the knot
* @param multiplicity - The new multiplicity value to set
* @throws {RangeError} If multiplicity is less than 1
*/
set multiplicity(multiplicity) {
if (multiplicity < 1) {
this.throwRangeErrorMessage("multiplicity_setter", EM_KNOT_CONSTRUCTOR_KNOT_MULTIPLICITY);
}
else {
this._multiplicity = multiplicity;
}
}
/**
* Increases the knot multiplicity by the specified increment
* @param increment - The value to increase multiplicity by (default: 1)
* @throws {RangeError} If increment is less than 1
*/
incrementMultiplicity(increment = 1) {
if (increment < 1)
this.throwRangeErrorMessage("incrementMultiplicity", EM_KNOT_INCREMENT_DECREMENT);
this._multiplicity = this._multiplicity + increment;
return;
}
/**
* Decreases the knot multiplicity by the specified decrement
* @param decrement - The value to decrease multiplicity by (default: 1)
* @throws {RangeError} If decrement is less than 1 or if resulting multiplicity would be less than 1
*/
decrementMultiplicity(decrement = 1) {
if (decrement < 1)
this.throwRangeErrorMessage("incrementMultiplicity", EM_KNOT_INCREMENT_DECREMENT);
if (this._multiplicity < (decrement + 1)) {
this.throwRangeErrorMessage("decrementMultiplicity", EM_KNOT_DECREMENT_KNOT_MULTIPLICITY);
}
else {
this._multiplicity = this._multiplicity - decrement;
}
return;
}
/**
* Throws a RangeError with formatted error message
* @param functionName - Name of the function where error occurred
* @param message - The error message to display
* @throws {RangeError} With formatted error message
*/
throwRangeErrorMessage(functionName, message) {
const error = new ErrorLog(this.constructor.name, functionName);
error.addMessage(message);
console.log(error.generateMessageString());
throw new RangeError(error.generateMessageString());
}
}
export { Knot };