iOS & macOS Charting Documentation - SciChart iOS & macOS Charts SDK v4.x

The Free Surface 3D Chart Type

The Free Surface 3D Chart types are a set of 3D Charts that represent the data by plotting the surface in a custom shape in 3D space.

It’s represented by the SCIFreeSurfaceRenderableSeries3D in SciChart, and can be configured with different SCIFreeSurfaceDataSeries3D.

The Free Surface 3D Chart Types can be divided into a two groups:

You can find more information about individual Free Surface types in the corresponding sections of this article.

Free Surface 3D Collage

Constrained Free Surface 3D Types

Each of constrained chart type represents its basic primitive. There is a 3 constrained free-surface types available out of the box in SciChart: a sphere, a cylinder, or a disk.

The Surface of such charts can be modified by the 2D offset array. Each particular type of the constrained 3D chart specifies how the surface can be offset:

  • The Ellipsoid Chart - offsets its points on the surface in each of XYZ axes proportionality, based on the location of its origin.
  • The Cylindroid Chart - offsets the surface in XZ axes, based on its Y-axis aligned origin line.
  • The Polar 3D Chart - offsets its surface in Y-axis, based on XZ axes origin plane.

Unconstrained Free Surface 3D Type

In contrast to the constrained chart types, The Custom Free Surface 3D Chart isn’t based on any geometric primitive. The shape of its surface is defined by a set of user-defined functions, injected in the constructor during the instantiation. This approach allows the surface to obtain any possible shape.

Configuring Free Surface 3D Series

Most of the configuration options follow the same approach as it is in The SurfaceMesh 3D Chart Type so all of the following are also applicable to Free Surface Meshes:

Despite the similarity of configuration to other 3D charts, Free Surface 3D Charts have some unique options. One of them is the Palette Mode, determining which color is picked from the Palette based on its four components:

Each of components can be used separately or blended together, based on values of corresponding Factor properties. Below is the formula that determines the color of the Palette:

Free Surface Palette Formula

All of the components are 0 by default, except Radial which is equal to 1.

To learn more about each of the component - read on the following section of this article.

The Axial Palette Component

In this mode, palette color is determined by the position of a particular point on the surface that linearly interpolates between the user-specified minimum and maximum values. The axial component is controlled by the SCIFreeSurfaceRenderableSeries3D.paletteAxialFactor vector.

The weight of the Axial Palette Component is calculated by following formula:

Free Surface Axial Palette Formula

See how it works in the code below:

unsigned int colors[7] = { 0xFF00008B, 0xFF0000FF, 0xFF00FFFF, 0xFFADFF2F, 0xFFFFFF00, 0xFFFF0000, 0xFF8B0000 }; float stops[7] = { 0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0}; SCIGradientColorPalette *palette = [[SCIGradientColorPalette alloc] initWithColors:colors stops:stops count:7]; SCIFreeSurfaceRenderableSeries3D *rSeries = [SCIFreeSurfaceRenderableSeries3D new]; rSeries.meshColorPalette = palette; rSeries.paletteMinMaxMode = SCIFreeSurfacePaletteMinMaxMode_Absolute; rSeries.paletteMinimum = [[SCIVector3 alloc] initWithX:0.0 y:-4.0 z:0.0]; rSeries.paletteMaximum = [[SCIVector3 alloc] initWithX:0.0 y:4.0 z:0.0]; rSeries.paletteAxialFactor = [[SCIVector3 alloc] initWithX:0.0 y:1.0 z:0.0];
let colors: [UInt32] = [0xFF1D2C6B, 0xFF0000FF, 0xFF00FFFF, 0xFFADFF2F, 0xFFFFFF00, 0xFFFF0000, 0xFF8B0000] let stops: [Float] = [0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0] let palette = SCIGradientColorPalette(colors: colors, stops: stops, count: 7) let rSeries = SCIFreeSurfaceRenderableSeries3D() rSeries.meshColorPalette = palette rSeries.paletteMinMaxMode = .absolute rSeries.paletteMinimum = SCIVector3(x: 0.0, y: -4.0, z: 0.0) rSeries.paletteMaximum = SCIVector3(x: 0.0, y: 4.0, z: 0.0) rSeries.paletteAxialFactor = SCIVector3(x: 0.0, y: 1.0, z: 0.0)
var palette = new SCIGradientColorPalette( new[] { ColorUtil.Sapphire, ColorUtil.Blue, ColorUtil.Cyan, ColorUtil.GreenYellow, ColorUtil.Yellow, ColorUtil.Red, ColorUtil.DarkRed }, new[] { 0, .1f, .3f, .5f, .7f, .9f, 1 }); var rSeries = new SCIFreeSurfaceRenderableSeries3D(); rSeries.MeshColorPalette = palette; rSeries.PaletteMinMaxMode = SCIFreeSurfacePaletteMinMaxMode.Absolute; rSeries.PaletteMinimum = new SCIVector3(0.0f, -4.0f, 0.0f); rSeries.PaletteMaximum = new SCIVector3(0.0f, 4.0f, 0.0f); rSeries.PaletteAxialFactor = new SCIVector3(0.0f, 1.0f, 0.0f);

Free Surface Axial Palette

The Radial Palette Component

The Radial component is controlled by the SCIFreeSurfaceRenderableSeries3D.paletteRadialFactor property. It is quite simple, similar to the 2d heatmaps, see the example below:

unsigned int colors[7] = { 0xFF00008B, 0xFF0000FF, 0xFF00FFFF, 0xFFADFF2F, 0xFFFFFF00, 0xFFFF0000, 0xFF8B0000 }; float stops[7] = { 0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0}; SCIGradientColorPalette *palette = [[SCIGradientColorPalette alloc] initWithColors:colors stops:stops count:7]; SCIFreeSurfaceRenderableSeries3D *rSeries = [SCIFreeSurfaceRenderableSeries3D new]; rSeries.meshColorPalette = palette; rSeries.paletteMinMaxMode = SCIFreeSurfacePaletteMinMaxMode_Relative; rSeries.paletteMinimum = [[SCIVector3 alloc] initWithX:0.0 y:6.0 z:0.0]; rSeries.paletteMaximum = [[SCIVector3 alloc] initWithX:0.0 y:7.0 z:0.0]; rSeries.paletteRadialFactor = 1;
let colors: [UInt32] = [0xFF1D2C6B, 0xFF0000FF, 0xFF00FFFF, 0xFFADFF2F, 0xFFFFFF00, 0xFFFF0000, 0xFF8B0000] let stops: [Float] = [0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0] let palette = SCIGradientColorPalette(colors: colors, stops: stops, count: 7) let rSeries = SCIFreeSurfaceRenderableSeries3D() rSeries.meshColorPalette = palette rSeries.paletteMinMaxMode = .relative rSeries.paletteMinimum = SCIVector3(x: 0.0, y: 6.0, z: 0.0) rSeries.paletteMaximum = SCIVector3(x: 0.0, y: 7.0, z: 0.0) rSeries.paletteRadialFactor = 1
var palette = new SCIGradientColorPalette( new[] { ColorUtil.Sapphire, ColorUtil.Blue, ColorUtil.Cyan, ColorUtil.GreenYellow, ColorUtil.Yellow, ColorUtil.Red, ColorUtil.DarkRed }, new[] { 0, .1f, .3f, .5f, .7f, .9f, 1 }); var rSeries = new SCIFreeSurfaceRenderableSeries3D(); rSeries.MeshColorPalette = palette; rSeries.PaletteMinMaxMode = SCIFreeSurfacePaletteMinMaxMode.Relative; rSeries.PaletteMinimum = new SCIVector3(0.0f, 6.0f, 0.0f); rSeries.PaletteMaximum = new SCIVector3(0.0f, 7.0f, 0.0f); rSeries.PaletteRadialFactor = 1;

Free Surface Radial Palette

The Azimuthal Palette Component

In this mode palette color is determined by cos angle between the unit vector of the X-Axis and vector from the origin point to the particular point on the surface, projected onto the XZ plane. The azimuthal component is controlled by the SCIFreeSurfaceRenderableSeries3D.paletteAzimuthalFactor property.

The weight of the Azimuthal Palette Component is calculated by the following formula:

Free Surface Azimuthal Palette Formula

  • X - is the unit vector of the X-Axis;
  • Pxz - is a particular point on the surface, projected onto the XZ plane;

See how it works in the code below:

unsigned int colors[7] = { 0xFF00008B, 0xFF0000FF, 0xFF00FFFF, 0xFFADFF2F, 0xFFFFFF00, 0xFFFF0000, 0xFF8B0000 }; float stops[7] = { 0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0}; SCIGradientColorPalette *palette = [[SCIGradientColorPalette alloc] initWithColors:colors stops:stops count:7]; SCIFreeSurfaceRenderableSeries3D *rSeries = [SCIFreeSurfaceRenderableSeries3D new]; rSeries.meshColorPalette = palette; rSeries.paletteMinMaxMode = SCIFreeSurfacePaletteMinMaxMode_Relative; rSeries.paletteAzimuthalFactor = 1;
let colors: [UInt32] = [0xFF1D2C6B, 0xFF0000FF, 0xFF00FFFF, 0xFFADFF2F, 0xFFFFFF00, 0xFFFF0000, 0xFF8B0000] let stops: [Float] = [0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0] let palette = SCIGradientColorPalette(colors: colors, stops: stops, count: 7) let rSeries = SCIFreeSurfaceRenderableSeries3D() rSeries.meshColorPalette = palette rSeries.paletteMinMaxMode = .relative rSeries.paletteAzimuthalFactor = 1
var palette = new SCIGradientColorPalette( new[] { ColorUtil.Sapphire, ColorUtil.Blue, ColorUtil.Cyan, ColorUtil.GreenYellow, ColorUtil.Yellow, ColorUtil.Red, ColorUtil.DarkRed }, new[] { 0, .1f, .3f, .5f, .7f, .9f, 1 }); var rSeries = new SCIFreeSurfaceRenderableSeries3D(); rSeries.MeshColorPalette = palette; rSeries.PaletteMinMaxMode = SCIFreeSurfacePaletteMinMaxMode.Relative; rSeries.PaletteAzimuthalFactor = 1;

Free Surface Azimuthal Palette

The Polar Palette Component

In this mode, palette color is determined by cos angle between the unit vector of the Y-Axis and vector from the origin point to the particular point on the surface. The polar component is controlled by the SCIFreeSurfaceRenderableSeries3D.palettePolarFactor property.

The weight of the Polar Palette Component is calculated by following formula:

Free Surface Polar Palette Formula

  • Y - is the unit vector of the Y-Axis;
  • P - is a particular point on the surface.

See how it works in the code below:

unsigned int colors[7] = { 0xFF00008B, 0xFF0000FF, 0xFF00FFFF, 0xFFADFF2F, 0xFFFFFF00, 0xFFFF0000, 0xFF8B0000 }; float stops[7] = { 0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0}; SCIGradientColorPalette *palette = [[SCIGradientColorPalette alloc] initWithColors:colors stops:stops count:7]; SCIFreeSurfaceRenderableSeries3D *rSeries = [SCIFreeSurfaceRenderableSeries3D new]; rSeries.meshColorPalette = palette; rSeries.paletteMinMaxMode = SCIFreeSurfacePaletteMinMaxMode_Relative; rSeries.palettePolarFactor = 1;
let colors: [UInt32] = [0xFF1D2C6B, 0xFF0000FF, 0xFF00FFFF, 0xFFADFF2F, 0xFFFFFF00, 0xFFFF0000, 0xFF8B0000] let stops: [Float] = [0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0] let palette = SCIGradientColorPalette(colors: colors, stops: stops, count: 7) let rSeries = SCIFreeSurfaceRenderableSeries3D() rSeries.meshColorPalette = palette rSeries.paletteMinMaxMode = .relative rSeries.palettePolarFactor = 1
var palette = new SCIGradientColorPalette( new[] { ColorUtil.Sapphire, ColorUtil.Blue, ColorUtil.Cyan, ColorUtil.GreenYellow, ColorUtil.Yellow, ColorUtil.Red, ColorUtil.DarkRed }, new[] { 0, .1f, .3f, .5f, .7f, .9f, 1 }); var rSeries = new SCIFreeSurfaceRenderableSeries3D(); rSeries.MeshColorPalette = palette; rSeries.PaletteMinMaxMode = SCIFreeSurfacePaletteMinMaxMode.Relative; rSeries.PalettePolarFactor = 1;

Free Surface Polar Palette