@numericelements/knot-sequence
Version:
A library for generating and manipulating knot sequences for b-spline curves and surfaces
104 lines (101 loc) • 5.41 kB
JavaScript
import { KNOT_SEQUENCE_ORIGIN, KNOT_COINCIDENCE_TOLERANCE, UPPER_BOUND_NORMALIZED_BASIS_DEFAULT_ABSCISSA } from './namedConstants/KnotSequences.js';
import { AbstractStrictlyIncreasingOpenKnotSequence } from './AbstractStrictlyIncreasingOpenKnotSequence.js';
import { STRICTLYINCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY, STRICTLYINCREASINGOPENKNOTSEQUENCE } from './KnotSequenceConstructorInterface.js';
import { EM_INCONSISTENT_ORIGIN_NONUNIFORM_KNOT_SEQUENCE, EM_U_OUTOF_KNOTSEQ_RANGE } from './ErrorMessages/KnotSequences.js';
import { KnotIndexStrictlyIncreasingSequence } from './KnotIndexStrictlyIncreasingSequence.js';
class StrictlyIncreasingOpenKnotSequenceOpenCurve extends AbstractStrictlyIncreasingOpenKnotSequence {
constructor(maxMultiplicityOrder, knotParameters) {
super(maxMultiplicityOrder, knotParameters);
this.updateNormalizedBasisOrigin();
this.checkMaxMultiplicityOrderConsistency();
this.checkNonUniformKnotMultiplicityOrder();
this.checkUniformityOfKnotMultiplicity();
this.checkUniformityOfKnotSpacing();
}
get isSequenceUpToC0Discontinuity() {
return this._isSequenceUpToC0Discontinuity;
}
updateNormalizedBasisOrigin() {
if (this.knotSequence[0].abscissa !== KNOT_SEQUENCE_ORIGIN && this._maxMultiplicityOrder === this.knotSequence[0].multiplicity) {
this.throwRangeErrorMessage("checkCurveOrigin", EM_INCONSISTENT_ORIGIN_NONUNIFORM_KNOT_SEQUENCE);
}
else if (this.knotSequence[0].abscissa !== KNOT_SEQUENCE_ORIGIN) {
super.updateNormalizedBasisOrigin();
}
}
checkNonUniformKnotMultiplicityOrder() {
this._isKnotMultiplicityNonUniform = false;
if (this.knotSequence[0].multiplicity === this._maxMultiplicityOrder &&
this.knotSequence[this.knotSequence.length - 1].multiplicity === this._maxMultiplicityOrder)
this._isKnotMultiplicityNonUniform = true;
}
clone() {
if (this._isSequenceUpToC0Discontinuity) {
return new StrictlyIncreasingOpenKnotSequenceOpenCurve(this._maxMultiplicityOrder, { type: STRICTLYINCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY, knots: this.distinctAbscissae(), multiplicities: this.multiplicities() });
}
else {
return new StrictlyIncreasingOpenKnotSequenceOpenCurve(this._maxMultiplicityOrder, { type: STRICTLYINCREASINGOPENKNOTSEQUENCE, knots: this.distinctAbscissae(), multiplicities: this.multiplicities() });
}
}
findSpan(u) {
let index = UPPER_BOUND_NORMALIZED_BASIS_DEFAULT_ABSCISSA;
if (u < KNOT_SEQUENCE_ORIGIN || u > this._uMax) {
this.throwRangeErrorMessage("findSpan", EM_U_OUTOF_KNOTSEQ_RANGE);
}
else {
if (this.isAbscissaCoincidingWithKnot(u)) {
index = 0;
for (const knot of this.knotSequence) {
index++;
if (Math.abs(u - knot.abscissa) < KNOT_COINCIDENCE_TOLERANCE) {
if (knot.abscissa === this.knotSequence[this.knotSequence.length - 1].abscissa) {
index = this.knotSequence.length - 1;
}
index -= 1;
break;
}
}
return new KnotIndexStrictlyIncreasingSequence(index);
}
const indexAtUmax = this.getKnotIndexNormalizedBasisAtSequenceEnd();
index = this.findSpanWithAbscissaDistinctFromKnotStrictlyIncreasingKnotSequence(u, indexAtUmax.knot.knotIndex);
}
return new KnotIndexStrictlyIncreasingSequence(index);
}
revertKnotSequence() {
const newKnotSequence = this.clone();
newKnotSequence.revertKnotSpacing();
return newKnotSequence;
}
decrementKnotMultiplicity(index, checkSequenceConsistency = true) {
const newKnotSequence = this.clone();
newKnotSequence.decrementKnotMultiplicityMutSeq(index, checkSequenceConsistency);
return newKnotSequence;
}
raiseKnotMultiplicity(index, multiplicity = 1, checkSequenceConsistency = true) {
const newKnotSequence = this.clone();
newKnotSequence.raiseKnotMultiplicityKnotArrayMutSeq(index, multiplicity, checkSequenceConsistency);
return newKnotSequence;
}
insertKnot(abscissae, multiplicity = 1) {
const newKnotSequence = this.clone();
newKnotSequence.insertKnotAbscissaArrayMutSeq(abscissae, multiplicity);
return newKnotSequence;
}
updateKnotSequenceThroughNormalizedBasisAnalysis() {
const previousKnotSequence = this.knotSequence.slice();
this.updateKnotSequenceThroughNormalizedBasisAnalysisMutSeq();
const knotAbscissae = [];
const multiplicities = [];
for (const knot of this.knotSequence) {
if (knot !== undefined) {
knotAbscissae.push(knot.abscissa);
multiplicities.push(knot.multiplicity);
}
}
const updatedSeq = new StrictlyIncreasingOpenKnotSequenceOpenCurve(this._maxMultiplicityOrder, { type: STRICTLYINCREASINGOPENKNOTSEQUENCE, knots: knotAbscissae, multiplicities: multiplicities });
this.knotSequence = previousKnotSequence;
return updatedSeq;
}
}
export { StrictlyIncreasingOpenKnotSequenceOpenCurve };