// Generation of fractle mountains - hexagon 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 Hexagon extends FloorPlan { private static final float D000 = 0f; private static final float D060 = (float) Math.PI / 3f; private static final float D090 = (float) Math.PI / 2f; private static final float D120 = 2f * (float) Math.PI / 3f; private static final float D180 = (float) Math.PI; private float variation; private int size; private boolean verticle; private float[] xs; private float[] ys; private float[] zs; private Hexagon[] children; // create internal hexagon specifying coordinates and the order in which they should be stored private Hexagon(float[] XS, float YS[], float ZS[], int[] order, boolean V) { verticle = V; xs = new float[6]; ys = new float[6]; zs = new float[6]; for (int i = 0; i < 6; i++) { xs[i] = XS[order[i]]; ys[i] = YS[order[i]]; zs[i] = ZS[order[i]]; } } // decompose model private void internalRecursion(Random R, float variation) { // either by decomposing children if (children != null) { for (int i = 0; i < 3; i++) children[i].internalRecursion(R, variation); } // or decomposing oneself, perhaps for the verticle hexagon model else if (verticle) { children = new Hexagon[3]; float[] XS = new float[13]; float[] YS = new float[13]; float[] ZS = new float[13]; int[] order = new int[6]; int v = (int) (variation); // standard x positions float x0 = xs[5]; float x1 = (xs[0] + 2 * xs[5]) / 3f; float x2 = xs[0]; float x3 = (xs[1] - 2 * xs[0]) / 3f; float x4 = xs[1]; float x5 = (4 * xs[1] - xs[0]) / 3f; // standard y positions float y0 = ys[0]; float y1 = ys[1]; float y2 = (ys[0] + ys[3]) / 2f; float y3 = ys[2]; float y4 = ys[3]; // all coordinates for sub-hexagons XS[ 0] = x2; YS[ 0] = y0; ZS[ 0] = zs[0]; XS[ 1] = x3; YS[ 1] = y1; ZS[ 1] = (zs[0] + zs[1]) / 2f + R.range(v) - v / 2; XS[ 2] = x4; YS[ 2] = y1; ZS[ 2] = zs[1]; XS[ 3] = x5; YS[ 3] = y2; ZS[ 3] = (zs[1] + zs[2]) / 2f + R.range(v) - v / 2; XS[ 4] = x4; YS[ 4] = y3; ZS[ 4] = zs[2]; XS[ 5] = x3; YS[ 5] = y3; ZS[ 5] = (zs[2] + zs[3]) / 2f + R.range(v) - v / 2; XS[ 6] = x2; YS[ 6] = y4; ZS[ 6] = zs[3]; XS[ 7] = x1; YS[ 7] = y4; ZS[ 7] = (zs[3] + zs[4]) / 2f + R.range(v) - v / 2; XS[ 8] = x0; YS[ 8] = y3; ZS[ 8] = zs[4]; XS[ 9] = x1; YS[ 9] = y2; ZS[ 9] = (zs[4] + zs[5]) / 2f + R.range(v) - v / 2; XS[10] = x0; YS[10] = y1; ZS[10] = zs[5]; XS[11] = x1; YS[11] = y0; ZS[11] = (zs[5] + zs[0]) / 2f + R.range(v) - v / 2; XS[12] = x2; YS[12] = y2; ZS[12] = (zs[0] + zs[1] + zs[2] + zs[3] + zs[4] + zs[5]) / 6f; // sub-hexagons given select coordinates order[0] = 0; order[1] = 1; order[2] = 12; order[3] = 9; order[4] = 10; order[5] = 11; children[0] = new Hexagon(XS, YS, ZS, order, !verticle); order[0] = 2; order[1] = 3; order[2] = 4; order[3] = 5; order[4] = 12; order[5] = 1; children[1] = new Hexagon(XS, YS, ZS, order, !verticle); order[0] = 12; order[1] = 5; order[2] = 6; order[3] = 7; order[4] = 8; order[5] = 9; children[2] = new Hexagon(XS, YS, ZS, order, !verticle); xs = null; ys = null; zs = null; } // perhaps for the horizontal hexagon model else { children = new Hexagon[3]; float[] XS = new float[13]; float[] YS = new float[13]; float[] ZS = new float[13]; int[] order = new int[6]; int v = (int) (variation); // standard x positions float x0 = xs[4]; float x1 = xs[5]; float x2 = (xs[0] + xs[5]) / 2f; float x3 = xs[0]; float x4 = xs[1]; // standard y positions float y0 = ys[0]; float y1 = (ys[1] + 2 * ys[0]) / 3f; float y2 = ys[1]; float y3 = (ys[2] + 2 * ys[1]) / 3f; float y4 = ys[2]; float y5 = (4 * ys[2] - ys[1]) / 3f; // all coordinates for sub-hexagons XS[ 0] = x1; YS[ 0] = y0; ZS[ 0] = zs[5]; XS[ 1] = x2; YS[ 1] = y1; ZS[ 1] = (zs[5] + zs[0]) / 2f + R.range(v) - v / 2; XS[ 2] = x3; YS[ 2] = y0; ZS[ 2] = zs[0]; XS[ 3] = x4; YS[ 3] = y1; ZS[ 3] = (zs[0] + zs[1]) / 2f + R.range(v) - v / 2; XS[ 4] = x4; YS[ 4] = y2; ZS[ 4] = zs[1]; XS[ 5] = x3; YS[ 5] = y3; ZS[ 5] = (zs[1] + zs[2]) / 2f + R.range(v) - v / 2; XS[ 6] = x3; YS[ 6] = y4; ZS[ 6] = zs[2]; XS[ 7] = x2; YS[ 7] = y5; ZS[ 7] = (zs[2] + zs[3]) / 2f + R.range(v) - v / 2; XS[ 8] = x1; YS[ 8] = y4; ZS[ 8] = zs[3]; XS[ 9] = x1; YS[ 9] = y3; ZS[ 9] = (zs[3] + zs[4]) / 2f + R.range(v) - v / 2; XS[10] = x0; YS[10] = y2; ZS[10] = zs[4]; XS[11] = x0; YS[11] = y1; ZS[11] = (zs[4] + zs[5]) / 2f + R.range(v) - v / 2; XS[12] = x2; YS[12] = y2; ZS[12] = (zs[0] + zs[1] + zs[2] + zs[3] + zs[4] + zs[5]) / 6f; // sub-hexagons given select coordinates order[0] = 0; order[1] = 1; order[2] = 12; order[3] = 9; order[4] = 10; order[5] = 11; children[0] = new Hexagon(XS, YS, ZS, order, !verticle); order[0] = 2; order[1] = 3; order[2] = 4; order[3] = 5; order[4] = 12; order[5] = 1; children[1] = new Hexagon(XS, YS, ZS, order, !verticle); order[0] = 12; order[1] = 5; order[2] = 6; order[3] = 7; order[4] = 8; order[5] = 9; children[2] = new Hexagon(XS, YS, ZS, order, !verticle); xs = null; ys = null; zs = null; } } // add triangles to current model for n'th hexagon private int internalGetObject(Vector[] vs, int[] ts, Color[] cs, int hex) { // either by accessing children if (children != null) { for (int i = 0; i < 3; i++) hex = children[i].internalGetObject(vs, ts, cs, hex); return hex; } // or calculating from coordinates else { int hex7 = 7 * hex; vs[hex7 + 0] = new Vector(xs[0], ys[0], zs[0]); vs[hex7 + 1] = new Vector(xs[1], ys[1], zs[1]); vs[hex7 + 2] = new Vector(xs[2], ys[2], zs[2]); vs[hex7 + 3] = new Vector(xs[3], ys[3], zs[3]); vs[hex7 + 4] = new Vector(xs[4], ys[4], zs[4]); vs[hex7 + 5] = new Vector(xs[5], ys[5], zs[5]); if (verticle) vs[hex7 + 6] = new Vector(xs[0], (ys[0] + ys[3]) / 2f, (zs[0] + zs[1] + zs[2] + zs[3] + zs[4] + zs[5]) / 6f); else vs[hex7 + 6] = new Vector((xs[0] + xs[5]) / 2f, ys[1], (zs[0] + zs[1] + zs[2] + zs[3] + zs[4] + zs[5]) / 6f); int hex18 = 18 * hex; ts[hex18 + 0] = hex7 + 0; ts[hex18 + 1] = hex7 + 1; ts[hex18 + 2] = hex7 + 6; ts[hex18 + 3] = hex7 + 1; ts[hex18 + 4] = hex7 + 2; ts[hex18 + 5] = hex7 + 6; ts[hex18 + 6] = hex7 + 2; ts[hex18 + 7] = hex7 + 3; ts[hex18 + 8] = hex7 + 6; ts[hex18 + 9] = hex7 + 3; ts[hex18 + 10] = hex7 + 4; ts[hex18 + 11] = hex7 + 6; ts[hex18 + 12] = hex7 + 4; ts[hex18 + 13] = hex7 + 5; ts[hex18 + 14] = hex7 + 6; ts[hex18 + 15] = hex7 + 5; ts[hex18 + 16] = hex7 + 0; ts[hex18 + 17] = hex7 + 6; int hex6 = 6 * hex; cs[hex6 + 0] = Color.white; cs[hex6 + 1] = Color.white; cs[hex6 + 2] = Color.white; cs[hex6 + 3] = Color.white; cs[hex6 + 4] = Color.white; cs[hex6 + 5] = Color.white; return hex + 1; } } public Hexagon(Random R, float X, float Y, float Z, float L, float S) { variation = L * S; size = 6; int v = (int) (variation); float h = L / 2f; // first hexagon is pointy side upwards verticle = true; xs = new float[6]; ys = new float[6]; zs = new float[6]; xs[0] = X + (float) Math.sin(D000) * h; ys[0] = Y - (float) Math.cos(D000) * h; zs[0] = Z + R.range(v) - v / 2; xs[1] = X + (float) Math.sin(D060) * h; ys[1] = Y - (float) Math.cos(D060) * h; zs[1] = Z + R.range(v) - v / 2; xs[2] = X + (float) Math.sin(D120) * h; ys[2] = Y - (float) Math.cos(D120) * h; zs[2] = Z + R.range(v) - v / 2; xs[3] = X + (float) Math.sin(D180) * h; ys[3] = Y - (float) Math.cos(D180) * h; zs[3] = Z + R.range(v) - v / 2; xs[4] = X + (float) Math.sin(-D120) * h; ys[4] = Y - (float) Math.cos(-D120) * h; zs[4] = Z + R.range(v) - v / 2; xs[5] = X + (float) Math.sin(-D060) * h; ys[5] = Y - (float) Math.cos(-D060) * h; zs[5] = Z + R.range(v) - v / 2; } public void recurse(Random R) { variation /= 2f; size *= 3; internalRecursion(R, variation); } public int getSize() { return size; } public Entity getObject() { Vector[] vs = new Vector[size + size / 6]; int[] ts = new int[3 * size]; Color[] cs = new Color[size]; internalGetObject(vs, ts, cs, 0); return new Entity(vs, ts, cs, null); } }