KochanekSpline1D

Introduction

vtkKochanekSpline1D provides methods for creating a Kochanek interpolating
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

computeCloseCoefficients

Argument Type Required Description
size Number Yes
work Float32Array Yes
x Array. Yes
y Array. Yes

computeOpenCoefficients

Argument Type Required Description
size Number Yes
work Float32Array Yes
x Array. Yes
y Array. Yes

extend

Method used to decorate a given object (publicAPI+model) with vtkKochanekSpline1D 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 IKochanekSpline1DInitialValues No (default: {})

getValue

Argument Type Required Description
intervalIndex Number Yes
t Number Yes

newInstance

Method used to create a new instance of vtkKochanekSpline1D.

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

Source

index.d.ts
import vtkSpline1D from '../Spline1D';


interface IKochanekSpline1DInitialValues {
tension?: number;
bias?: number;
continuity?: number;
}

export interface vtkKochanekSpline1D extends vtkSpline1D {

/**
*
* @param {Number} size
* @param {Float32Array} work
* @param {Number[]} x
* @param {Number[]} y
*/
computeCloseCoefficients(size: number, work: Float32Array, x: number[], y: number[]): void;

/**
*
* @param {Number} size
* @param {Float32Array} work
* @param {Number[]} x
* @param {Number[]} y
*/
computeOpenCoefficients(size: number, work: Float32Array, x: number[], y: number[]): void;

/**
*
* @param {Number} intervalIndex
* @param {Number} t
*/
getValue(intervalIndex: number, t: number): number;
}

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

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

/**
* vtkKochanekSpline1D provides methods for creating a Kochanek interpolating
* 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 vtkKochanekSpline1D: {
newInstance: typeof newInstance,
extend: typeof extend
};
export default vtkKochanekSpline1D;
index.js
import macro from 'vtk.js/Sources/macros';
import vtkSpline1D from 'vtk.js/Sources/Common/DataModel/Spline1D';

const { vtkErrorMacro } = macro;

// ----------------------------------------------------------------------------
// vtkKochanekSpline1D methods
// ----------------------------------------------------------------------------

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

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

publicAPI.computeCloseCoefficients = (size, work, x, y) => {
if (!model.coefficients || model.coefficients.length !== 4 * size) {
model.coefficients = new Float32Array(4 * size);
}
const N = size - 1;

for (let i = 1; i < N; i++) {
const cs = y[i] - y[i - 1];
const cd = y[i + 1] - y[i];

let ds =
cs * ((1 - model.tension) * (1 - model.continuity) * (1 + model.bias)) +
cd * ((1 - model.tension) * (1 + model.continuity) * (1 - model.bias));

let dd =
cs * ((1 - model.tension) * (1 + model.continuity) * (1 + model.bias)) +
cd * ((1 - model.tension) * (1 - model.continuity) * (1 - model.bias));

// adjust deriviatives for non uniform spacing between nodes
const n1 = x[i + 1] - x[i];
const n0 = x[i] - x[i - 1];

ds *= n0 / (n0 + n1);
dd *= n1 / (n0 + n1);

model.coefficients[4 * i + 0] = y[i];
model.coefficients[4 * i + 1] = dd;
model.coefficients[4 * i + 2] = ds;
}

// Calculate the deriviatives at the end points
model.coefficients[4 * 0 + 0] = y[0];
model.coefficients[4 * N + 0] = y[N];
model.coefficients[4 * N + 1] = 0;
model.coefficients[4 * N + 2] = 0;
model.coefficients[4 * N + 3] = 0;

// The curve is continuous and closed at P0=Pn
const cs = y[N] - y[N - 1];
const cd = y[1] - y[0];

let ds =
cs * ((1 - model.tension) * (1 - model.continuity) * (1 + model.bias)) +
cd * ((1 - model.tension) * (1 + model.continuity) * (1 - model.bias));

let dd =
cs * ((1 - model.tension) * (1 + model.continuity) * (1 + model.bias)) +
cd * ((1 - model.tension) * (1 - model.continuity) * (1 - model.bias));

// adjust deriviatives for non uniform spacing between nodes
const n1 = x[1] - x[0];
const n0 = x[N] - x[N - 1];

ds *= n0 / (n0 + n1);
dd *= n1 / (n0 + n1);

model.coefficients[4 * 0 + 1] = dd;
model.coefficients[4 * 0 + 2] = ds;
model.coefficients[4 * N + 1] = dd;
model.coefficients[4 * N + 2] = ds;

for (let i = 0; i < N; i++) {
//
// c0 = P ; c1 = DD ;
// i i i i
//
// c1 = P ; c2 = DS ;
// i+1 i+1 i+1 i+1
//
// c2 = -3P + 3P - 2DD - DS ;
// i i i+1 i i+1
//
// c3 = 2P - 2P + DD + DS ;
// i i i+1 i i+1
//
model.coefficients[4 * i + 2] =
-3 * y[i] +
3 * y[i + 1] +
-2 * model.coefficients[4 * i + 1] +
-1 * model.coefficients[4 * (i + 1) + 2];
model.coefficients[4 * i + 3] =
2 * y[i] +
-2 * y[i + 1] +
1 * model.coefficients[4 * i + 1] +
1 * model.coefficients[4 * (i + 1) + 2];
}
};

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

publicAPI.computeOpenCoefficients = (size, work, x, y) => {
vtkErrorMacro('Open splines are not implemented yet!');
};

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

publicAPI.getValue = (intervalIndex, t) => {
const t2 = t * t;
const t3 = t * t * t;

return (
model.coefficients[4 * intervalIndex + 3] * t3 +
model.coefficients[4 * intervalIndex + 2] * t2 +
model.coefficients[4 * intervalIndex + 1] * t +
model.coefficients[4 * intervalIndex + 0]
);
};
}

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

const DEFAULT_VALUES = {
tension: 0,
bias: 0,
continuity: 0,
};

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

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

vtkSpline1D.extend(publicAPI, model, initialValues);

// Build VTK API
macro.obj(publicAPI, model);
vtkKochanekSpline1D(publicAPI, model);
}

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

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

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

export default { newInstance, extend };