@numericelements/knot-sequence
Version:
A library for generating and manipulating knot sequences for b-spline curves and surfaces
109 lines (106 loc) • 5.74 kB
JavaScript
import { KNOT_SEQUENCE_ORIGIN, KNOT_COINCIDENCE_TOLERANCE, UPPER_BOUND_NORMALIZED_BASIS_DEFAULT_ABSCISSA } from './namedConstants/KnotSequences.js';
import { AbstractIncreasingOpenKnotSequence } from './AbstractIncreasingOpenKnotSequence.js';
import { KnotIndexIncreasingSequence } from './KnotIndexIncreasingSequence.js';
import { INCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY, INCREASINGOPENKNOTSEQUENCE } from './KnotSequenceConstructorInterface.js';
import { EM_U_OUTOF_KNOTSEQ_RANGE } from './ErrorMessages/KnotSequences.js';
import { fromIncreasingToStrictlyIncreasingOpenKnotSequenceOC } from './KnotSequenceAndUtilities/fromIncreasingToStrictlyIncreasingOpenKnotSequenceOC.js';
import { KnotIndexStrictlyIncreasingSequence } from './KnotIndexStrictlyIncreasingSequence.js';
class IncreasingOpenKnotSequenceOpenCurve extends AbstractIncreasingOpenKnotSequence {
constructor(maxMultiplicityOrder, knotParameters) {
super(maxMultiplicityOrder, knotParameters);
if (knotParameters.type !== INCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY)
this.updateNormalizedBasisOrigin();
this.checkNonUniformKnotMultiplicityOrder();
this.checkUniformityOfKnotMultiplicity();
this.checkUniformityOfKnotSpacing();
}
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 IncreasingOpenKnotSequenceOpenCurve(this._maxMultiplicityOrder, { type: INCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY, knots: this.allAbscissae });
}
else {
return new IncreasingOpenKnotSequenceOpenCurve(this._maxMultiplicityOrder, { type: INCREASINGOPENKNOTSEQUENCE, knots: this.allAbscissae });
}
}
toKnotIndexStrictlyIncreasingSequence(index) {
const strictlyIncreasingKnotSequence = fromIncreasingToStrictlyIncreasingOpenKnotSequenceOC(this);
const abscissa = this.abscissaAtIndex(index);
let i = 0;
for (const knot of strictlyIncreasingKnotSequence.allAbscissae) {
if (knot !== undefined) {
if (knot === abscissa)
break;
i++;
}
}
return new KnotIndexStrictlyIncreasingSequence(i);
}
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 += knot.multiplicity;
if (Math.abs(u - knot.abscissa) < KNOT_COINCIDENCE_TOLERANCE) {
if (knot.abscissa === this.knotSequence[this.knotSequence.length - 1].abscissa) {
index -= this.knotSequence[this.knotSequence.length - 1].multiplicity;
}
const curveDegree = this._maxMultiplicityOrder - 1;
if (this.isKnotMultiplicityUniform && index === (this.knotSequence.length - curveDegree))
index -= 1;
index -= 1;
break;
}
}
return new KnotIndexIncreasingSequence(index);
}
const indexAtUmax = this.getKnotIndexNormalizedBasisAtSequenceEnd();
index = this.findSpanWithAbscissaDistinctFromKnotIncreasingKnotSequence(u, indexAtUmax.knot.knotIndex);
}
return new KnotIndexIncreasingSequence(index);
}
revertKnotSequence() {
const newKnotSequence = this.clone();
newKnotSequence.revertKnotSpacing();
return newKnotSequence;
}
decrementKnotMultiplicity(index, checkSequenceConsistency = true) {
const newKnotSequence = this.clone();
newKnotSequence.decrementKnotMultiplicityKnotArrayMutSeq(index, checkSequenceConsistency);
return newKnotSequence;
}
raiseKnotMultiplicity(arrayIndices, multiplicity = 1, checkSequenceConsistency = true) {
const newKnotSequence = this.clone();
newKnotSequence.raiseKnotMultiplicityKnotArrayMutSeq(arrayIndices, multiplicity, checkSequenceConsistency);
return newKnotSequence;
}
insertKnot(arrayAbscissae, multplicity = 1) {
const newKnotSequence = this.clone();
newKnotSequence.insertKnotAbscissaArrayMutSeq(arrayAbscissae, multplicity);
return newKnotSequence;
}
updateKnotSequenceThroughNormalizedBasisAnalysis() {
const previousKnotSequence = this.knotSequence.slice();
this.updateKnotSequenceThroughNormalizedBasisAnalysisMutSeq();
const knotAbscissae = [];
for (const knot of this.allAbscissae) {
knotAbscissae.push(knot);
}
let updatedSeq = new IncreasingOpenKnotSequenceOpenCurve(this._maxMultiplicityOrder, { type: INCREASINGOPENKNOTSEQUENCE, knots: knotAbscissae });
if (this._isSequenceUpToC0Discontinuity)
updatedSeq = new IncreasingOpenKnotSequenceOpenCurve(this._maxMultiplicityOrder, { type: INCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY, knots: knotAbscissae });
this.knotSequence = previousKnotSequence;
return updatedSeq;
}
}
export { IncreasingOpenKnotSequenceOpenCurve };