Commits

Karsten Schmidt committed 3dbfdb5

refactored sheet layout algorithm into strategy pattern using new UnwrapLayoutStrategy and DefaultLayout as its current implementation

  • Participants
  • Parent commits 1d63a72

Comments (0)

Files changed (3)

src/flatworld/DefaultLayout.java

+package flatworld;
+
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import toxi.math.MathUtils;
+
+public class DefaultLayout implements UnwrapLayoutStrategy {
+
+    protected int maxSearchIterations;
+
+    public DefaultLayout() {
+        this(100);
+    }
+
+    public DefaultLayout(int maxSearchIterations) {
+        this.maxSearchIterations = maxSearchIterations;
+    }
+
+    protected float getMinDistanceOnSheet(UnwrappedFace face, UnwrapSheet sheet) {
+        float minDist = Float.MAX_VALUE;
+        for (UnwrappedFace f : sheet.faces) {
+            float d = face.sheetPos.distanceToSquared(f.sheetPos);
+            if (d < minDist) {
+                minDist = d;
+            }
+        }
+        return minDist;
+    }
+
+    public boolean placeFace(UnwrappedFace face, List<UnwrapSheet> sheets) {
+        UnwrapSheet bestSheet = null;
+        Vec2D bestPos = null;
+        float bestTheta = 0;
+        float minDist = Float.MAX_VALUE;
+        face.setPosition(new Vec2D(), 0);
+        float faceArea = face.getArea();
+        boolean isPlaced = false;
+        for (UnwrapSheet sheet : sheets) {
+            if (sheet.getFreeArea() >= faceArea) {
+                for (int i = 0; i < maxSearchIterations; i++) {
+                    Vec2D pos = sheet.getRandomPos();
+                    float theta = MathUtils.random(MathUtils.TWO_PI);
+                    face.setPosition(pos, theta);
+                    if (sheet.isFacePlacable(face)) {
+                        float dist = getMinDistanceOnSheet(face, sheet);
+                        if (dist <= minDist) {
+                            bestSheet = sheet;
+                            bestPos = pos;
+                            bestTheta = theta;
+                            minDist = dist;
+                        }
+                    }
+                }
+            }
+        }
+        if (bestSheet != null) {
+            face.setPosition(bestPos, bestTheta);
+            bestSheet.add(face);
+            isPlaced = true;
+        }
+        return isPlaced;
+    }
+}

src/flatworld/UnwrapLayoutStrategy.java

+package flatworld;
+
+import java.util.List;
+
+public interface UnwrapLayoutStrategy {
+
+    public boolean placeFace(UnwrappedFace face, List<UnwrapSheet> sheets);
+}

src/flatworld/Unwrapper.java

 import toxi.geom.mesh.WEFace;
 import toxi.geom.mesh.WETriangleMesh;
 import toxi.geom.mesh.WingedEdge;
-import toxi.math.MathUtils;
 
 public class Unwrapper {
 
 
     protected EdgeRenderStrategy edgeStrategy;
 
-    private int maxSearchIterations = 100;
+    private UnwrapLayoutStrategy layout;
 
     public Unwrapper(int width, int height) {
+        this(width, height, new DefaultLayout());
+    }
+
+    public Unwrapper(int width, int height, UnwrapLayoutStrategy layout) {
         this.sheetWidth = width;
         this.sheetHeight = height;
-    }
-
-    private boolean attemptToAddFaceToSheet(UnwrappedFace face,
-            List<UnwrapSheet> sheets) {
-        UnwrapSheet bestSheet = null;
-        Vec2D bestPos = null;
-        float bestTheta = 0;
-        float minDist = Float.MAX_VALUE;
-        face.setPosition(new Vec2D(), 0);
-        float faceArea = face.getArea();
-        boolean isPlaced = false;
-        for (UnwrapSheet sheet : sheets) {
-            if (sheet.getFreeArea() >= faceArea) {
-                for (int i = 0; i < maxSearchIterations; i++) {
-                    Vec2D pos = sheet.getRandomPos();
-                    float theta = MathUtils.random(MathUtils.TWO_PI);
-                    face.setPosition(pos, theta);
-                    if (sheet.isFacePlacable(face)) {
-                        float dist = getMinDistanceOnSheet(face, sheet);
-                        if (dist <= minDist) {
-                            bestSheet = sheet;
-                            bestPos = pos;
-                            bestTheta = theta;
-                            minDist = dist;
-                        }
-                    }
-                }
-            }
-        }
-        if (bestSheet != null) {
-            face.setPosition(bestPos, bestTheta);
-            bestSheet.add(face);
-            isPlaced = true;
-        }
-        return isPlaced;
+        this.layout = layout;
     }
 
     private UnwrapEdge getEdgeFor(WEFace f, Vec3D v, Vec3D w) {
         return edgeStrategy;
     }
 
-    /**
-     * @return the maxSearchIterations
-     */
-    public int getMaxSearchIterations() {
-        return maxSearchIterations;
-    }
-
-    private float getMinDistanceOnSheet(UnwrappedFace face, UnwrapSheet sheet) {
-        float minDist = Float.MAX_VALUE;
-        for (UnwrappedFace f : sheet.faces) {
-            float d = face.sheetPos.distanceToSquared(f.sheetPos);
-            if (d < minDist) {
-                minDist = d;
-            }
-        }
-        return minDist;
-    }
-
     public List<UnwrapSheet> getSheets() {
         return sheets;
     }
         this.edgeStrategy = edgeStrategy;
     }
 
-    /**
-     * @param maxSearchIterations
-     *            the maxSearchIterations to set
-     */
-    public void setMaxSearchIterations(int maxSearchIterations) {
-        this.maxSearchIterations = maxSearchIterations;
-    }
-
     public void unwrapMesh(WETriangleMesh mesh, float scale) {
         sheets.clear();
         int id = 1;
             UnwrapEdge eca = getEdgeFor(ff, fc, fa);
             UnwrappedFace face =
                     new UnwrappedFace(tri, id++, scale, eab, ebc, eca);
-            boolean isPlaced = attemptToAddFaceToSheet(face, sheets);
+            boolean isPlaced = layout.placeFace(face, sheets);
             if (!isPlaced) {
                 UnwrapSheet sheet = new UnwrapSheet(sheetWidth, sheetHeight);
-                attemptToAddFaceToSheet(face, Collections.singletonList(sheet));
+                layout.placeFace(face, Collections.singletonList(sheet));
                 sheets.add(sheet);
             }
         }