EllipseArcSource

Introduction

vtkEllipseArcSource is a source object that creates an elliptical arc defined
by a normal, a center and the major radius vector. You can define an angle to
draw only a section of the ellipse. The number of segments composing the
polyline is controlled by setting the object resolution.

Usage

import vtkEllipseArcSource from '@kitware/vtk.js/Filters/Sources/EllipseArcSource';

const arc = vtkEllipseArcSource.newInstance();
const polydata = arc.getOutputData();

Methods

extend

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

getCenter

Get the center of the arc.

getCenterByReference

Get the center of the arc by reference.

getClose

Get whether the arc is closed.

getMajorRadiusVector

Get the major radius vector of the arc.

getMajorRadiusVectorByReference

Get the major radius vector of the arc by reference.

getNormal

Get the normal vector of the arc.

getNormalByReference

Get the normal vector of the arc by reference.

getOutputPointsPrecision

Get the output points precision.

getRatio

Get the ratio of the arc.

getResolution

Get the resolution of the arc.

getSegmentAngle

Get the segment angle of the arc.

getStartAngle

Get the start angle of the arc.

newInstance

Method used to create a new instance of vtkEllipseArcSource.

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

requestData

Argument Type Required Description
inData Yes
outData Yes

setCenter

Set the center of the arc.

Argument Type Required Description
center Vector3 Yes The center’s coordinates.

setCenterFrom

Set the center of the arc by reference.

Argument Type Required Description
center Vector3 Yes The center’s coordinates.

setClose

Set whether the arc is closed.

Argument Type Required Description
close Boolean Yes Whether the arc is closed.

setMajorRadiusVector

Set the major radius vector of the arc.

Argument Type Required Description
majorRadiusVector Vector3 Yes The major radius vector’s coordinates.

setMajorRadiusVectorFrom

Set the major radius vector of the arc by reference.

Argument Type Required Description
majorRadiusVector Vector3 Yes The major radius vector’s coordinates.

setNormal

Set the normal vector of the arc.

Argument Type Required Description
normal Vector3 Yes The normal vector’s coordinates.

setNormalFrom

Set the normal vector of the arc by reference.

Argument Type Required Description
normal Vector3 Yes The normal vector’s coordinates.

setOutputPointsPrecision

Set the output points precision.

Argument Type Required Description
precision DesiredOutputPrecision Yes The desired output precision.

setRatio

Set the ratio of the arc.

Argument Type Required Description
ratio Number Yes The ratio of the arc.

setResolution

Set the resolution of the arc.

Argument Type Required Description
resolution Number Yes The number of points in the arc.

setSegmentAngle

Set the segment angle of the arc.

Argument Type Required Description
segmentAngle Number Yes The segment angle in degrees.

setStartAngle

Set the start angle of the arc.

Argument Type Required Description
startAngle Number Yes The start angle in degrees.

Source

index.d.ts
import { DesiredOutputPrecision } from '../../../Common/DataModel/DataSetAttributes';
import { vtkAlgorithm, vtkObject } from '../../../interfaces';
import { Vector3 } from '../../../types';

/**
*
*/
export interface IEllipseArcSourceInitialValues {
center?: Vector3;
normal?: Vector3;
majorRadiusVector?: Vector3;
startAngle?: number;
segmentAngle?: number;
resolution?: number;
close?: boolean;
outputPointsPrecision?: DesiredOutputPrecision;
ratio?: number;
}

type vtkEllipseArcSourceBase = vtkObject &
Omit<
vtkAlgorithm,
| 'getInputData'
| 'setInputData'
| 'setInputConnection'
| 'getInputConnection'
| 'addInputConnection'
| 'addInputData'
>;

export interface vtkEllipseArcSource extends vtkEllipseArcSourceBase {
/**
* Get whether the arc is closed.
*/
getClose(): boolean;

/**
* Get the center of the arc.
*/
getCenter(): Vector3;

/**
* Get the center of the arc by reference.
*/
getCenterByReference(): Vector3;

/**
* Get the major radius vector of the arc.
*/
getMajorRadiusVector(): Vector3;

/**
* Get the major radius vector of the arc by reference.
*/
getMajorRadiusVectorByReference(): Vector3;

/**
* Get the normal vector of the arc.
*/
getNormal(): Vector3;

/**
* Get the normal vector of the arc by reference.
*/
getNormalByReference(): Vector3;

/**
* Get the output points precision.
*/
getOutputPointsPrecision(): DesiredOutputPrecision;

/**
* Get the ratio of the arc.
*/
getRatio(): number;

/**
* Get the resolution of the arc.
*/
getResolution(): number;

/**
* Get the segment angle of the arc.
*/
getSegmentAngle(): number;

/**
* Get the start angle of the arc.
*/
getStartAngle(): number;

/**
*
* @param inData
* @param outData
*/
requestData(inData: any, outData: any): void;

/**
* Set whether the arc is closed.
* @param {Boolean} close Whether the arc is closed.
*/
setClose(close: boolean): boolean;

/**
* Set the center of the arc.
* @param {Vector3} center The center's coordinates.
*/
setCenter(center: Vector3): boolean;

/**
* Set the center of the arc by reference.
* @param {Vector3} center The center's coordinates.
*/
setCenterFrom(center: Vector3): boolean;

/**
* Set the major radius vector of the arc.
* @param {Vector3} majorRadiusVector The major radius vector's coordinates.
*/
setMajorRadiusVector(majorRadiusVector: Vector3): boolean;

/**
* Set the major radius vector of the arc by reference.
* @param {Vector3} majorRadiusVector The major radius vector's coordinates.
*/
setMajorRadiusVectorFrom(majorRadiusVector: Vector3): boolean;

/**
* Set the normal vector of the arc.
* @param {Vector3} normal The normal vector's coordinates.
*/
setNormal(normal: Vector3): boolean;

/**
* Set the normal vector of the arc by reference.
* @param {Vector3} normal The normal vector's coordinates.
*/
setNormalFrom(normal: Vector3): boolean;

/**
* Set the output points precision.
* @param {DesiredOutputPrecision} precision The desired output precision.
*/
setOutputPointsPrecision(precision: DesiredOutputPrecision): boolean;

/**
* Set the ratio of the arc.
* @param {Number} ratio The ratio of the arc.
*/
setRatio(ratio: number): boolean;

/**
* Set the resolution of the arc.
* @param {Number} resolution The number of points in the arc.
*/
setResolution(resolution: number): boolean;

/**
* Set the segment angle of the arc.
* @param {Number} segmentAngle The segment angle in degrees.
*/
setSegmentAngle(segmentAngle: number): boolean;

/**
* Set the start angle of the arc.
* @param {Number} startAngle The start angle in degrees.
*/
setStartAngle(startAngle: number): boolean;
}

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

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

/**
* vtkEllipseArcSource is a source object that creates an elliptical arc defined
* by a normal, a center and the major radius vector. You can define an angle to
* draw only a section of the ellipse. The number of segments composing the
* polyline is controlled by setting the object resolution.
*
* @example
* ```js
* import vtkEllipseArcSource from '@kitware/vtk.js/Filters/Sources/EllipseArcSource';
*
* const arc = vtkEllipseArcSource.newInstance();
* const polydata = arc.getOutputData();
* ```
*/
export declare const vtkEllipseArcSource: {
newInstance: typeof newInstance;
extend: typeof extend;
};
export default vtkEllipseArcSource;
index.js
import macro from 'vtk.js/Sources/macros';
import vtkCellArray from 'vtk.js/Sources/Common/Core/CellArray';
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
import vtkMath from 'vtk.js/Sources/Common/Core/Math';
import vtkPoints from 'vtk.js/Sources/Common/Core/Points';
import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData';
import { DesiredOutputPrecision } from 'vtk.js/Sources/Common/DataModel/DataSetAttributes/Constants';

const { vtkErrorMacro } = macro;
const { VtkDataTypes } = vtkDataArray;

// ----------------------------------------------------------------------------
// vtkEllipseArcSource methods
// ----------------------------------------------------------------------------

function vtkEllipseArcSource(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkEllipseArcSource');

publicAPI.requestData = (inData, outData) => {
const isClosedShape = Math.abs(model.segmentAngle - 360.0) < 1e-5;
const resolution =
model.close && !isClosedShape ? model.resolution + 1 : model.resolution;

const numLines = resolution;
const numPts = resolution + 1;
const tc = [0.0, 0.0];

const output = outData[0]?.initialize() || vtkPolyData.newInstance();

// Make sure the normal vector is normalized
const normal = [...model.normal];
vtkMath.normalize(normal);

// Get orthogonal vector between user-defined major radius and normal
const orthogonalVect = [0, 0, 0];
vtkMath.cross(normal, model.majorRadiusVector, orthogonalVect);

if (vtkMath.norm(orthogonalVect) < 1e-10) {
vtkErrorMacro(
'Ellipse normal vector and major radius axis are collinear'
);
return;
}

vtkMath.normalize(orthogonalVect);

const majorRadiusVect = [0, 0, 0];
vtkMath.cross(orthogonalVect, normal, majorRadiusVect);
vtkMath.normalize(majorRadiusVect);

const a = vtkMath.norm(model.majorRadiusVector);
const b = a * model.ratio;

let startAngleRad = vtkMath.radiansFromDegrees(model.startAngle);
if (startAngleRad < 0) {
startAngleRad += 2.0 * Math.PI;
}

const segmentAngleRad = vtkMath.radiansFromDegrees(model.segmentAngle);

const angleIncRad = segmentAngleRad / model.resolution;

let pointType = VtkDataTypes.FLOAT;
if (model.outputPointsPrecision === DesiredOutputPrecision.SINGLE) {
pointType = VtkDataTypes.FLOAT;
} else if (model.outputPointsPrecision === DesiredOutputPrecision.DOUBLE) {
pointType = VtkDataTypes.DOUBLE;
}

const points = vtkPoints.newInstance({
dataType: pointType,
});
points.setNumberOfPoints(numPts);

const tcoords = vtkDataArray.newInstance({
numberOfComponents: 2,
size: numPts * 2,
dataType: VtkDataTypes.FLOAT,
name: 'TextureCoordinates',
});

const lines = vtkCellArray.newInstance();
lines.allocate(numLines);

const skipLastPoint = model.close && isClosedShape;

let theta = startAngleRad;
let pointIndex = 0;

for (let i = 0; i <= resolution; ++i, theta += angleIncRad) {
const quotient = Math.floor(theta / (2.0 * Math.PI));
const normalizedTheta = theta - quotient * 2.0 * Math.PI;

let thetaEllipse = Math.atan(Math.tan(normalizedTheta) * model.ratio);

if (normalizedTheta > Math.PI / 2 && normalizedTheta <= Math.PI) {
thetaEllipse += Math.PI;
} else if (
normalizedTheta > Math.PI &&
normalizedTheta <= 1.5 * Math.PI
) {
thetaEllipse -= Math.PI;
}

const cosTheta = Math.cos(thetaEllipse);
const sinTheta = Math.sin(thetaEllipse);

const p = [
model.center[0] +
a * cosTheta * majorRadiusVect[0] +
b * sinTheta * orthogonalVect[0],
model.center[1] +
a * cosTheta * majorRadiusVect[1] +
b * sinTheta * orthogonalVect[1],
model.center[2] +
a * cosTheta * majorRadiusVect[2] +
b * sinTheta * orthogonalVect[2],
];

tc[0] = i / resolution;
tc[1] = 0.0;

if (i !== resolution || !skipLastPoint) {
points.setPoint(pointIndex, ...p);
tcoords.setTuple(pointIndex, tc);
pointIndex++;
}
}

const actualNumPts = pointIndex;
const pointIds = [];

for (let k = 0; k < actualNumPts - 1; ++k) {
pointIds.push(k);
}

if (model.close) {
pointIds.push(0);
} else {
pointIds.push(actualNumPts - 1);
}

lines.insertNextCell(pointIds);

output.setPoints(points);
output.getPointData().setTCoords(tcoords);
output.setLines(lines);

outData[0] = output;
};
}

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

const DEFAULT_VALUES = {
center: [0.0, 0.0, 0.0],
normal: [0.0, 0.0, 1.0],
majorRadiusVector: [1.0, 0.0, 0.0],
startAngle: 0.0,
segmentAngle: 90.0,
resolution: 100,
close: false,
outputPointsPrecision: DesiredOutputPrecision.SINGLE,
ratio: 1.0,
};

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

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

// Ensure resolution is at least 1
if (model.resolution < 1) {
model.resolution = 1;
}

// Build VTK API
macro.obj(publicAPI, model);
macro.algo(publicAPI, model, 0, 1);

macro.setGet(publicAPI, model, [
'resolution',
'startAngle',
'segmentAngle',
'close',
'outputPointsPrecision',
'ratio',
]);

macro.setGetArray(
publicAPI,
model,
['center', 'normal', 'majorRadiusVector'],
3
);

vtkEllipseArcSource(publicAPI, model);
}

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

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

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

export default { newInstance, extend };