Anonymous avatar Anonymous committed 7714586

start of actually porting squidlib FOV/LOS -- BresenhamLOS done

Comments (0)

Files changed (8)

src/main/java/net/fishbulb/jcod/fov/BresenhamLOS.java

 package net.fishbulb.jcod.fov;
 
-import net.fishbulb.jcod.util.Bresenham;
+import lombok.Getter;
+import net.fishbulb.jcod.util.PlotAlgorithms;
 
-import java.awt.Point;
-import java.util.LinkedList;
-import java.util.Queue;
+import static net.fishbulb.jcod.util.PlotAlgorithms.bresenham;
 
 /**
  * A Bresenham-based line-of-sight algorithm.
  *
- * @author Eben Howard - http://squidpony.com - howard@squidpony.com
+ * Adapted from SquidPony implementation by Eben Howard - http://squidpony.com - howard@squidpony.com
  */
 public class BresenhamLOS implements LOSSolver {
+    class LOSFunction implements PlotAlgorithms.PlotFunction {
+        private float[][] resistanceMap;
+        private final int startx;
+        private final int starty;
+        float currentForce;
+        private final float decay;
+        private final RadiusStrategy radiusStrategy;
 
-    Queue<Point> lastPath = new LinkedList<>();
+        @Getter
+        boolean reachable = true;
+
+        LOSFunction(float[][] resistanceMap, int startx, int starty, float currentForce, float decay, RadiusStrategy radiusStrategy) {
+            this.resistanceMap = resistanceMap;
+            this.startx = startx;
+            this.starty = starty;
+            this.currentForce = currentForce;
+            this.decay = decay;
+            this.radiusStrategy = radiusStrategy;
+        }
+
+        @Override public boolean apply(int x, int y) {
+            if (x != startx || y != starty) {
+                currentForce *= (1 - resistanceMap[x][y]);
+            }
+            double radius = radiusStrategy.radius(startx, starty, x, y);
+            reachable = currentForce - (radius * decay) > 0;
+            return reachable;
+        }
+    }
 
     @Override
     public boolean isReachable(float[][] resistanceMap, int startx, int starty, int targetx, int targety, float force, float decay, RadiusStrategy radiusStrategy) {
-        Queue<Point> path = Bresenham.line2D(startx, starty, targetx, targety);
-        lastPath = new LinkedList<>(path);//save path for later retreival
-        float currentForce = force;
-        for (Point p : path) {
-            if (p.x == targetx && p.y == targety) {
-                return true;//reached the end 
-            }
-            if (p.x != startx || p.y != starty) {//don't discount the start location even if on resistant cell
-                currentForce *= (1 - resistanceMap[p.x][p.y]);
-            }
-            double radius = radiusStrategy.radius(startx, starty, p.x, p.y);
-            if (currentForce - (radius * decay) <= 0) {
-                return false;//too much resistance
-            }
-        }
-        return false;//never got to the target point
-    }
-
-    @Override
-    public Queue<Point> getLastPath() {
-        return lastPath;
+        LOSFunction solver = new LOSFunction(resistanceMap, startx, starty, force, decay, radiusStrategy);
+        bresenham(startx, starty, targetx, targety, solver);
+        return solver.isReachable();
     }
 
     @Override

src/main/java/net/fishbulb/jcod/fov/EliasLOS.java

         return isReachable(resistanceMap, startx, starty, targetx, targety, Float.MAX_VALUE, 0f, BasicRadiusStrategy.CIRCLE);
     }
 
-    @Override
-    public Queue<Point> getLastPath() {
-        return lastPath;
-    }
 }

src/main/java/net/fishbulb/jcod/fov/FOVSolver.java

  * amount of view (typically sight, but perhaps sound, smell, etc.) which the
  * origin has of each cell.
  *
- * The force parameter allows tiles to have a varying resistance to the kind of
+ * The currentForce parameter allows tiles to have a varying resistance to the kind of
  * rays emanating from the source. This parameter is a percentage of light
  * passed so 1f or higher will block all light. 0f or lower will block no light.
  *
- * If a simple radius is desired, set the resistance of your cells to 0f, the force
+ * If a simple radius is desired, set the resistance of your cells to 0f, the currentForce
  * to 1f, and the decay to 1f / (the radius).
  *
  * The coordinates of the returned structure match those of the input grid.

src/main/java/net/fishbulb/jcod/fov/LOSSolver.java

 package net.fishbulb.jcod.fov;
 
-import java.awt.Point;
-import java.util.Queue;
-
 /**
  * An interface for Line of Sight algorithms.
  *
  *
  * If the decay is set to 0 then the line will be run until an obstruction or
  * target is reached. Otherwise the target is considered not reached if the
- * calculation of force, decay, and resistances prevent the line from reaching
+ * calculation of currentForce, decay, and resistances prevent the line from reaching
  * the target.
  *
  * @author Eben Howard - http://squidpony.com - howard@squidpony.com
      * @param targetx
      * @param targety
      * @param force the amount of impetus to start with
-     * @param decay the amount the force is reduced per unit distance
+     * @param decay the amount the currentForce is reduced per unit distance
      * @param radiusStrategy the strategy to use in computing unit distance
      * @return
      */
      * @return
      */
     public boolean isReachable(float[][] resistanceMap, int startx, int starty, int targetx, int targety);
-
-    /**
-     * Returns the path of the last LOS calculation, with the starting point as
-     * the head of the queue.
-     *
-     * @return
-     */
-    public Queue<Point> getLastPath();
 }

src/main/java/net/fishbulb/jcod/fov/RayCastingLOS.java

     public boolean isReachable(float[][] resistanceMap, int startx, int starty, int targetx, int targety) {
         return isReachable(resistanceMap, startx, starty, targetx, targety, 1, 0, BasicRadiusStrategy.CIRCLE);
     }
-
-    @Override
-    public Queue<Point> getLastPath() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
 }

src/main/java/net/fishbulb/jcod/fov/ShadowFOV.java

 
 
 /**
- * Recursive shadowcasting FOV. Uses force * decay for the radius calculation
+ * Recursive shadowcasting FOV. Uses currentForce * decay for the radius calculation
  * and treats all translucent cells as fully transparent.
  *
  * Performs bounds checking so edges are not required to be opaque.

src/main/java/net/fishbulb/jcod/fov/TranslucenceWrapperFOV.java

         lightMap = new float[width][height];
         shadowMap = fov.calculateFOV(resistanceMap, startx, starty, force, decay, radiusStrategy);
 
-        lightMap[startx][starty] = force;//start out at full force
+        lightMap[startx][starty] = force;//start out at full currentForce
         for (Direction dir : Direction.OUTWARDS) {
             pushLight(startx + dir.deltaX, starty + dir.deltaY, force + decay, dir, dir, RayType.PRIMARY);
         }

src/main/java/net/fishbulb/jcod/util/Bresenham.java

-package net.fishbulb.jcod.util;
-
-import java.awt.Point;
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * Provides a means to generate Bresenham lines in 2D and 3D.
- *
- * @author Eben Howard - http://squidpony.com - howard@squidpony.com
- * @author Lewis Potter
- */
-public class Bresenham {
-
-    /**
-     * Prevents any instances from being created
-     */
-    private Bresenham() {
-    }
-
-    /**
-     * Generates a 2D Bresenham line between two points.
-     *
-     * @param a
-     * @param b
-     * @return
-     */
-    public static Queue<Point> line2D(Point a, Point b) {
-        return line2D(a.x, a.y, b.x, b.y);
-    }
-
-    /**
-     * Generates a 2D Bresenham line between two points.
-     *
-     * @param startX
-     * @param startY
-     * @param endX
-     * @param endY
-     * @return
-     */
-    public static Queue<Point> line2D(int startX, int startY, int endX, int endY) {
-        Queue<Point> line = new LinkedList<>();
-        Queue<Point3D> found = line3D(startX, startY, 0, endX, endY, 0);
-        while (!found.isEmpty()) {
-            line.offer(found.poll());
-        }
-        return line;
-    }
-
-    /**
-     * Generates a 3D Bresenham line between two points.
-     *
-     * @param a Point to start from. This will be the first element of the list
-     * @param b Point to end at. This will be the last element of the list.
-     * @return A list of points between a and b.
-     */
-    public static Queue<Point3D> line3D(Point3D a, Point3D b) {
-        return line3D(a.x, a.y, a.z, b.x, b.y, b.z);
-    }
-
-    /**
-     * Generates a 3D Bresenham line between the given coordinates.
-     *
-     * @param startx
-     * @param starty
-     * @param startz
-     * @param endx
-     * @param endy
-     * @param endz
-     * @return
-     */
-    public static Queue<Point3D> line3D(int startx, int starty, int startz, int endx, int endy, int endz) {
-        Queue<Point3D> result = new LinkedList<>();
-
-        int dx = endx - startx;
-        int dy = endy - starty;
-        int dz = endz - startz;
-
-        int ax = Math.abs(dx) << 1;
-        int ay = Math.abs(dy) << 1;
-        int az = Math.abs(dz) << 1;
-
-        int signx = (int) Math.signum(dx);
-        int signy = (int) Math.signum(dy);
-        int signz = (int) Math.signum(dz);
-
-        int x = startx;
-        int y = starty;
-        int z = startz;
-
-        int deltax, deltay, deltaz;
-        if (ax >= Math.max(ay, az)) /* x dominant */ {
-            deltay = ay - (ax >> 1);
-            deltaz = az - (ax >> 1);
-            while (true) {
-                result.offer(new Point3D(x, y, z));
-                if (x == endx) {
-                    return result;
-                }
-
-                if (deltay >= 0) {
-                    y += signy;
-                    deltay -= ax;
-                }
-
-                if (deltaz >= 0) {
-                    z += signz;
-                    deltaz -= ax;
-                }
-
-                x += signx;
-                deltay += ay;
-                deltaz += az;
-            }
-        } else if (ay >= Math.max(ax, az)) /* y dominant */ {
-            deltax = ax - (ay >> 1);
-            deltaz = az - (ay >> 1);
-            while (true) {
-                result.offer(new Point3D(x, y, z));
-                if (y == endy) {
-                    return result;
-                }
-
-                if (deltax >= 0) {
-                    x += signx;
-                    deltax -= ay;
-                }
-
-                if (deltaz >= 0) {
-                    z += signz;
-                    deltaz -= ay;
-                }
-
-                y += signy;
-                deltax += ax;
-                deltaz += az;
-            }
-        } else if (az >= Math.max(ax, ay)) /* z dominant */ {
-            deltax = ax - (az >> 1);
-            deltay = ay - (az >> 1);
-            while (true) {
-                result.offer(new Point3D(x, y, z));
-                if (z == endz) {
-                    return result;
-                }
-
-                if (deltax >= 0) {
-                    x += signx;
-                    deltax -= az;
-                }
-
-                if (deltay >= 0) {
-                    y += signy;
-                    deltay -= az;
-                }
-
-                z += signz;
-                deltax += ax;
-                deltay += ay;
-            }
-        }
-        return result;
-    }
-}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.