Spline3D

Introduction

vtkSpline3D provides methods for creating a 1D cubic spline object from given
parameters, and allows for the calculation of the spline value and derivative
at any given point inside the spline intervals.

Methods

computeCoefficients

Argument Type Required Description
points Yes

extend

Method used to decorate a given object (publicAPI+model) with vtkSpline3D characteristics.

Argument Type Required Description
publicAPI Yes object on which methods will be bounds (public)
model Yes object on which data structure will be bounds (protected)
initialValues ISpline3DInitialValues No (default: {})

getPoint

Argument Type Required Description
intervalIndex Number Yes
t Number Yes

newInstance

Method used to create a new instance of vtkSpline3D.

Argument Type Required Description
initialValues ISpline3DInitialValues No for pre-setting some of its content

Source

Constants.d.ts
export declare enum splineKind {
CARDINAL_SPLINE = 'CARDINAL_SPLINE',
KOCHANEK_SPLINE = 'KOCHANEK_SPLINE',
}

declare const _default: {
splineKind: typeof splineKind;
};
export default _default;
Constants.js
export const splineKind = {
CARDINAL_SPLINE: 'CARDINAL_SPLINE',
KOCHANEK_SPLINE: 'KOCHANEK_SPLINE',
};

export default {
splineKind,
};
index.d.ts
import { vtkObject } from '../../../interfaces';
import { splineKind } from './Constants';

export interface ISpline3DInitialValues {
close?: boolean;
intervals?: any;
kind?: splineKind;
tension?: number;
continuity?: number;
bias?: number;
}

export interface vtkSpline3D extends vtkObject {
/**
*
* @param points
*/
computeCoefficients(points: number[]): void;

/**
*
* @param {Number} intervalIndex
* @param {Number} t
*/
getPoint(intervalIndex: number, t: number): number[];
}

/**
* Method used to decorate a given object (publicAPI+model) with vtkSpline3D characteristics.
*
* @param publicAPI object on which methods will be bounds (public)
* @param model object on which data structure will be bounds (protected)
* @param {ISpline3DInitialValues} [initialValues] (default: {})
*/
export function extend(
publicAPI: object,
model: object,
initialValues?: ISpline3DInitialValues
): void;

/**
* Method used to create a new instance of vtkSpline3D.
* @param {ISpline3DInitialValues} [initialValues] for pre-setting some of its content
*/
export function newInstance(
initialValues?: ISpline3DInitialValues
): vtkSpline3D;

/**
* vtkSpline3D provides methods for creating a 1D cubic spline object from given
* parameters, and allows for the calculation of the spline value and derivative
* at any given point inside the spline intervals.
*/
export declare const vtkSpline3D: {
newInstance: typeof newInstance;
extend: typeof extend;
};
export default vtkSpline3D;
index.js
import macro from 'vtk.js/Sources/macros';
import vtkCardinalSpline1D from 'vtk.js/Sources/Common/DataModel/CardinalSpline1D';
import vtkKochanekSpline1D from 'vtk.js/Sources/Common/DataModel/KochanekSpline1D';

import { splineKind } from 'vtk.js/Sources/Common/DataModel/Spline3D/Constants';

const { vtkErrorMacro } = macro;

// ----------------------------------------------------------------------------
// vtkSpline3D methods
// ----------------------------------------------------------------------------

function vtkSpline3D(publicAPI, model) {
// Set our classname
model.classHierarchy.push('vtkSpline3D');

// --------------------------------------------------------------------------

function computeCoefficients1D(spline, points, boundaryConditionValue) {
if (points.length === 0) {
vtkErrorMacro('Splines require at least one points');
}

// If we have only one point we create a spline
// which two extremities are the same point
if (points.length === 1) {
points.push(points[0]);
}

const size = points.length;

let work = null;
let intervals = null;

work = new Float32Array(size);
if (model.intervals.length === 0) {
intervals = new Float32Array(size);
for (let i = 0; i < intervals.length; i++) {
intervals[i] = i;
}
} else {
intervals = model.intervals;
}

if (model.close) {
spline.computeCloseCoefficients(size, work, intervals, points);
} else {
spline.computeOpenCoefficients(size, work, intervals, points, {
leftConstraint: model.boundaryCondition,
leftValue: boundaryConditionValue,
rightConstraint: model.boundaryCondition,
rightValue: boundaryConditionValue,
});
}
}

// --------------------------------------------------------------------------

publicAPI.computeCoefficients = (points) => {
const x = points.map((pt) => pt[0]);
const y = points.map((pt) => pt[1]);
const z = points.map((pt) => pt[2]);

computeCoefficients1D(model.splineX, x, model.boundaryConditionValues[0]);
computeCoefficients1D(model.splineY, y, model.boundaryConditionValues[1]);
computeCoefficients1D(model.splineZ, z, model.boundaryConditionValues[2]);
};

// --------------------------------------------------------------------------

publicAPI.getPoint = (intervalIndex, t) => [
model.splineX.getValue(intervalIndex, t),
model.splineY.getValue(intervalIndex, t),
model.splineZ.getValue(intervalIndex, t),
];

// --------------------------------------------------------------------------
// initialization
// --------------------------------------------------------------------------

if (model.kind === splineKind.KOCHANEK_SPLINE) {
model.splineX = vtkKochanekSpline1D.newInstance({
tension: model.tension,
continuity: model.continuity,
bias: model.bias,
});
model.splineY = vtkKochanekSpline1D.newInstance({
tension: model.tension,
continuity: model.continuity,
bias: model.bias,
});
model.splineZ = vtkKochanekSpline1D.newInstance({
tension: model.tension,
continuity: model.continuity,
bias: model.bias,
});
} else if (model.kind === splineKind.CARDINAL_SPLINE) {
model.splineX = vtkCardinalSpline1D.newInstance();
model.splineY = vtkCardinalSpline1D.newInstance();
model.splineZ = vtkCardinalSpline1D.newInstance();
} else {
vtkErrorMacro(`Unknown spline type ${model.kind}`);
}
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
close: false,
intervals: [],
kind: splineKind.KOCHANEK_SPLINE,
boundaryConditionValues: [0, 0, 0],

// Passed to the vtkKochanekSpline1D
tension: 0,
continuity: 0,
bias: 0,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);

// Build VTK API
macro.obj(publicAPI, model);
macro.setGet(publicAPI, model, ['close', 'intervals']);
vtkSpline3D(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkSpline3D');

// ----------------------------------------------------------------------------

export default { newInstance, extend };