Core 1.0
AnalyticScalarField Class Reference

A core analytic three-dimensional scalar field. More...

#include <scalarfield.h>

Inheritance diagram for AnalyticScalarField:
Algebraic Noise SimplexNoise NoiseTurbulence SimplexTurbulence

Public Member Functions

 AnalyticScalarField (bool=true)
 Constructor.
 
virtual double Value (const Vector &) const
 Compute the value of the field.
 
virtual Vector Gradient (const Vector &) const
 Compute the gradient of the field.
 
Matrix Hessian (const Vector &) const
 Compute the Hessian symmetric matrix of the field function.
 
virtual Vector Normal (const Vector &) const
 Compute the normal to the surface.
 
bool Inside (const double &) const
 Check if the value is considered as inside or outside.
 
virtual Color GetMaterial (const Vector &, const Vector &=Vector::Null) const
 Compute the color.
 
virtual Box GetBox () const
 Compute the bounding box of the scalar field.
 
void Curvature (const Vector &, double &, double &) const
 Compute the gaussian and mean curvatures.
 
Vector Cast (const Vector &, const double &, const double &=1e-6, int n=100) const
 Given a starting vertex x, project it onto the implicit surface following the gradient.
 
Vector Dichotomy (Vector, Vector, double, double, double, const double &=1.0e-4) const
 Compute the intersection between a segment and an implicit surface.
 
virtual bool GetSample (Vector &, const Box &, Random &=Random::R239) const
 Find a point sample on the implicit surface.
 
virtual int GetSamples (QVector< Vector > &, const Box &, int, Random &=Random::R239) const
 Find a set of random sample points on the implicit surface.
 
virtual QVector< VectorPoisson (double, int, Random &=Random::R239) const
 Compute a Poisson sphere distribution on an implicit surface.
 
virtual ScalarField2 Sample (const Rectangles &, int, int) const
 Compute the field function at the vertices a lattice.
 
virtual ScalarField2 Sample (const Quadrangle &, int) const
 Sample the scalar field on a quadrangle.
 
virtual ScalarField Sample (const Box &, int) const
 Sample the implicit surface to get a scalar field.
 
int Roots (const Ray &, const double &, const double &, const double &, double *, int=1, const double &=1.0e-4) const
 Find the intersections between a ray and an implicit surface on a given interval.
 
int Roots (const Ray &, const double &, const double &, const double &, const double &, const double &, double *, int=1, const double &=1.0e-4) const
 This functions searches the intersections between a ray and an implicit surface on a given interval.
 
virtual double K () const
 Compute the Lipschitz constant of the field function.
 
virtual double K (const Box &) const
 Compute the local Lipschitz constant inside a box.
 
virtual double K (const Sphere &) const
 Compute the local Lipschitz constant inside a box.
 
virtual double K (const Segment &) const
 Compute the local Lipschitz constant along a segment.
 
virtual void Polygonize (int, Mesh &, const Box &, const double &=1e-4) const
 Compute the polygonal mesh approximating the implicit surface.
 
virtual void PolygonizeLucie (const Box &, Mesh &, bool, bool) const
 Implementation of the original continuation polygonization method.
 
virtual void PolygonizeLucie (const double &, Mesh &, bool, bool) const
 Wyvill's original marching cubes algorithm.
 
virtual void Dual (int, Mesh &, const Box &) const
 Dual polygonization.
 
virtual bool SphereTrace (const Ray &, const double &, const double &, const double &, double &, int &, const double &=1e-4) const
 Find the first intersection between a ray and an implicit surface on a given interval, using sphere tracing.
 
virtual void Polygonize (const Box &, QVector< Triangle > &, const double &=1e-4, bool=false) const
 Polygonize a cube.
 
virtual void Polygonize (const Tetrahedra &, QVector< Triangle > &, const double &=1e-4) const
 Polygonize a tetrahedral cell.
 
virtual Mesh PolygonizeOctree (const Box &, int, const double &=1e-4) const
 Compute the polygonal mesh approximating the implicit surface using an octree decomposition of space.
 
virtual void Voxelize (const Box &, int, Box &, QVector< Vector > &) const
 Voxelize the scalar field.
 
virtual void Voxelize (int, Voxel &, const Box &) const
 Voxelization.
 
virtual double Volume (int=5) const
 Computes the volume of the BlobTree.
 
virtual double Volume (const Box &, int) const
 Compute the volume of a BlobTree object.
 
virtual double Volume (const Box &, int, double &) const
 Compute the volume of an implicit surface.
 
virtual double StochasticVolume (const Box &, int) const
 Compute the volume of an implicit surface.
 
virtual Sphere Center (int) const
 Computes the gravity center of the BlobTree.
 
virtual Sphere Center (const Box &, int) const
 Compute the center of gravity of the BlobTree.
 
virtual void Colorize (const Mesh &, MeshColor &) const
 Colorize the vertexes of a mesh according to the analytic scalar field.
 

Static Public Member Functions

static int Cubes ()
 Get the number of cubes processed.
 

Protected Member Functions

bool Find (Vector &, bool, const Box &, int=10000, Random &=Random::R239) const
 Find a random sample point inside or outside the surface.
 

Protected Attributes

bool sign = true
 Sign convention, used for normal computation.
 

Static Protected Attributes

static int ncubes = 0
 Number of cubes processed by polygonization algorithms.
 
static const double Epsilon = 1e-6
 Epsilon value for partial derivatives.
 

Detailed Description

A core analytic three-dimensional scalar field.

Constructor & Destructor Documentation

◆ AnalyticScalarField()

AnalyticScalarField::AnalyticScalarField ( bool s = true)
inline

Constructor.

Parameters
sSign, by default set sign convention to true, i.e., negative values inside and positive outside.

Member Function Documentation

◆ Cast()

Vector AnalyticScalarField::Cast ( const Vector & p,
const double & step,
const double & epsilon = 1e-6,
int n = 100 ) const

Given a starting vertex x, project it onto the implicit surface following the gradient.

This function returns a vertex on the implicit surface. It updates a pair of points that are moved so that they straddle the surface, before invoking a bisection step.

Parameters
pStarting vertex.
stepStepping distance.
epsilonPrecision.
nMaximum number of iterations when marching in the direction of the gradient.
Returns
Point on the implicit surface.

◆ Center() [1/2]

Sphere AnalyticScalarField::Center ( const Box & box,
int depth ) const
virtual

Compute the center of gravity of the BlobTree.

Parameters
boxInitial box.
depthRecursion depth.
See also
BlobTree::Center(int)

◆ Center() [2/2]

Sphere AnalyticScalarField::Center ( int depth) const
virtual

Computes the gravity center of the BlobTree.

This function returns a sphere, the center is the center of gravity, and the radius is the volume.

Parameters
depthRecursion depth.

◆ Colorize()

void AnalyticScalarField::Colorize ( const Mesh & m,
MeshColor & c ) const
virtual

Colorize the vertexes of a mesh according to the analytic scalar field.

Parameters
mMesh.
cColored mesh.

◆ Curvature()

void AnalyticScalarField::Curvature ( const Vector & p,
double & gaussian,
double & mean ) const

Compute the gaussian and mean curvatures.

Parameters
pPoint.
gaussianReturned gaussian curvature.
meanReturned mean curvature.

◆ Dichotomy()

Vector AnalyticScalarField::Dichotomy ( Vector a,
Vector b,
double va,
double vb,
double length,
const double & epsilon = 1.0e-4 ) const

Compute the intersection between a segment and an implicit surface.

This method iteratively converges to the solution by performing a bisection on the segment. It avoids the internal computation if the length of the segment if it happens to be known already.

The segment should straddle the implicit surface only once, otherwise should several intersections exist, there is no guarantee that the bissection will converge to an intersection.

Parameters
a,bEnd vertices of the segment straddling the surface.
va,vbField function value at those end vertices.
lengthDistance between vertices.
epsilonPrecision.
Returns
Point on the implicit surface.

◆ Dual()

void AnalyticScalarField::Dual ( int n,
Mesh & g,
const Box & box ) const
virtual

Dual polygonization.

Compute a scalar field with function values sampled at the vertices of the lattice, and invoque the dual scalar field polygonization algorithm.

See also
ScalarField::Dual
Parameters
nSubdivision.
gMesh.
boxThe box.

◆ Find()

bool AnalyticScalarField::Find ( Vector & p,
bool s,
const Box & box,
int n = 10000,
Random & random = Random::R239 ) const
protected

Find a random sample point inside or outside the surface.

Parameters
pReturned point.
sPrescribed position with respect to the surface, true if inside, false if outside.
boxBox domain where the point is to be found.
nMaximum number of random points being evaluated.
randomRandom number generator.
Returns
Return true if a sample has been found, false otherwise.

◆ GetBox()

Box AnalyticScalarField::GetBox ( ) const
virtual

Compute the bounding box of the scalar field.

Simply return Box::Infinity.

Reimplemented in Algebraic.

◆ GetMaterial()

Color AnalyticScalarField::GetMaterial ( const Vector & p,
const Vector & n = Vector::Null ) const
virtual

Compute the color.

Parameters
pPoint.
nNormal at point.
Returns
Color.

◆ GetSample()

bool AnalyticScalarField::GetSample ( Vector & p,
const Box & box,
Random & random = Random::R239 ) const
virtual

Find a point sample on the implicit surface.

Simply find two random points inside and outside of the surface, and perform bisection to converge to the surface.

Parameters
boxSampling box.
pPoint sample on the surface, if succeded in finding one.
randomRandom number generator.

◆ GetSamples()

int AnalyticScalarField::GetSamples ( QVector< Vector > & s,
const Box & box,
int n,
Random & random = Random::R239 ) const
virtual

Find a set of random sample points on the implicit surface.

Simply call AnalyticScalarField::GetSample() several times.

Parameters
boxSampling box.
sSet of sample points.
nNumber of (desired) sampes.
randomRandom number generator.
Returns
The number of samples found on the surface.

◆ Gradient()

Vector AnalyticScalarField::Gradient ( const Vector & p) const
virtual

Compute the gradient of the field.

Parameters
pPoint.

Reimplemented in Algebraic, and Noise.

◆ Hessian()

Matrix AnalyticScalarField::Hessian ( const Vector & p) const

Compute the Hessian symmetric matrix of the field function.

This method uses a numerical approximation of the successive derivatives in each direction.

Parameters
pPoint.
Returns
Hessian matrix.

◆ Inside()

bool AnalyticScalarField::Inside ( const double & v) const
inline

Check if the value is considered as inside or outside.

Result depend on the sign definition of the implicit surface.

Parameters
vValue.

◆ K() [1/4]

double AnalyticScalarField::K ( ) const
virtual

Compute the Lipschitz constant of the field function.

Compute the Lipschitz constant.

By default, return 1.0.

Reimplemented in Algebraic, Noise, NoiseTurbulence, SimplexNoise, and SimplexTurbulence.

◆ K() [2/4]

double AnalyticScalarField::K ( const Box & box) const
virtual

Compute the local Lipschitz constant inside a box.

Parameters
boxBox.

Reimplemented in Algebraic.

◆ K() [3/4]

double AnalyticScalarField::K ( const Segment & segment) const
virtual

Compute the local Lipschitz constant along a segment.

Parameters
segmentThe segment.

◆ K() [4/4]

double AnalyticScalarField::K ( const Sphere & sphere) const
virtual

Compute the local Lipschitz constant inside a box.

Parameters
sphereSphere.

◆ Normal()

Vector AnalyticScalarField::Normal ( const Vector & p) const
virtual

Compute the normal to the surface.

See also
AnalyticScalarField::Gradient(const Vector&) const
Parameters
pPoint (should be on the surface).

◆ Poisson()

QVector< Vector > AnalyticScalarField::Poisson ( double r,
int n,
Random & rng = Random::R239 ) const
virtual

Compute a Poisson sphere distribution on an implicit surface.

This function uses a simple O(n2) dart throwing algorithm.

Parameters
rRadius of the sphere.
nNumber of candidate points.
rngRandom number generator.

◆ Polygonize() [1/3]

void AnalyticScalarField::Polygonize ( const Box & box,
QVector< Triangle > & triangles,
const double & epsilon = 1e-4,
bool tetrahedra = false ) const
virtual

Polygonize a cube.

The algorithm uses either a look-up table disambiguation scheme, or a decomposition into six tetrahedra.

The fundamental problem is to form a facet approximation to an isosurface through a scalar field sampled on a rectangular grid. Given one grid cell defined by its vertices and scalar values at each vertex, it is necessary to create planar facets that best represent the isosurface through that grid cell.

The isosurface may not be pass through the grid cell, it may cut off any one of the vertices, or it may pass through in any one of a number of more complicated ways. Each possibility will be characterised by the number of vertices that have values above or below the isosurface. If one vertex is above the isosurface say and an adjacent vertex is below the isosurface then we know the isosurface cuts the edge between these two vertices.

The position that it cuts the edge will be linearly interpolated, the ratio of the length between the two vertices will be the same as the ratio of the isosurface value to the values at the vertices of the grid cell.

Parameters
boxThe box.
trianglesSet of triangles.
epsilonPrecision.
tetrahedraBoolean specifying whether tetrahedral decomposition should be used.

◆ Polygonize() [2/3]

void AnalyticScalarField::Polygonize ( const Tetrahedra & tetra,
QVector< Triangle > & triangles,
const double & epsilon = 1e-4 ) const
virtual

Polygonize a tetrahedral cell.

Parameters
tetraTetrahedral cell.
trianglesSet of triangles.
epsilonPrecision.

◆ Polygonize() [3/3]

void AnalyticScalarField::Polygonize ( int n,
Mesh & g,
const Box & box,
const double & epsilon = 1e-4 ) const
virtual

Compute the polygonal mesh approximating the implicit surface.

This member function implements the marching cube tesselation algorithm, using a fixed look-up table. This technique does suffer from the ambiguities in the traditional marching cubes algorithms where some special cases result in unexpected holes in the resulting surface.


The first part of the algorithm uses a table (edgeTable) which maps the vertices under the isosurface to the intersecting edges. An 8 bit index is formed where each bit corresponds to a vertex.

Looking up the edge table returns a 12 bit number, each bit corresponding to an edge, 0 if the edge isn't cut by the isosurface, 1 if the edge is cut by the isosurface. If none of the edges are cut the table returns a 0, this occurs when cubeindex is 0 (all vertices below the isosurface) or 0xff (all vertices above the isosurface).

The last part of the algorithm involves forming the correct facets from the positions that the isosurface intersects the edges of the grid cell. Again a table is used which this time uses the same cubeindex but allows the vertex sequence to be looked up for as many triangular facets are necessary to represent the isosurface within the grid cell. There at most 5 triangular facets necessary.

Lets say vertex 0 and 3 are below the isosurface. cubeindex will then be 0000 1001==9. The 9th entry into the egdeTable is 905 = 1001 0000 0101: edges 11, 8, 2, and 0 are cut and so we work out the vertices of the intersection of the isosurface with those edges. Next 9 in the triangle table is 0, 11, 2, 8, 11, 0. This corresponds to 2 triangular facets, one between the intersection of edge 0 11 and 2; the other between the intersections along edges 8, 11, and 0.

Parameters
boxBox defining the region that will be polygonized.
nDiscretization parameter.
gReturned geometry.
epsilonEpsilon value for computing vertices on straddling edges.

◆ PolygonizeLucie() [1/2]

void AnalyticScalarField::PolygonizeLucie ( const Box & box,
Mesh & mesh,
bool dichotomy,
bool computeNormals ) const
virtual

Implementation of the original continuation polygonization method.

Parameters
boxStarting cube straddling the surface.
meshMesh.
dichotomyBoolean for computing vertexes using bisection.
computeNormalsBoolean for computing normals.

The original method is described in: Data structure forsoft objects. Geoff Wyvill, Craig McPheeters, Brian Wyvill. The Visual Computer, 2, 227–234, 1986.

◆ PolygonizeLucie() [2/2]

void AnalyticScalarField::PolygonizeLucie ( const double & size,
Mesh & mesh,
bool dichotomy,
bool computeNormals ) const
virtual

Wyvill's original marching cubes algorithm.

Published one year before Lorensen and Cline sweeping version!

Find a cube straddling the surface, and apply Wyvill's marching algorithm.

Parameters
sizeSize of the cubes that will be straddling the surface.
meshMesh.
dichotomyBoolean for computing vertexes using bisection.
computeNormalsBoolean for computing normals.

◆ PolygonizeOctree()

Mesh AnalyticScalarField::PolygonizeOctree ( const Box & box,
int level,
const double & epsilon = 1e-4 ) const
virtual

Compute the polygonal mesh approximating the implicit surface using an octree decomposition of space.

Parameters
boxBox defining the region that will be polygonized.
levelOctree depth, the corresponding grid subdivision is 2n+1.
epsilonEpsilon value for computing vertices on straddling edges.

◆ Roots() [1/2]

int AnalyticScalarField::Roots ( const Ray & ray,
const double & a,
const double & b,
const double & k,
const double & ya,
const double & yb,
double * x,
int n = 1,
const double & epsilon = 1.0e-4 ) const

This functions searches the intersections between a ray and an implicit surface on a given interval.

The original algorithm recursively isolate the roots by applying the Lipschitz criteria over the interval. It has been rewritten into an iterative form which is more efficient.

Parameters
rayThe ray.
a,bInterval of analysis.
kLipschitz constant.
ya,ybField function values at the end-points of the interval of analysis.
xArray for storing roots.
nSearch for at most n roots.
epsilonPrecision parameter.

◆ Roots() [2/2]

int AnalyticScalarField::Roots ( const Ray & ray,
const double & a,
const double & b,
const double & k,
double * s,
int n = 1,
const double & epsilon = 1.0e-4 ) const

Find the intersections between a ray and an implicit surface on a given interval.

Parameters
rayThe ray.
a,bInterval of analysis.
kLipschitz constant.
sArray for storing roots.
nSearch for n roots at most.
epsilonPrecision parameter.

◆ Sample() [1/3]

ScalarField AnalyticScalarField::Sample ( const Box & box,
int n ) const
virtual

Sample the implicit surface to get a scalar field.

Parameters
nSubdivision.
boxThe box.

◆ Sample() [2/3]

ScalarField2 AnalyticScalarField::Sample ( const Quadrangle & quad,
int n ) const
virtual

Sample the scalar field on a quadrangle.

Returns the 2D scalarfield.

Parameters
quadQuadrangle
ndiscretization

◆ Sample() [3/3]

ScalarField2 AnalyticScalarField::Sample ( const Rectangles & r,
int x,
int y ) const
virtual

Compute the field function at the vertices a lattice.

Parameters
rRectangle.
x,yDiscretization.

◆ SphereTrace()

bool AnalyticScalarField::SphereTrace ( const Ray & ray,
const double & k,
const double & a,
const double & b,
double & t,
int & s,
const double & epsilon = 1e-4 ) const
virtual

Find the first intersection between a ray and an implicit surface on a given interval, using sphere tracing.

Parameters
rayThe ray.
kLipschitz constant.
a,bInterval where intersection is tracked.
tNearest root, if it exists.
sReturn number of steps.
epsilonPrecision on field function values for detecting ray-surface intersection.

Simply march along the ray with variable steps depending on the magnitude of the field function at point samples. Intersection occurs if the absolute value of the field function get lower than epsilon.

◆ StochasticVolume()

double AnalyticScalarField::StochasticVolume ( const Box & box,
int n ) const
virtual

Compute the volume of an implicit surface.

Parameters
boxCube where volume computations will be performed.
nNumber of samples.
See also
BlobTree::Volume(const Box&,int) const

◆ Value()

double AnalyticScalarField::Value ( const Vector & p) const
virtual

Compute the value of the field.

Parameters
pPoint.

Reimplemented in Algebraic, Noise, NoiseTurbulence, SimplexNoise, and SimplexTurbulence.

◆ Volume() [1/3]

double AnalyticScalarField::Volume ( const Box & box,
int depth ) const
virtual

Compute the volume of a BlobTree object.

Parameters
boxCube where volume computations will be performed.
depthRecursion depth.

◆ Volume() [2/3]

double AnalyticScalarField::Volume ( const Box & box,
int depth,
double & e ) const
virtual

Compute the volume of an implicit surface.

Parameters
boxCube where volume computations will be performed.
depthRecursion depth.
eError, i.e., amount of volume that could not be classified as inside or outside.
See also
BlobTree::Volume(const Box&,int) const

◆ Volume() [3/3]

double AnalyticScalarField::Volume ( int depth = 5) const
virtual

Computes the volume of the BlobTree.

Create an octree subdivision of space and check the differents cells of the octree using a Lipschitz criterion to determine whether cells are inside, outside or straddling the object.

Parameters
depthRecursion depth in the creation of the octree.

◆ Voxelize() [1/2]

void AnalyticScalarField::Voxelize ( const Box & box,
int n,
Box & cell,
QVector< Vector > & cubes ) const
virtual

Voxelize the scalar field.

Parameters
boxThe box.
nSubdivision.
cellReturned reference cube.
cubesSet of vectors defining the position of the instantiated reference cube.

◆ Voxelize() [2/2]

void AnalyticScalarField::Voxelize ( int n,
Voxel & voxel,
const Box & box ) const
virtual

Voxelization.

Parameters
nSubdivision.
voxelVoxel.
boxThe box.