// file: j3dvisual/examples/tilogo/Torus.java // written by Jan Köhnlein import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.geometry.*; public class Torus extends Shape3D { /** the radius of the center circle */ private double radius = 1.; /** the radius of the tube */ private double thickness = 0.2; /** number of longitudes */ private int iCount = 20; /** number of latitudes */ private int jCount = 10; public Torus() { computeGeometry(); } public Torus( double radius, double tickness ) { this.radius = radius; this.thickness = thickness; computeGeometry(); } public Torus( int iCount, int jCount, double radius, double tickness ) { this.iCount = iCount; this.jCount = jCount; this.radius = radius; this.thickness = thickness; computeGeometry(); } public Torus( int iCount, int jCount ) { this.iCount = iCount; this.jCount = jCount; computeGeometry(); } public void computeGeometry() { Transform3D turnMatrix = new Transform3D(); double angle = 0; double innerAngle = 0; Point3f center = null; Point3f[] vertices = new Point3f[ ( iCount + 1 ) * jCount ]; int[] indices = new int[ 4 * ( iCount + 1 ) * jCount ]; Point2f[] textureCoords = new Point2f[ ( iCount + 1 ) * jCount ]; Vector3f[] normals = new Vector3f[ ( iCount + 1 ) * jCount ]; int index = 0; for ( int i = 0; i <= iCount; ++i ) { angle = 2. * i * Math.PI / iCount; center = new Point3f ( ( float ) ( Math.cos( angle ) * radius ), ( float ) ( Math.sin( angle ) * radius ), 0 ); turnMatrix.rotZ( angle + Math.PI / 2. ); turnMatrix.setTranslation( new Vector3f( center ) ); for ( int j = 0; j < jCount; ++j ) { innerAngle = 2. * j * Math.PI / jCount; // vertex vertices[ index ] = new Point3f ( 0, ( float ) ( Math.cos( innerAngle ) * thickness ), ( float ) ( Math.sin( innerAngle ) * thickness ) ); turnMatrix.transform( vertices[ index ] ); // normals normals[ index ] = new Vector3f (); normals[ index ].sub( vertices[ index ], center ); normals[ index ].normalize(); // texture coordinates textureCoords[ index ] = new Point2f ( ( ( float ) i ) / iCount , ( ( float ) j ) / jCount ); // face indices[ 4 * index ] = j + i * jCount; indices[ 4 * index + 1 ] = ( j + 1 ) % jCount + i * jCount; indices[ 4 * index + 2 ] = ( j + 1 ) % jCount + ( i + 1 ) * jCount; indices[ 4 * index + 3 ] = j + ( i + 1 ) * jCount; index ++; } } // initialize QuadArray QuadArray quad = new QuadArray ( 4 * iCount * jCount, GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2 | GeometryArray.COLOR_3 ); Color3f colour = new Color3f( 0f, 0f, 1f ); for ( int i = 0; i < iCount * jCount; ++i ) { for ( int j = 0; j < 4; ++j ) { quad.setCoordinate ( 4 * i + j, vertices[ indices[ 4 * i + j ] ] ); quad.setTextureCoordinate ( 4 * i + j, textureCoords[ indices[ 4 * i + j ] ] ); quad.setNormal ( 4 * i + j, normals[ indices [ 4 * i + j ] ] ); quad.setColor ( 4 * i + j, colour ); } } setGeometry( quad ); } }