From cb37a129d1adb403019c96e798e86e2da9667f15 Mon Sep 17 00:00:00 2001 From: Normand Briere <nbriere@noware.ca> Date: Sun, 17 Nov 2019 17:56:04 -0500 Subject: [PATCH] Maze --- ObjEditor.java | 2 Maze.java | 129 +++++++++++++++++++++++++ GroupEditor.java | 134 +++++++++++++++++++++++--- Object3D.java | 16 ++ 4 files changed, 259 insertions(+), 22 deletions(-) diff --git a/GroupEditor.java b/GroupEditor.java index d6b309a..f47872a 100644 --- a/GroupEditor.java +++ b/GroupEditor.java @@ -2052,6 +2052,8 @@ } menu.add("-"); + mazeItem = menu.add(new MenuItem("Maze")); + mazeItem.addActionListener(this); parseverticesItem = menu.add(new MenuItem("Multiplicity")); parseverticesItem.addActionListener(this); textureFieldItem = menu.add(new MenuItem("Texture Field")); @@ -2247,6 +2249,111 @@ elem.openEditWindow(this, newWindow); //, false); System.out.println("edit : " + elem); elem.editWindow.refreshContents(true); // ? new + } + + private void GenerateMaze() + { + if (group.selection.size() == 4) + { + final double scaleX = SelectionSizeX(); + final double scaleZ = SelectionSizeZ(); + + final cGroup mazeGroup = new cGroup("Maze"); + + final int dim = 15; + + Maze maze = new Maze(dim, dim); + + maze.display(); // console + + maze.Display(new Maze.Parse() + { + public void Tile(int i, int j, boolean north, boolean east, boolean south, boolean west) + { + if ((i == 0 || i == dim-1) && j == dim/2) + { + return; + } + + int v = 0; + if (north) + { + cGroup n = new cGroup("" + i + "," + j); + n.Translate(-j * scaleX, 0, i * scaleZ); + n.add(group.selection.get(0)); + mazeGroup.add(n); + } + if (east) + { + cGroup n = new cGroup("" + i + "," + j); + n.Translate(-j * scaleX, 0, i * scaleZ); + n.add(group.selection.get(1)); + mazeGroup.add(n); + } + if (south) + { + cGroup n = new cGroup("" + i + "," + j); + n.Translate(-j * scaleX, 0, i * scaleZ); + n.add(group.selection.get(2)); + mazeGroup.add(n); + } + if (west) + { + cGroup n = new cGroup("" + i + "," + j); + n.Translate(-j * scaleX, 0, i * scaleZ); + n.add(group.selection.get(3)); + mazeGroup.add(n); + } + } + } + ); + + makeSomething(mazeGroup); + } + } + + private double SelectionSize() + { + cVector bbmin = new cVector(); + cVector bbmax = new cVector(); + + group.selection.getBounds(bbmin, bbmax, true); + + double dx = bbmax.x - bbmin.x; + //double dy = bbmax.y - bbmin.y; + double dz = bbmax.z - bbmin.z; + + return Math.sqrt(dx*dx /*+ dy*dy*/ + dz*dz); + } + + private double SelectionSizeX() + { + cVector bbmin = new cVector(); + cVector bbmax = new cVector(); + + group.selection.getBounds(bbmin, bbmax, true); + + return bbmax.x - bbmin.x; + } + + private double SelectionSizeY() + { + cVector bbmin = new cVector(); + cVector bbmax = new cVector(); + + group.selection.getBounds(bbmin, bbmax, true); + + return bbmax.y - bbmin.y; + } + + private double SelectionSizeZ() + { + cVector bbmin = new cVector(); + cVector bbmax = new cVector(); + + group.selection.getBounds(bbmin, bbmax, true); + + return bbmax.z - bbmin.z; } /** @@ -3590,6 +3697,10 @@ { ReverseNormals(); } else + if (source == mazeItem) + { + GenerateMaze(); + } else if (source == parseverticesItem) { ParseVertices(); @@ -4874,29 +4985,13 @@ if (group.selection.size() == 0) return; - cVector bbmin = new cVector(); - cVector bbmax = new cVector(); - - group.selection.get(0).getBounds(bbmin, bbmax, true); - - double dx = bbmax.x - bbmin.x; - double dy = bbmax.y - bbmin.y; - double dz = bbmax.z - bbmin.z; - - double scale = Math.sqrt(dx*dx + dy*dy + dz*dz); + double scale = SelectionSize(); for (int i=0; i<group.selection.size(); i++) { Object3D obj = group.selection.get(i); - if (obj.toParent == null) - { - obj.toParent = LA.newMatrix(); - obj.fromParent = LA.newMatrix(); - } - - LA.matTranslate(obj.toParent, i * scale, 0, 0); - LA.matTranslateInv(obj.fromParent, -i * scale, 0, 0); + obj.Translate(i * scale, 0, 0); } Globals.lighttouched = true; @@ -6429,8 +6524,9 @@ private MenuItem unstripifyItem; private MenuItem trimItem; private MenuItem untrimItem; - private MenuItem clearColorsItem; + + private MenuItem mazeItem; private MenuItem parseverticesItem; private MenuItem alignItem; private MenuItem mirrorItem; diff --git a/Maze.java b/Maze.java new file mode 100644 index 0000000..13295e2 --- /dev/null +++ b/Maze.java @@ -0,0 +1,129 @@ + +import java.util.Collections; +import java.util.Arrays; + +/* + * recursive backtracking algorithm + * shamelessly borrowed from the ruby at + * http://weblog.jamisbuck.org/2010/12/27/maze-generation-recursive-backtracking + */ +public class Maze +{ + public interface Parse + { + void Tile(int i, int j, boolean north, boolean east, boolean south, boolean west); + }; + + private int dimx; + private int dimy; + private byte[][] maze; + + public Maze(int x, int y) + { + this.dimx = x; + this.dimy = y; + maze = new byte[this.dimx][this.dimy]; + generateMaze(0, 0); + } + + public void Display(Parse p) + { + for (int j = 0; j < dimy; j++) + { + for (int i = 0; i < dimx; i++) + { + boolean n = (maze[i][j] & 1) == 0; + boolean e = true; + if (i < dimx-1) + e = (maze[i+1][j] & 8) == 0; + boolean w = (maze[i][j] & 8) == 0; + boolean s = true; + if (j < dimy-1) + s = (maze[i][j+1] & 1) == 0; + p.Tile(i, j, n, e, s, w); + } + } + } + + public void display() + { + for (int j = 0; j < dimy; j++) + { + // draw the north edge + for (int i = 0; i < dimx; i++) + { + System.out.print((maze[i][j] & 1) == 0 ? "+---" : "+ "); + } + System.out.println("+"); + // draw the west edge + for (int i = 0; i < dimx; i++) + { + System.out.print((maze[i][j] & 8) == 0 ? "| " : " "); + } + System.out.println("|"); + } + + // draw the bottom line + for (int j = 0; j < dimx; j++) + { + System.out.print("+---"); + } + System.out.println("+"); + } + + private void generateMaze(int cx, int cy) + { + DIR[] dirs = DIR.values(); + Collections.shuffle(Arrays.asList(dirs)); // Works because of elementData = collection.toArray() in ArrayList constructor. + for (DIR dir : dirs) + { + int nx = cx + dir.dx; + int ny = cy + dir.dy; + if (between(nx, dimx) && between(ny, dimy) && (maze[nx][ny] == 0)) + { + maze[cx][cy] |= dir.bit; + maze[nx][ny] |= dir.opposite.bit; + generateMaze(nx, ny); + } + } + } + + private static boolean between(int v, int upper) + { + return (v >= 0) && (v < upper); + } + + private enum DIR + { + N(1, 0, -1), E(2, 1, 0), S(4, 0, 1), W(8, -1, 0); + + private final int bit; + private final int dx; + private final int dy; + private DIR opposite; + + // use the static initializer to resolve forward references + static + { + N.opposite = S; + S.opposite = N; + E.opposite = W; + W.opposite = E; + } + + private DIR(int bit, int dx, int dy) + { + this.bit = bit; + this.dx = dx; + this.dy = dy; + } + }; + + public static void main(String[] args) + { + int x = args.length >= 1 ? (Integer.parseInt(args[0])) : 3; + int y = args.length == 2 ? (Integer.parseInt(args[1])) : 3; + Maze maze = new Maze(x, y); + maze.display(); + } +} diff --git a/ObjEditor.java b/ObjEditor.java index 778de2f..ab56542 100644 --- a/ObjEditor.java +++ b/ObjEditor.java @@ -563,7 +563,7 @@ // } cameraView.transformMode = objectTabbedPane.getSelectedIndex() == transformTabIndex; - if (copy.selection.size() == 1) + if (copy.selection.size() == 1 && objectTabbedPane.getSelectedIndex() > 1) // Not backgrounds and objects { copy.selection.get(0).tabIndex = objectTabbedPane.getSelectedIndex() + 1; } diff --git a/Object3D.java b/Object3D.java index f4c3fee..bcefc4f 100644 --- a/Object3D.java +++ b/Object3D.java @@ -6957,8 +6957,8 @@ //javax.media.opengl.GL gl = display.GetGL(); - if (CameraPane.BOXMODE && //!Link2Support()) // - !selected) // || CameraPane.movingcamera) + if (CameraPane.BOXMODE && !Link2Support()) // + //!selected) // || CameraPane.movingcamera) { int fc = bRep.FaceCount(); int vc = bRep.VertexCount(); @@ -9266,5 +9266,17 @@ return -1; } */ + + void Translate(double x, double y, double z) + { + if (toParent == null) + { + toParent = LA.newMatrix(); + fromParent = LA.newMatrix(); + } + + LA.matTranslate(toParent, x, y, z); + LA.matTranslateInv(fromParent, -x, -y, -z); + } } -- Gitblit v1.6.2