// Generation of fractle mountains - square floor plan // // Author Matthew Caryl // Created 6.4.97 // // Although under copywrite to the author (Matthew Caryl) this code can be copied and modified for non-commercial // purposes as long as any derivatives contain this condition. package Mountains; import java.awt.Color; import ADT.Random; import ADT.Vector; import ADT.Entity; final class Square extends FloorPlan { private float variation; private int size; private float[][] xs; // square array of vertices private float[][] ys; private float[][] zs; public Square(Random R, float X, float Y, float Z, float L, float S) { variation = L * S; size = 4; int v = (int) (variation); xs = new float[2][2]; ys = new float[2][2]; zs = new float[2][2]; xs[0][0] = X - L / 2f; ys[0][0] = Y - L / 2f; zs[0][0] = Z + (float) (R.range(v) - v / 2); xs[0][1] = X + L / 2f; ys[0][1] = Y - L / 2f; zs[0][1] = Z + (float) (R.range(v) - v / 2); xs[1][0] = X - L / 2f; ys[1][0] = Y + L / 2f; zs[1][0] = Z + (float) (R.range(v) - v / 2); xs[1][1] = X + L / 2f; ys[1][1] = Y + L / 2f; zs[1][1] = Z + (float) (R.range(v) - v / 2); } public void recurse(Random R) { variation /= 2f; size *= 4; int v = (int) (variation); float[][] XS = new float[2 * xs.length - 1][2 * xs.length - 1]; float[][] YS = new float[2 * ys.length - 1][2 * xs.length - 1]; float[][] ZS = new float[2 * zs.length - 1][2 * xs.length - 1]; int side = xs.length; // bulk of new vertices in main grid for (int i = side - 2; i >= 0; i--) for (int j = side - 2; j >= 0; j--) { XS[2 * i ][2 * j ] = xs[i][j]; YS[2 * i ][2 * j ] = ys[i][j]; ZS[2 * i ][2 * j ] = (9f * zs[i][j] + 3f * zs[i][j + 1] + 3f * zs[i + 1][j] + 1f * zs[i + 1][j + 1]) / 16f + (float) (R.range(v) - v / 2); XS[2 * i ][2 * j + 1] = (xs[i][j] + xs[i][j + 1]) / 2f; YS[2 * i ][2 * j + 1] = (ys[i][j] + ys[i][j + 1]) / 2f; ZS[2 * i ][2 * j + 1] = (3f * zs[i][j] + 9f * zs[i][j + 1] + 1f * zs[i + 1][j] + 3f * zs[i + 1][j + 1]) / 16f + (float) (R.range(v) - v / 2); XS[2 * i + 1][2 * j ] = (xs[i][j] + xs[i + 1][j]) / 2f; YS[2 * i + 1][2 * j ] = (ys[i][j] + ys[i + 1][j]) / 2f; ZS[2 * i + 1][2 * j ] = (3 * zs[i][j] + 1 * zs[i][j + 1] + 9 * zs[i + 1][j] + 3 * zs[i + 1][j + 1]) / 16f + (float) (R.range(v) - v / 2); XS[2 * i + 1][2 * j + 1] = (xs[i][j + 1] + xs[i + 1][j]) / 2f; YS[2 * i + 1][2 * j + 1] = (ys[i][j + 1] + ys[i + 1][j]) / 2f; ZS[2 * i + 1][2 * j + 1] = (1 * zs[i][j] + 3 * zs[i][j + 1] + 3 * zs[i + 1][j] + 9 * zs[i + 1][j + 1]) / 16f + (float) (R.range(v) - v / 2); } // special requirements for // the bottom { int i = side - 1; for (int j = side - 2; j >= 0; j--) { XS[2 * i][2 * j ] = xs[i][j]; YS[2 * i][2 * j ] = ys[i][j]; ZS[2 * i][2 * j ] = (9f * zs[i][j] + 3f * zs[i][j + 1] - 3f * zs[i - 1][j] - 1f * zs[i - 1][j + 1]) / 16f + (float) (R.range(v) - v / 2); XS[2 * i][2 * j + 1] = (xs[i][j] + xs[i][j + 1]) / 2f; YS[2 * i][2 * j + 1] = (ys[i][j] + ys[i][j + 1]) / 2f; ZS[2 * i][2 * j + 1] = (3f * zs[i][j] + 9f * zs[i][j + 1] - 1f * zs[i - 1][j] - 3f * zs[i - 1][j + 1]) / 16f + (float) (R.range(v) - v / 2); } } // the right { int j = side - 1; for (int i = side - 2; i >= 0; i--) { XS[2 * i ][2 * j] = xs[i][j]; YS[2 * i ][2 * j] = ys[i][j]; ZS[2 * i ][2 * j] = (9f * zs[i][j] - 3f * zs[i][j - 1] + 3f * zs[i + 1][j] - 1f * zs[i + 1][j - 1]) / 16f + (float) (R.range(v) - v / 2); XS[2 * i + 1][2 * j] = (xs[i][j] + xs[i + 1][j]) / 2f; YS[2 * i + 1][2 * j] = (ys[i][j] + ys[i + 1][j]) / 2f; ZS[2 * i + 1][2 * j] = (3 * zs[i][j] - 1 * zs[i][j - 1] + 9 * zs[i + 1][j] - 3 * zs[i + 1][j - 1]) / 16f + (float) (R.range(v) - v / 2); } } // and the bottom right { int j = side - 1; int i = side - 1; XS[2 * i][2 * j] = xs[i][j]; YS[2 * i][2 * j] = ys[i][j]; } xs = XS; ys = YS; zs = ZS; } public int getSize() { return size; } public Entity getObject() { int side = xs.length; Vector[] vs = new Vector[side * side + (side - 1) * (side - 1)]; int[] ts = new int[3 * 4 * (side - 1) * (side - 1)]; Color[] cs = new Color[4 * (side - 1) * (side - 1)]; // transfer vertices over for (int i = side - 1, o = side * side - 1; i >= 0; i--) for (int j = side - 1; j >= 0; j--, o--) vs[o] = new Vector(xs[i][j], ys[i][j], zs[i][j]); // and make new ones in the middle of each square for (int i = side - 1, o = vs.length - 1; i >= 1; i--) for (int j = side - 1; j >= 1; j--, o--) vs[o] = new Vector((xs[i - 1][j - 1] + xs[i - 1][j] + xs[i][j - 1] + xs[i][j]) / 4f, (ys[i - 1][j - 1] + ys[i - 1][j] + ys[i][j - 1] + ys[i][j]) / 4f, (zs[i - 1][j - 1] + zs[i - 1][j] + zs[i][j - 1] + zs[i][j]) / 4f); // create triangles bottom-right to top-left for (int i = side - 2, o = 0; i >= 0; i--) { for (int j = side - 2; j >= 0; j--, o++) { ts[3 * 4 * o + 0] = i * side + j; ts[3 * 4 * o + 1] = i * side + j + 1; ts[3 * 4 * o + 2] = vs.length - o - 1; cs[4 * o] = Color.white; ts[3 * 4 * o + 3] = i * side + j + 1; ts[3 * 4 * o + 4] = (i + 1) * side + j + 1; ts[3 * 4 * o + 5] = vs.length - o - 1; cs[4 * o + 1] = Color.white; ts[3 * 4 * o + 6] = (i + 1) * side + j + 1; ts[3 * 4 * o + 7] = (i + 1) * side + j; ts[3 * 4 * o + 8] = vs.length - o - 1; cs[4 * o + 2] = Color.white; ts[3 * 4 * o + 9] = (i + 1) * side + j; ts[3 * 4 * o + 10] = i * side + j; ts[3 * 4 * o + 11] = vs.length - o - 1; cs[4 * o + 3] = Color.white; } } return new Entity(vs, ts, cs, null); } }