Geometries¶
Frenet Frame & Dir Tube¶
In three.js, Frenet Frame is used for generating TubeGeometry.
To generate a tube, the TubeGeomerty calling Curve.computeFrenetFrames() to create parallel curves, then build mesh points with indecis.
function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {
BufferGeometry.call( this );
this.type = 'TubeBufferGeometry';
this.parameters = {
path: path,
tubularSegments: tubularSegments,
radius: radius,
radialSegments: radialSegments,
closed: closed
};
tubularSegments = tubularSegments || 64;
radius = radius || 1;
radialSegments = radialSegments || 8;
closed = closed || false;
var frames = path.computeFrenetFrames( tubularSegments, closed );
// expose internals
this.tangents = frames.tangents;
this.normals = frames.normals;
this.binormals = frames.binormals;
// helper variables
var vertex = new Vector3();
var normal = new Vector3();
var uv = new Vector2();
var P = new Vector3();
var i, j;
// buffer
var vertices = [];
var normals = [];
var uvs = [];
var indices = [];
// create buffer data
generateBufferData();
// build geometry
this.setIndex( indices );
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
function generateBufferData() {
for ( i = 0; i < tubularSegments; i ++ ) {
generateSegment( i );
}
generateSegment( ( closed === false ) ? tubularSegments : 0 );
generateUVs();
generateIndices();
}
}
The Three.js Curve.computeFrenetFrames() is a key function to implement tube geometry generation. Which use an other method to generate frames’ tangents:
for ( i = 0; i <= segments; i ++ ) {
u = i / segments;
tangents[ i ] = this.getTangentAt( u, new Vector3() );
tangents[ i ].normalize();
}
getTangentAt: function ( u, optionalTarget ) {
var t = this.getUtoTmapping( u );
return this.getTangent( t, optionalTarget );
},
getUtoTmapping: function ( u, distance ) {
...
var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
var t = ( i + segmentFraction ) / ( il - 1 );
return t;
},
The problem of this is that it dosn’t follow the THREE.CatmullRomCurve3 curve. See a DirTubeGeometry test resulsts. It could be optimized.
Reference¶
- Three.js class: TubeGeometry docs & src.
- Three.js class: Curve.
- Andrew J. Hanson and Hui Ma, *Parallel Transport Approach to Curve Framing*, Department of Computer Science, Indiana University.
- *Frenet–Serret formulas*, wikipedia