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