UNPKG

@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
'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;