📄 gothiccolumn.java
字号:
//
// CLASS
// GothicColumn - Gothic-style column used in example scenes
//
// DESCRIPTION
// This class builds a Gothic-column architectural column.
//
// SEE ALSO
// ?
//
// AUTHOR
// David R. Nadeau / San Diego Supercomputer Center
//
//
package Java3DApplet;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
class GothicColumn
extends Primitive
{
//
// Construction Flags
//
public final static int BUILD_TAPERED_CROWN = 0x1;
public final static int BUILD_TOP = 0x2;
public final static int BUILD_BOTTOM = 0x4;
//
// 3D nodes
//
private Appearance mainAppearance = null;
//
// Construct a column
//
public GothicColumn( float height, float radius, Appearance app )
{
this( height, radius, 0, app );
}
public GothicColumn( float height, float radius,
int flags, Appearance app )
{
mainAppearance = app;
// Compute sizes and positions based upon the
// desired main column radius
// Base box
float baseWidth = 2.7f * radius;
float baseDepth = baseWidth;
float baseHeight = 0.75f * radius / 2.0f;
// Base box #2
float base2Width = 0.8f * baseWidth;
float base2Depth = base2Width;
float base2Height = baseHeight / 2.0f;
// Tapered crown
float crownWidth1 = 2.0f * 0.707f * radius;
float crownDepth1 = crownWidth1;
float crownWidth2 = 1.0f * base2Width;
float crownDepth2 = 1.0f * base2Depth;
float crownHeight = 2.0f * baseHeight;
// Box above tapered crown
float crown2Width = 1.1f * base2Width;
float crown2Depth = 1.1f * base2Depth;
float crown2Height = base2Height;
// Final crown box
float crown3Width = 1.1f * baseWidth;
float crown3Depth = 1.1f * baseDepth;
float crown3Height = baseHeight;
// Cylindrical column
// Extend it up and into the tapered crown
float columnHeight = height - baseHeight - base2Height -
crown2Height - crown3Height;
float columnRadius = radius;
float baseY = baseHeight/2.0f;
float base2Y = baseHeight + base2Height/2.0f;
float columnY = baseHeight + base2Height + columnHeight/2.0f;
float crown2Y = baseHeight + base2Height + columnHeight +
crown2Height/2.0f;
float crown3Y = baseHeight + base2Height + columnHeight +
crown2Height + crown3Height/2.0f;
float crownY = crown2Y - crown2Height/2.0f - crownHeight/2.0f;
// Column base box
int fl = BUILD_TOP;
if ( (flags & BUILD_BOTTOM) != 0 )
fl |= BUILD_BOTTOM;
addBox( baseWidth, baseHeight, baseDepth, baseY, fl );
// Column base box #2 (no bottom)
addBox( base2Width, base2Height, base2Depth, base2Y, BUILD_TOP );
// Main column (no top or bottom)
addCylinder( columnRadius, columnHeight, columnY );
// Column crown tapered box (no top or bottom)
if ( (flags & BUILD_TAPERED_CROWN) != 0 )
{
addBox( crownWidth1, crownHeight, crownDepth1, crownY,
crownWidth2, crownDepth2, 0 );
}
// Box above tapered crown (no top)
addBox( crown2Width, crown2Height, crown2Depth, crown2Y, BUILD_BOTTOM );
// Final crown box
fl = BUILD_BOTTOM;
if ( (flags & BUILD_TOP) != 0 )
fl |= BUILD_TOP;
addBox( crown3Width, crown3Height, crown3Depth, crown3Y, fl );
}
//
// Add an untapered box
//
private void addBox( float width, float height, float depth, float y )
{
addBox( width, height, depth, y, width, depth, 0 );
}
private void addBox( float width, float height, float depth, float y,
int flags )
{
addBox( width, height, depth, y, width, depth, flags );
}
private void addBox( float width, float height, float depth, float y,
float width2, float depth2 )
{
addBox( width, height, depth, y, width2, depth2, 0 );
}
//
// Add a tapered box
//
private void addBox( float width, float height, float depth, float y,
float width2, float depth2, int flags )
{
float[] coordinates = {
// around the bottom
-width/2.0f, -height/2.0f, depth/2.0f,
width/2.0f, -height/2.0f, depth/2.0f,
width/2.0f, -height/2.0f, -depth/2.0f,
-width/2.0f, -height/2.0f, -depth/2.0f,
// around the top
-width2/2.0f, height/2.0f, depth2/2.0f,
width2/2.0f, height/2.0f, depth2/2.0f,
width2/2.0f, height/2.0f, -depth2/2.0f,
-width2/2.0f, height/2.0f, -depth2/2.0f,
};
int[] fullCoordinateIndexes = {
0, 1, 5, 4, // front
1, 2, 6, 5, // right
2, 3, 7, 6, // back
3, 0, 4, 7, // left
4, 5, 6, 7, // top
3, 2, 1, 0, // bottom
};
float v = -(width2 - width) / height;
float[] normals = {
0.0f, v, 1.0f, // front
1.0f, v, 0.0f, // right
0.0f, v, -1.0f, // back
-1.0f, v, 0.0f, // left
0.0f, 1.0f, 0.0f, // top
0.0f, -1.0f, 0.0f, // bottom
};
int[] fullNormalIndexes = {
0, 0, 0, 0, // front
1, 1, 1, 1, // right
2, 2, 2, 2, // back
3, 3, 3, 3, // left
4, 4, 4, 4, // top
5, 5, 5, 5, // bottom
};
float[] textureCoordinates = {
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
};
int[] fullTextureCoordinateIndexes = {
0, 1, 2, 3, // front
0, 1, 2, 3, // right
0, 1, 2, 3, // back
0, 1, 2, 3, // left
0, 1, 2, 3, // top
0, 1, 2, 3, // bottom
};
// Select indexes needed
int[] coordinateIndexes;
int[] normalIndexes;
int[] textureCoordinateIndexes;
if ( flags == 0 )
{
// build neither top or bottom
coordinateIndexes = new int[4*4];
textureCoordinateIndexes = new int[4*4];
normalIndexes = new int[4*4];
for ( int i = 0; i < 4*4; i++ )
{
coordinateIndexes[i] = fullCoordinateIndexes[i];
textureCoordinateIndexes[i] = fullTextureCoordinateIndexes[i];
normalIndexes[i] = fullNormalIndexes[i];
}
}
else if ( (flags & (BUILD_TOP|BUILD_BOTTOM)) == (BUILD_TOP|BUILD_BOTTOM) )
{
// build top and bottom
coordinateIndexes = fullCoordinateIndexes;
textureCoordinateIndexes = fullTextureCoordinateIndexes;
normalIndexes = fullNormalIndexes;
}
else if ( (flags & BUILD_TOP) != 0 )
{
// build top but not bottom
coordinateIndexes = new int[5*4];
textureCoordinateIndexes = new int[5*4];
normalIndexes = new int[5*4];
for ( int i = 0; i < 5*4; i++ )
{
coordinateIndexes[i] = fullCoordinateIndexes[i];
textureCoordinateIndexes[i] = fullTextureCoordinateIndexes[i];
normalIndexes[i] = fullNormalIndexes[i];
}
}
else
{
// build bottom but not top
coordinateIndexes = new int[5*4];
textureCoordinateIndexes = new int[5*4];
normalIndexes = new int[5*4];
for ( int i = 0; i < 4*4; i++ )
{
coordinateIndexes[i] = fullCoordinateIndexes[i];
textureCoordinateIndexes[i] = fullTextureCoordinateIndexes[i];
normalIndexes[i] = fullNormalIndexes[i];
}
for ( int i = 5*4; i < 6*4; i++ )
{
coordinateIndexes[i-4] = fullCoordinateIndexes[i];
textureCoordinateIndexes[i-4] = fullTextureCoordinateIndexes[i];
normalIndexes[i-4] = fullNormalIndexes[i];
}
}
IndexedQuadArray quads = new IndexedQuadArray(
coordinates.length, // number of vertexes
GeometryArray.COORDINATES |// vertex coordinates given
GeometryArray.NORMALS | // normals given
GeometryArray.TEXTURE_COORDINATE_2, // texture coordinates given
coordinateIndexes.length ); // number of coordinate indexes
quads.setCoordinates( 0, coordinates );
quads.setCoordinateIndices( 0, coordinateIndexes );
quads.setNormals( 0, normals );
quads.setNormalIndices( 0, normalIndexes );
quads.setTextureCoordinates( 0, textureCoordinates );
quads.setTextureCoordinateIndices( 0, textureCoordinateIndexes );
Shape3D box = new Shape3D( quads, mainAppearance );
Vector3f trans = new Vector3f( 0.0f, y, 0.0f );
Transform3D tr = new Transform3D( );
tr.set( trans ); // translate
TransformGroup tg = new TransformGroup( tr );
tg.addChild( box );
addChild( tg );
}
private final static int NSTEPS = 16;
private void addCylinder( float radius, float height, float y )
{
//
// Compute coordinates, normals, and texture coordinates
// around the top and bottom of a cylinder
//
float[] coordinates = new float[NSTEPS*2*3]; // xyz
float[] normals = new float[NSTEPS*2*3]; // xyz vector
float[] textureCoordinates = new float[NSTEPS*2*2]; // st
float angle = 0.0f;
float deltaAngle = 2.0f * (float)Math.PI / ((float)NSTEPS-1);
float s = 0.0f;
float deltaS = 1.0f / ((float)NSTEPS-1);
int n = 0;
int tn = 0;
float h2 = height/2.0f;
for ( int i = 0; i < NSTEPS; i++ )
{
// bottom
normals[n+0] = (float)Math.cos( angle );
normals[n+1] = 0.0f;
normals[n+2] = -(float)Math.sin( angle );
coordinates[n+0] = radius * normals[n+0];
coordinates[n+1] = -h2;
coordinates[n+2] = radius * normals[n+2];
textureCoordinates[tn+0] = s;
textureCoordinates[tn+1] = 0.0f;
n += 3;
tn += 2;
// top
normals[n+0] = normals[n-3];
normals[n+1] = 0.0f;
normals[n+2] = normals[n-1];
coordinates[n+0] = coordinates[n-3];
coordinates[n+1] = h2;
coordinates[n+2] = coordinates[n-1];
textureCoordinates[tn+0] = s;
textureCoordinates[tn+1] = 1.0f;
n += 3;
tn += 2;
angle += deltaAngle;
s += deltaS;
}
//
// Compute coordinate indexes, normal indexes, and texture
// coordinate indexes awround the sides of a cylinder.
// For this application, we don't need top or bottom, so
// skip them.
//
int[] indexes = new int[NSTEPS*4];
n = 0;
int p = 0; // panel count
for ( int i = 0; i < NSTEPS-1; i++ )
{
indexes[n+0] = p; // bottom left
indexes[n+1] = p+2; // bottom right (next panel)
indexes[n+2] = p+3; // top right (next panel)
indexes[n+3] = p+1; // top left
n += 4;
p += 2;
}
indexes[n+0] = p; // bottom left
indexes[n+1] = 0; // bottom right (next panel)
indexes[n+2] = 1; // top right (next panel)
indexes[n+3] = p+1; // top left
IndexedQuadArray quads = new IndexedQuadArray(
coordinates.length/3, // number of vertexes
GeometryArray.COORDINATES | // format
GeometryArray.NORMALS |
GeometryArray.TEXTURE_COORDINATE_2,
indexes.length ); // number of indexes
quads.setCoordinates( 0, coordinates );
quads.setTextureCoordinates( 0, textureCoordinates );
quads.setNormals( 0, normals );
quads.setCoordinateIndices( 0, indexes );
quads.setTextureCoordinateIndices( 0, indexes );
quads.setNormalIndices( 0, indexes );
Shape3D shape = new Shape3D( quads, mainAppearance );
Vector3f trans = new Vector3f( 0.0f, y, 0.0f );
Transform3D tr = new Transform3D( );
tr.set( trans ); // translate
TransformGroup tg = new TransformGroup( tr );
tg.addChild( shape );
addChild( tg );
}
//
// Control the appearance
//
public void setAppearance( Appearance app )
{
mainAppearance = app;
}
//
// Provide info on the shape and geometry
//
public Shape3D getShape( int partid )
{
return null;
}
public int getNumTriangles( )
{
return 0;
}
public int getNumVertices( )
{
return 2;
}
public Appearance getAppearance(int partId)
{
return getShape(0).getAppearance();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -