/** class MetaModel
*
* Generates a 3-D model of a recursive polyhedron. It does so by starting
* with a basic polyhedron, and then repeating it at each of the verticies
* of itself. For example (using a polygon),
*
* # #1
* / \ / \
* #___# would change to 01__1
* / \ / \
* #0__02_2#
*
* as it projects itself onto each of its verticies(#). On the next iteration,
* it would duplicate the new model to each of it's verticies, like this -
*
* #1
* / \
* 1___1
* / \ / \ (The next level would consist of
* 01__1__12 one a shape just like this, with all
* / \ / \ zeros, beside one just like it with all
* 0___0 2___2 twos, and one on top with all ones.)
* / \ / \ / \ / \
* #0__0___02__2__2#
*
* - and so on. This technique would work with any polygon or polyhedron,
* but gross overlap would occur on all shapes except triangle, square, and
* the 5 polyhedra defined in this file (see below)
*
* Once initialized, this object contains a VRML-esque representation of
* the model, consisting of an array of the points in 3-space, and an
* array describing which of the points each line is to be drawn between.
*
* note that his technique causes many of the points to be duplicated.
* This is useful for separating the individual polygons, as well as
* providing mathematical simplicity. In java, performance is dependant
* mainly upon color changes and line draws in a paint method somewhere,
* and little is to be gained by reducing the number of points that the
* lines reference. (as long as you have nice clean rotator, perspective,
* and zSort methods)
*/
public class MetaModel extends WFModel
{
double[][] points;
int[][] lines;
int[] params;
int numUnitP, numUnitL; // used externally
double separation;
////////////
//
// points representing the verticies of the basic polyhedra in 3-space
// (tetrahedron, pyramid, sextahedron, octahedron, cube)
//
double[][][] unitPoints = {
{{0, 0, 0}, {10, 0, 0}, {5, -7, -5}, {5, -7, 5}},
{{0, 0, 0}, {10, 0, 0}, {10, 0, 10}, {0, 0, 10}, {5, -9, 5}},
{{0, 0, 0}, {10, 0, 0}, {5, 0, 8.66}, {5, 6, 4}, {5, -6, 4}},
{{0, 0, 0}, {10, 0, 0}, {10, 0, 10}, {0, 0, 10}, {5, -6.8, 5}, {5, 6.8, 5}},
{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}, {0, 0, 10}, {10, 0, 10}, {10, 10, 10}, {0, 10, 10}}
};
/////////////
//
// lines connecting the points in the basic polyhedra
//
int[][][] unitLines = {
{{0, 1, 0}, {1, 2, 0}, {2, 0, 0}, {0, 3, 0}, {1, 3, 0}, {2, 3, 0}},
{{0, 1, 0}, {1, 2, 0}, {2, 3, 0}, {3, 0, 0}, {0, 4, 0}, {1, 4, 0}, {2, 4, 0}, {3, 4, 0}},
{{0, 1, 0}, {1, 2, 0}, {2, 0, 0}, {0, 3, 0}, {1, 3, 0}, {2, 3, 0}, {0, 4, 0}, {1, 4, 0}, {2, 4, 0}},
{{0, 1, 0}, {1, 2, 0}, {2, 3, 0}, {3, 0, 0}, {0, 4, 0}, {1, 4, 0}, {2, 4, 0}, {3, 4, 0}, {0, 5, 0}, {1, 5, 0}, {2, 5, 0}, {3, 5, 0}},
{{0, 1, 0}, {1, 2, 0}, {2, 3, 0}, {3, 0, 0}, {4, 5, 0}, {5, 6, 0}, {6, 7, 0}, {7, 4, 0}, {0, 4, 0}, {1, 5, 0}, {2, 6, 0}, {3, 7, 0}}
};
/** MetaModel
*
* Generates a new model using one of the unit polyhedra defined in
* this object.
* @param params values for polyhedron, recursion, and spacing
*/
public MetaModel(int[] params)
{
this.params = params;
separation = (double)(params[1])/100;
numUnitP = unitPoints[params[2]].length;
numUnitL = unitLines[params[2]].length;
buildModel(unitPoints[params[2]], unitLines[params[2]]);
}
/** MetaModel
*
* Generates a new model based on an external set of points and lines.
* These could be a different shape, or one of the defined unit polyhedra
* that has been rotated by the user (faster than keeping track of
* and processing all of the net rotation axes)
* @param parameters values for polyhedron, recursion and spacing.
* @param newUnitPoints one of the points must be (0, 0, 0).
* @param newUnitLines must be a valid set of lines for newUnitPoints.
*/
public MetaModel(int[] params, double[][] newUnitPoints, int[][] newUnitLines)
{
this.params = params;
separation = (double)(params[1])/100;
numUnitP = newUnitPoints.length;
numUnitL = newUnitLines.length;
buildModel(newUnitPoints, newUnitLines);
}
/** buildModel
*
* builds the model by cycling through the recursion levels and adding
* bigger and bigger models to themselves, to generate a bigger and
* bigger model to add to itself, to generate a bigger and bigger...
*/
public void buildModel(double[][]unitPoints, int[][]unitLines)
{
int num = unitPoints.length;
/////////////
//
// for the first iteration, start
// with the points and lines for a single unit polyhedron
//
double[][] oldPoints = unitPoints;
int [][] oldLines = unitLines;
///////////
//
// iterate over the number of recursions
//
for (int q = 0; q