@numericelements/knot-sequence
Version:
A library for generating and manipulating knot sequences for b-spline curves and surfaces
206 lines (202 loc) • 11.1 kB
JavaScript
'use strict';
var tslib = require('tslib');
var AbstractOpenKnotSequence = require('./AbstractOpenKnotSequence.cjs');
var Knot = require('./Knot.cjs');
var KnotSequenceConstructorInterface = require('./KnotSequenceConstructorInterface.cjs');
var KnotSequences = require('./ErrorMessages/KnotSequences.cjs');
var KnotSequences$1 = require('./namedConstants/KnotSequences.cjs');
var KnotIndexStrictlyIncreasingSequence = require('./KnotIndexStrictlyIncreasingSequence.cjs');
var Knots = require('./namedConstants/Knots.cjs');
var adaptParameterRaiseKnotMultiplicity = require('./KnotSequenceAndUtilities/adaptParameterRaiseKnotMultiplicity.cjs');
var adaptParameterInsertKnot = require('./KnotSequenceAndUtilities/adaptParameterInsertKnot.cjs');
var adaptParameterDecrementKnotMultiplicity = require('./KnotSequenceAndUtilities/adaptParameterDecrementKnotMultiplicity.cjs');
class AbstractIncreasingOpenKnotSequence extends AbstractOpenKnotSequence.AbstractOpenKnotSequence {
constructor(maxMultiplicityOrder, knotParameters) {
super(maxMultiplicityOrder, knotParameters);
this._indexKnotOrigin = new KnotIndexStrictlyIncreasingSequence.KnotIndexStrictlyIncreasingSequence(Knots.DEFAULT_KNOT_INDEX);
this._isSequenceUpToC0Discontinuity = false;
if (knotParameters.type === KnotSequenceConstructorInterface.NO_KNOT_OPEN_CURVE) {
this._indexKnotOrigin.knotIndex = 0;
}
else if (knotParameters.type === KnotSequenceConstructorInterface.NO_KNOT_CLOSED_CURVE) {
this._indexKnotOrigin.knotIndex = this._maxMultiplicityOrder - 1;
}
else if (knotParameters.type === KnotSequenceConstructorInterface.UNIFORM_OPENKNOTSEQUENCE) {
this._indexKnotOrigin.knotIndex = this._maxMultiplicityOrder - 1;
}
else if (knotParameters.type === KnotSequenceConstructorInterface.UNIFORMLYSPREADINTERKNOTS_OPENKNOTSEQUENCE) {
this._indexKnotOrigin.knotIndex = 0;
}
else if (knotParameters.type === KnotSequenceConstructorInterface.INCREASINGOPENKNOTSEQUENCE || knotParameters.type === KnotSequenceConstructorInterface.INCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY
|| knotParameters.type === KnotSequenceConstructorInterface.INCREASINGOPENKNOTSEQUENCECLOSEDCURVEALLKNOTS || knotParameters.type === KnotSequenceConstructorInterface.INCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY_CLOSEDCURVEALLKNOTS) {
if (knotParameters.type === KnotSequenceConstructorInterface.INCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY || knotParameters.type === KnotSequenceConstructorInterface.INCREASINGOPENKNOTSEQUENCE_UPTOC0DISCONTINUITY_CLOSEDCURVEALLKNOTS)
this._isSequenceUpToC0Discontinuity = true;
this.generateKnotSequence(knotParameters);
}
}
get allAbscissae() {
const abscissae = [];
for (const knot of this) {
if (knot !== undefined)
abscissae.push(knot);
}
return abscissae;
}
get indexKnotOrigin() {
return this._indexKnotOrigin;
}
get isSequenceUpToC0Discontinuity() {
return this._isSequenceUpToC0Discontinuity;
}
// temporary add setter while constructors of curve are set adequately
set isSequenceUpToC0Discontinuity(isSequenceUpToC0Discontinuity) {
this._isSequenceUpToC0Discontinuity = isSequenceUpToC0Discontinuity;
}
[Symbol.iterator]() {
let nbKnots = 0;
const knotIndicesKnotAbscissaChange = [];
for (const multiplicity of this.multiplicities()) {
nbKnots = nbKnots + multiplicity;
knotIndicesKnotAbscissaChange.push(nbKnots);
}
const lastIndex = nbKnots - 1;
let indexAbscissaChange = 0;
let index = 0;
return {
next: () => {
if (index <= lastIndex) {
if (index === knotIndicesKnotAbscissaChange[indexAbscissaChange]) {
indexAbscissaChange++;
}
index++;
return { value: this.knotSequence[indexAbscissaChange].abscissa, done: false };
}
else {
index = 0;
return { done: true };
}
}
};
}
knotIndexInputParamAssessment(index, methodName) {
if (index.knotIndex > (this.allAbscissae.length - 1)) {
this.throwRangeErrorMessage(methodName, KnotSequences.EM_KNOTINDEX_INC_SEQ_TOO_LARGE);
}
}
updateNormalizedBasisOrigin() {
const normalizedBasisAtStart = this.getKnotIndexNormalizedBasisAtSequenceStart();
let abscissaOrigin = Knots.DEFAULT_KNOT_ABSCISSA_VALUE;
if (normalizedBasisAtStart.basisAtSeqExt === KnotSequences$1.NormalizedBasisAtSequenceExtremity.StrictlyNormalized) {
abscissaOrigin = this.abscissaAtIndex(this.toKnotIndexIncreasingSequence(normalizedBasisAtStart.knot));
}
if (abscissaOrigin !== KnotSequences$1.KNOT_SEQUENCE_ORIGIN)
this.throwRangeErrorMessage("checkNormalizedBasisOrigin", KnotSequences.EM_ORIGIN_NORMALIZEDKNOT_SEQUENCE);
}
generateKnotSequence(knotParameters) {
const minValueMaxMultiplicityOrder = 1;
this.constructorInputMultOrderAssessment(minValueMaxMultiplicityOrder);
this.constructorInputArrayAssessment(knotParameters);
this.checkKnotIncreasingValues(knotParameters.knots);
this.knotSequence.push(new Knot.Knot(knotParameters.knots[0], 1));
for (let i = 1; i < knotParameters.knots.length; i++) {
if (knotParameters.knots[i] === this.knotSequence[this.knotSequence.length - 1].abscissa) {
this.knotSequence[this.knotSequence.length - 1].multiplicity++;
}
else {
this.knotSequence.push(new Knot.Knot(knotParameters.knots[i], 1));
}
}
this.checkMaxMultiplicityOrderConsistency();
this.checkSizeConsistency(knotParameters.knots);
if (!this._isSequenceUpToC0Discontinuity)
this.checkMaxKnotMultiplicityAtIntermediateKnots();
const { start: normalizedBasisAtStart, end: normalizedBasisAtEnd } = this.getKnotIndicesBoundingNormalizedBasis();
if (normalizedBasisAtEnd.basisAtSeqExt === KnotSequences$1.NormalizedBasisAtSequenceExtremity.NotNormalized
|| normalizedBasisAtStart.basisAtSeqExt === KnotSequences$1.NormalizedBasisAtSequenceExtremity.NotNormalized) {
this.throwRangeErrorMessage("generateKnotSequence", KnotSequences.EM_NOT_NORMALIZED_BASIS);
}
else if (normalizedBasisAtEnd.basisAtSeqExt === KnotSequences$1.NormalizedBasisAtSequenceExtremity.StrictlyNormalized) {
this._uMax = this.abscissaAtIndex(this.toKnotIndexIncreasingSequence(normalizedBasisAtEnd.knot));
}
else if (normalizedBasisAtEnd.basisAtSeqExt === KnotSequences$1.NormalizedBasisAtSequenceExtremity.OverDefined) {
this.throwRangeErrorMessage("generateKnotSequence", KnotSequences.EM_CUMULATIVE_KNOTMULTIPLICITY_ATEND);
}
if (normalizedBasisAtStart.basisAtSeqExt === KnotSequences$1.NormalizedBasisAtSequenceExtremity.StrictlyNormalized) {
this._indexKnotOrigin = normalizedBasisAtStart.knot;
}
else if (normalizedBasisAtStart.basisAtSeqExt === KnotSequences$1.NormalizedBasisAtSequenceExtremity.OverDefined) {
this.throwRangeErrorMessage("generateKnotSequence", KnotSequences.EM_CUMULATIVE_KNOTMULTIPLICITY_ATSTART);
}
if (normalizedBasisAtEnd.knot.knotIndex <= normalizedBasisAtStart.knot.knotIndex)
this.throwRangeErrorMessage("generateKnotSequence", KnotSequences.EM_NORMALIZED_BASIS_INTERVAL_NOTSUFFICIENT);
}
checkSizeConsistency(knots) {
let size = 0;
for (const multiplicity of this.multiplicities()) {
size += multiplicity;
}
if (size !== knots.length)
this.throwRangeErrorMessage("checkSizeConsistency", KnotSequences.EM_SIZE_KNOTSEQ_INCOMPATIBLE_SIZE_INTERNAL_STRICTLYINC_KNOTSEQ);
}
length() {
let length = 0;
for (const knot of this) {
if (knot !== undefined)
length++;
}
return length;
}
abscissaAtIndex(index) {
this.knotIndexInputParamAssessment(index, "abscissaAtIndex");
let abscissa = KnotSequences$1.UPPER_BOUND_NORMALIZED_BASIS_DEFAULT_ABSCISSA;
let i = 0;
for (const knot of this) {
if (i === index.knotIndex && knot !== undefined)
abscissa = knot;
i++;
}
return abscissa;
}
extractSubsetOfAbscissae(knotStart, knotEnd) {
let knots = [];
if (!(knotStart.knotIndex >= 0) || !(knotEnd.knotIndex <= this.length() - 1) || !(knotStart.knotIndex <= knotEnd.knotIndex))
this.throwRangeErrorMessage("extractSubsetOfAbscissae", KnotSequences.EM_INDICES_FOR_EXTRACTION_OUTOF_RANGE);
let index = 0;
for (const knot of this) {
if (index >= knotStart.knotIndex && index <= knotEnd.knotIndex) {
if (knot !== undefined)
knots.push(knot);
}
index++;
}
return knots;
}
decrementKnotMultiplicityKnotArrayMutSeq(index, checkSequenceConsistency = true) {
return super.decrementKnotMultiplicityKnotArrayMutSeq(index, checkSequenceConsistency);
}
raiseKnotMultiplicityKnotArrayMutSeq(arrayIndices, multiplicity = 1, checkSequenceConsistency = true) {
return super.raiseKnotMultiplicityKnotArrayMutSeq(arrayIndices, multiplicity, checkSequenceConsistency);
}
insertKnotAbscissaArrayMutSeq(abscissa, multiplicity = 1) {
return super.insertKnotAbscissaArrayMutSeq(abscissa, multiplicity);
}
}
tslib.__decorate([
adaptParameterDecrementKnotMultiplicity.adaptParameterDecrementKnotMultiplicity(),
tslib.__metadata("design:type", Function),
tslib.__metadata("design:paramtypes", [Object, Boolean]),
tslib.__metadata("design:returntype", void 0)
], AbstractIncreasingOpenKnotSequence.prototype, "decrementKnotMultiplicityKnotArrayMutSeq", null);
tslib.__decorate([
adaptParameterRaiseKnotMultiplicity.adaptParameterRaiseKnotMultiplicity(),
tslib.__metadata("design:type", Function),
tslib.__metadata("design:paramtypes", [Object, Number, Boolean]),
tslib.__metadata("design:returntype", void 0)
], AbstractIncreasingOpenKnotSequence.prototype, "raiseKnotMultiplicityKnotArrayMutSeq", null);
tslib.__decorate([
adaptParameterInsertKnot.adaptParameterInsertKnot(),
tslib.__metadata("design:type", Function),
tslib.__metadata("design:paramtypes", [Object, Number]),
tslib.__metadata("design:returntype", void 0)
], AbstractIncreasingOpenKnotSequence.prototype, "insertKnotAbscissaArrayMutSeq", null);
exports.AbstractIncreasingOpenKnotSequence = AbstractIncreasingOpenKnotSequence;