de.jreality.geometry
Class TubeFactory

java.lang.Object
  extended by de.jreality.geometry.TubeFactory
Direct Known Subclasses:
PolygonalTubeFactory

public class TubeFactory
extends java.lang.Object

This class calculates tubes around curves. A tube of radius r around a curve C can be defined as the locus of points which lie at distant r from the curve (ignoring endpoints). We are interested only in imbedded tubes, that is, tubes which do not intersect themselves.

Example: in euclidean space, a tube around a line is an infinite cylinder. And, a tube around a line segment is a finite cylinder.

Complications arise in calculating tubes in various ways, some of which this class attempts to take into account:

If the curve is considered to be discrete, then the tubing problem is not well-posed near the joints of the curve, since there the curvature approaches infinity and any finite tube will intersect itself.

This factory provides the basic foundation. It does not provide any geometry output; it is useful mainly on account of the method #makeFrameField(double[][], int, int). See its documentation for a more precise statement of the mathematical implementation. Subclassses which generate actual geometric tubes can take different strategies to the challenges posed above, working with the same basic data provided in this class.

The basic data which determine the tube are:

These data are set using the instance methods below.

Calling update() will update the current state of the factory to the values set since the last call to update(). This is mostly of interest in the subclasses.

TODO adjust the parameter which determines how the profile at the vertices of the curve are "pulled back" towards the mid-segment profiles.

Author:
Charles Gunn

Field Summary
 boolean closedCurve
           
 double[][] crossSection
           
 double[][] edgeColors
           
 boolean extendAtEnds
           
 FrameFieldType frameFieldType
           
 boolean framesDirty
           
 boolean generateTextureCoordinates
           
 int metric
           
 double[] radii
           
 double radius
           
 double[][] theCurve
           
 int twists
           
 double[][] userBinormals
           
 double[][] userTangents
           
 double[][] vertexColors
           
 boolean vertexColorsEnabled
           
 
Constructor Summary
TubeFactory()
           
TubeFactory(double[][] curve)
           
 
Method Summary
 TubeUtility.FrameInfo[] getFrameField()
           
 SceneGraphComponent getFramesSceneGraphRepresentation()
           
static SceneGraphComponent getSceneGraphRepresentation(TubeUtility.FrameInfo[] frames)
           
static SceneGraphComponent getSceneGraphRepresentation(TubeUtility.FrameInfo[] frames, double scale)
           
 double[][] getTangents()
           
 double[][] getUserBinormals()
           
static SceneGraphComponent getXYZAxes()
           
 boolean isArcLengthTextureCoordinates()
           
 boolean isExtendAtEnds()
           
 boolean isGenerateEdges()
           
 boolean isGenerateTextureCoordinates()
           
 boolean isMatchClosedTwist()
           
 boolean isRemoveDuplicates()
           
 TubeUtility.FrameInfo[] makeFrameField(double[][] polygon, FrameFieldType type, int metric)
          The primary method in the tube-generating process.
 void setArcLengthTextureCoordinates(boolean arcLengthTextureCoordinates)
          If true, force the generated v- texture coordinates to run from 0 to 1 proportional to the (discrete) arc length of the curve.
 void setClosed(boolean closedCurve)
          Set whether the curve should be considered a closed loop.
 void setCrossSection(double[][] crossSection)
          A 2D curve in the (x,y) plane (with 3D coordinates!) to be used as the cross section of the tube.
 void setEdgeColors(double[][] edgeColors)
          Apply colors to faces of output tube, one for each tube segment.
 void setExtendAtEnds(boolean extendAtEnds)
           
 void setFrameField(TubeUtility.FrameInfo[] frames)
           
 void setFrameFieldType(FrameFieldType frameFieldType)
          Should the underlying frame field be generated by TubeUtility#PARALLEL or TubeUtility#FRENET displacement? Default: TubeUtility#PARALLEL
 void setGenerateEdges(boolean generateEdges)
           
 void setGenerateTextureCoordinates(boolean generateTextureCoordinates)
          Whether the output geometry should have automatic texture coordinates.
 void setMatchClosedTwist(boolean matchClosedTwist)
           
 void setMetric(int metric)
          Set the metric of the ambient space.
 void setRadii(double[] radii)
           
 void setRadius(double radius)
          Set the radius of the tube.
 void setRemoveDuplicates(boolean removeDuplicates)
           
 void setTangents(double[][] tangents)
           
 void setTwists(int twists)
          Set an integer number of twists to apply to the cross section as it is swept along the curve.
 void setUserBinormals(double[][] userBinormals)
           
 void setVertexColors(double[][] vertexColors)
          Apply colors to vertices of output tube, one for each tube cross section.
 void setVertexColorsEnabled(boolean vertexColorsEnabled)
          Whether to apply vertex colors to the output tube.
 void update()
           
 void updateFrames()
           
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

theCurve

public double[][] theCurve

userTangents

public double[][] userTangents

userBinormals

public double[][] userBinormals

vertexColors

public double[][] vertexColors

edgeColors

public double[][] edgeColors

crossSection

public double[][] crossSection

radii

public double[] radii

radius

public double radius

frameFieldType

public FrameFieldType frameFieldType

metric

public int metric

twists

public int twists

generateTextureCoordinates

public boolean generateTextureCoordinates

extendAtEnds

public boolean extendAtEnds

framesDirty

public boolean framesDirty

closedCurve

public boolean closedCurve

vertexColorsEnabled

public boolean vertexColorsEnabled
Constructor Detail

TubeFactory

public TubeFactory()

TubeFactory

public TubeFactory(double[][] curve)
Method Detail

updateFrames

public void updateFrames()

getFrameField

public TubeUtility.FrameInfo[] getFrameField()

setClosed

public void setClosed(boolean closedCurve)
Set whether the curve should be considered a closed loop. Default: false.

Parameters:
closedCurve -

setCrossSection

public void setCrossSection(double[][] crossSection)
A 2D curve in the (x,y) plane (with 3D coordinates!) to be used as the cross section of the tube. For flexibility: unless the first and last points are equal, the curve is considered to be open and the resulting tube will not close up. Default: an octagon lying on the unit circle.

Parameters:
crossSection -

getTangents

public double[][] getTangents()

setTangents

public void setTangents(double[][] tangents)

getUserBinormals

public double[][] getUserBinormals()

setUserBinormals

public void setUserBinormals(double[][] userBinormals)

setFrameField

public void setFrameField(TubeUtility.FrameInfo[] frames)

setFrameFieldType

public void setFrameFieldType(FrameFieldType frameFieldType)
Should the underlying frame field be generated by TubeUtility#PARALLEL or TubeUtility#FRENET displacement? Default: TubeUtility#PARALLEL

Parameters:
frameFieldType -

setRadius

public void setRadius(double radius)
Set the radius of the tube. To be exact, this is applied as a scale factor to the cross section before it is swept out to make the tube.

Parameters:
radius -

setRadii

public void setRadii(double[] radii)

setMetric

public void setMetric(int metric)
Set the metric of the ambient space. See Pn.

Parameters:
metric -

setTwists

public void setTwists(int twists)
Set an integer number of twists to apply to the cross section as it is swept along the curve. This twisting is done proportional to the arc length of the curve. For creating exotic shapes. Default: 0

Parameters:
twists -

setVertexColorsEnabled

public void setVertexColorsEnabled(boolean vertexColorsEnabled)
Whether to apply vertex colors to the output tube. See setVertexColors(double[][]).

Parameters:
vertexColorsEnabled -

setEdgeColors

public void setEdgeColors(double[][] edgeColors)
Apply colors to faces of output tube, one for each tube segment.

Parameters:
edgeColors - double[n][] where n is number of segments in curve

setVertexColors

public void setVertexColors(double[][] vertexColors)
Apply colors to vertices of output tube, one for each tube cross section.

Parameters:
vertexColors - double[n][] where n is number of vertices in curve

isGenerateTextureCoordinates

public boolean isGenerateTextureCoordinates()

setGenerateTextureCoordinates

public void setGenerateTextureCoordinates(boolean generateTextureCoordinates)
Whether the output geometry should have automatic texture coordinates. If true, texture coordinates will be based on the tubing parameters: u is the cross section parameter, v is the length of the tube.

See Also:
setArcLengthTextureCoordinates(boolean)

isArcLengthTextureCoordinates

public boolean isArcLengthTextureCoordinates()

setArcLengthTextureCoordinates

public void setArcLengthTextureCoordinates(boolean arcLengthTextureCoordinates)
If true, force the generated v- texture coordinates to run from 0 to 1 proportional to the (discrete) arc length of the curve.

Parameters:
arcLengthTextureCoordinates -

isExtendAtEnds

public boolean isExtendAtEnds()

setExtendAtEnds

public void setExtendAtEnds(boolean extendAtEnds)

isRemoveDuplicates

public boolean isRemoveDuplicates()

setRemoveDuplicates

public void setRemoveDuplicates(boolean removeDuplicates)

isGenerateEdges

public boolean isGenerateEdges()

setGenerateEdges

public void setGenerateEdges(boolean generateEdges)

isMatchClosedTwist

public boolean isMatchClosedTwist()

setMatchClosedTwist

public void setMatchClosedTwist(boolean matchClosedTwist)

getFramesSceneGraphRepresentation

public SceneGraphComponent getFramesSceneGraphRepresentation()

update

public void update()

makeFrameField

public TubeUtility.FrameInfo[] makeFrameField(double[][] polygon,
                                              FrameFieldType type,
                                              int metric)
The primary method in the tube-generating process.

This is an instance method, since there is quite a bit of state which is expensive to compute and so can be saved in the instance.

The code is complicated by dealing with euclidean, hyperbolic, and elliptic cases simultaneously and But at the same time the code is a interesting example of how euclidean objects can be generalized to non-euclidean setting.

Explanation of the algorithm: Assume that polygon is an array of length n

The input curve polygon is assumed to have an initial and terminal point with the following properties: 1) if the curve is closed, polygon[0]=polygon[n-2] and polygon[n-1]=polygon[1] 2) if the curve is not closed, then polygon[0] is the mirror of polygon[2] wrt polygon[1], similarly for polygon[n-1]. The tubing factories perform this setup automatically before calling this method, but if you want to use this method directly, you'll need to do this setup yourself.

The returned frame array (of type TubeUtility.FrameInfo is of length n-2.

The input curve can consist of either 3- or 4-d vectors; in the latter case they are assumed to be homogeneous projective coordinates.

The basic idea is: first calculate the Frenet frame for the curve. That is, in the best case, a simple matter at each point P[i] of the curve:

This algorithm calculates the Frenet frame. To get the parallel frame, first calculate the Frenet frame. Then the normal vector N has to be parallel transported along the curve: At points where three or more consecutive curve vertices are collinear, \ some of the steps of the above algorithm aren't well-defined. In that case, the correct behavior is basically to tube as if these points had been deleted before the processing began.

Parameters:
polygon - the curve to frame (as array of 3- or 4-d points)
type - TubeUtility.PARALLEL or {TubeUtility.FRENET}
metric - the metric metric Pn
Returns:
an array of length (n-2) of type TubeUtility.FrameInfo containing an orthonormal frame for each internal point in the initial polygon array.

getSceneGraphRepresentation

public static SceneGraphComponent getSceneGraphRepresentation(TubeUtility.FrameInfo[] frames)

getSceneGraphRepresentation

public static SceneGraphComponent getSceneGraphRepresentation(TubeUtility.FrameInfo[] frames,
                                                              double scale)

getXYZAxes

public static SceneGraphComponent getXYZAxes()