Core 1.0
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
AnalyticScalarField Class Reference

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

#include <scalarfield.h>

Inheritance diagram for AnalyticScalarField:
Algebraic

Public Member Functions

 AnalyticScalarField (bool=true)
 Constructor. More...
 
virtual double Value (const Vector &) const
 Compute the value of the field. More...
 
virtual Vector Gradient (const Vector &) const
 Compute the gradient of the field. More...
 
Matrix Hessian (const Vector &) const
 Compute the Hessian symmetric matrix of the field function. More...
 
virtual Color GetMaterial (const Vector &, const Vector &=Vector::Null) const
 Compute the color. More...
 
virtual Box GetBox () const
 Compute the bounding box of the scalar field. More...
 
virtual Vector Normal (const Vector &) const
 Compute the normal to the surface. More...
 
void Curvature (const Vector &, double &, double &) const
 Compute the gaussian and mean curvatures. More...
 
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. More...
 
Vector Dichotomy (Vector, Vector, double, double, double, const double &=1.0e-4) const
 Compute the intersection between a segment and an implicit surface. More...
 
virtual bool GetSample (Vector &, const Box &, Random &=Random::R239) const
 Find a point sample on the implicit surface. More...
 
virtual int GetSamples (QVector< Vector > &, const Box &, int, Random &=Random::R239) const
 Find a set of random sample points on the implicit surface. More...
 
virtual QVector< VectorPoisson (double, int, Random &=Random::R239) const
 Compute a Poisson sphere distribution on an implicit surface. More...
 
virtual ScalarField2 Sample (const Rectangles &, int, int) const
 Compute the field function at the vertices a grid. More...
 
virtual ScalarField2 Sample (const Quadrangle &, int) const
 Sample the scalar field on a quadrangle. More...
 
virtual ScalarField Sample (const Box &, int) const
 Sample the implicit surface to get a scalar field. More...
 
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. More...
 
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. More...
 
virtual double K () const
 Compute the Lipschitz constant of the field function. More...
 
virtual double K (const Box &) const
 Compute the local Lipschitz constant inside a box. More...
 
virtual double K (const Sphere &) const
 Compute the local Lipschitz constant inside a box. More...
 
virtual double K (const Segment &) const
 Compute the local Lipschitz constant along a segment. More...
 
virtual void Polygonize (int, Mesh &, const Box &, const double &=1e-4) const
 Compute the polygonal mesh approximating the implicit surface. More...
 
virtual void PolygonizeLucie (const Box &, Mesh &, bool, bool) const
 Implementation of the original continuation polygonization method. More...
 
virtual void PolygonizeLucie (const double &, Mesh &, bool, bool) const
 Wyvill's marching cubes algorithm. More...
 
virtual void Dual (int, Mesh &, const Box &) const
 Dual polygonization. More...
 
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. More...
 
virtual void Polygonize (const Box &, QVector< Triangle > &, const double &=1e-4, bool=false) const
 Polygonize a cube. More...
 
virtual void Polygonize (const Tetrahedra &, QVector< Triangle > &, const double &=1e-4) const
 Polygonize a tetrahedral cell. More...
 
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. More...
 
virtual void Voxelize (const Box &, int, Box &, QVector< Vector > &) const
 Voxelize the scalar field. More...
 
virtual void Voxelize (int, Voxel &, const Box &) const
 Voxelization. More...
 
virtual void Colorize (const Mesh &, MeshColor &) const
 Colorize the vertexes of a mesh according to the analytic scalar field. More...
 

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. More...
 

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.

◆ 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 grid, 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.

◆ 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.

◆ 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.

◆ 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 marching cubes algorithm.

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 grid.

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.

◆ Value()

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

Compute the value of the field.

Parameters
pPoint.

Reimplemented in Algebraic.

◆ 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.