Class FOV

java.lang.Object
squidpony.squidgrid.FOV
All Implemented Interfaces:
Serializable

public class FOV
extends Object
implements Serializable
This class provides methods for calculating Field of View in grids. Field of View (FOV) algorithms determine how much area surrounding a point can be seen. They return a 2D array of doubles, representing the amount of view (typically sight, but perhaps sound, smell, etc.) which the origin has of each cell. In the returned 2D array, 1.0 is always "fully seen," while 0.0 is always "unseen." Values in between are much more common, and they enable this class to be used for lighting effects.
The input resistanceMap is considered the percent of opacity. This resistance is on top of the resistance applied from the light spreading out. You can obtain a resistance map easily with the generateResistances(char[][]) method, which uses defaults for common chars used in SquidLib, but you may also want to create a resistance map manually if a given char means something very different in your game. This is easy enough to do by looping over all the x,y positions in your char[][] map and running a switch statement on each char, assigning a double to the same x,y position in a double[][]. The value should be between 0.0 (unblocked) for things light passes through, 1.0 (blocked) for things light can't pass at all, and possibly other values if you have translucent obstacles. There's generateSimpleResistances(char[][]) as well, which only returns 1.0 (fully blocked) or 0.0 (passable), and 3x3 subcell variants, which produce a resistance map that is 3 times wider and 3 times taller than the input map. The subcell variants have especially useful behavior when using DungeonUtility.hashesToLines(char[][]) to draw a map with box-drawing characters, since these 3x3 resistance maps will line up blocking cells to where a box-drawing line is.
The returned light map is considered the percent of light in the cells.
All implementations for FOV here (that is, Ripple FOV and Shadow FOV) provide percentage levels for partially-lit or partially-seen cells. This leads to a straightforward implementation of soft lighting using an FOV result -- just mix the background or floor color of a cell, however you represent it, with a very light color (like pastel yellow), with the percentage of the light color to mix in equal to the percent of light in the FOV map.
All solvers perform bounds checking so solid borders in the map are not required.
For calculating FOV maps, this class provides both instance methods, which attempt to reuse the same 2D array for light stored in the object, and static methods, which take a light 2D array as an argument and edit it in-place. In older versions of SquidLib, constantly allocating and returning 2D double arrays on each call dragged performance down, but both of the new methods should perform well.
Static methods are provided to add together FOV maps in the simple way (disregarding visibility of distant FOV from a given cell), or the more practical way for roguelikes (where a cell needs to be within line-of-sight in the first place for a distant light to illuminate it). The second method relies on an LOS map, which is essentially the same as a very-high-radius FOV map and can be easily obtained with calculateLOSMap().
If you want to iterate through cells that are visible in a double[][] returned by FOV, you can pass that double[][] to the constructor for GreasedRegion, and you can use the GreasedRegion as a reliably-ordered Collection of Coord (among other things). The order GreasedRegion iterates in is somewhat strange, and doesn't, for example, start at the center of an FOV map, but it will be the same every time you create a GreasedRegion with the same FOV map (or the same visible Coords).
This class is not thread-safe. This is generally true for most of SquidLib.
Author:
Eben Howard - http://squidpony.com - howard@squidpony.com
See Also:
Serialized Form
  • Field Summary

    Fields 
    Modifier and Type Field Description
    protected static Direction[] ccw  
    protected static Direction[] ccw_full  
    protected double[][] light
    Data allocated in the previous calls to the public API, if any.
    protected GreasedRegion nearLight
    Data allocated in the previous calls to the public API, if any.
    static int RIPPLE
    Performs FOV by pushing values outwards from the source location.
    static int RIPPLE_LOOSE
    Performs FOV by pushing values outwards from the source location.
    static int RIPPLE_TIGHT
    Performs FOV by pushing values outwards from the source location.
    static int RIPPLE_VERY_LOOSE
    Performs FOV by pushing values outwards from the source location.
    static int SHADOW
    Uses Shadow Casting FOV algorithm.
  • Constructor Summary

    Constructors 
    Constructor Description
    FOV()
    Creates a solver which will use the default SHADOW solver.
    FOV​(int type)
    Creates a solver which will use the provided FOV solver type, typically one of SHADOW (the default), RIPPLE, RIPPLE_TIGHT, RIPPLE_LOOSE, or RIPPLE_VERY_LOOSE.
  • Method Summary

    Modifier and Type Method Description
    static double[][] addFOVs​(double[][]... maps)
    Adds multiple FOV maps together in the simplest way possible; does not check line-of-sight between FOV maps.
    static double[][] addFOVs​(Iterable<double[][]> maps)
    Adds multiple FOV maps together in the simplest way possible; does not check line-of-sight between FOV maps.
    static double[][] addFOVsInto​(double[][] basis, double[][] addend)
    Adds an FOV map to another in the simplest way possible; does not check line-of-sight between FOV maps.
    static double[][] addFOVsInto​(double[][] basis, double[][]... maps)
    Adds multiple FOV maps to basis cell-by-cell, modifying basis; does not check line-of-sight between FOV maps.
    static double[][] bouncingLine​(double[][] resistanceMap, double[][] light, int startX, int startY, double distance, double angle)
    Reuses the existing light 2D array and fills it with a straight-line bouncing path of light that reflects its way through the given resistanceMap from startX, startY until it uses up the given distance.
    static double[][] calculateFOV​(double[][] resistanceMap, double[][] light, int startx, int starty)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    double[][] calculateFOV​(double[][] resistanceMap, int startx, int starty)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    double[][] calculateFOV​(double[][] resistanceMap, int startx, int starty, double radius)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    double[][] calculateFOV​(double[][] resistanceMap, int startX, int startY, double radius, Radius radiusTechnique)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    double[][] calculateFOV​(double[][] resistanceMap, int startX, int startY, double radius, Radius radiusTechnique, double angle, double span)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    double[][] calculateLOSMap​(double[][] resistanceMap, int startX, int startY)
    Calculates what cells are visible from (startX,startY) using the given resistanceMap; this can be given to mixVisibleFOVs() to limit extra light sources to those visible from the starting point.
    static double[][] generateResistances​(char[][] map)
    Given a char[][] for the map, produces a double[][] that can be used with most of the methods in FOV, like reuseFOV(double[][], double[][], int, int, double).
    static double[][] generateResistances3x3​(char[][] map)
    Given a char[][] for the map that should use box drawing characters (as produced by DungeonUtility.hashesToLines(char[][], boolean)), produces a double[][] with triple width and triple height that can be used with FOV methods like reuseFOV(double[][], double[][], int, int, double) in classes that use subcell lighting.
    static double[][] generateSimpleResistances​(char[][] map)
    Given a char[][] for the map, produces a double[][] that can be used with any FOV methods that expect a resistance map (like reuseFOV(double[][], double[][], int, int, double)), but does not treat any cells as partly transparent, only fully-blocking or fully-permitting light.
    static double[][] generateSimpleResistances3x3​(char[][] map)
    Given a char[][] for the map that should use box drawing characters (as produced by DungeonUtility.hashesToLines(char[][], boolean)), produces a double[][] with triple width and triple height that can be used with FOV's methods that expect a resistance map (like reuseFOV(double[][], double[][], int, int, double)) in classes that use subcell lighting.
    static double[][] mixVisibleFOVs​(double[][] losMap, double[][]... maps)
    Adds together multiple FOV maps, but only adds to a position if it is visible in the given LOS map.
    static double[][] mixVisibleFOVs​(double[][] losMap, Iterable<double[][]> maps)
    Adds together multiple FOV maps, but only adds to a position if it is visible in the given LOS map.
    static double[][] mixVisibleFOVsInto​(double[][] losMap, double[][] basis, double[][]... maps)
    Adds together multiple FOV maps, but only adds to a position if it is visible in the given LOS map.
    static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startx, int starty)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startx, int starty, double radius)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startX, int startY, double radius, Radius radiusTechnique)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startX, int startY, double radius, Radius radiusTechnique, double angle, double span)
    Calculates the Field Of View for the provided map from the given x, y coordinates, lighting at the given angle in degrees and covering a span centered on that angle, also in degrees.
    static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startX, int startY, double radius, Radius radiusTechnique, double angle, double forward, double sideForward, double side, double sideBack, double back)
    Calculates the Field Of View for the provided map from the given x, y coordinates, lighting with the view "pointed at" the given angle in degrees, extending to different ranges based on the direction the light is traveling.
    static double[][] reuseFOVSymmetrical​(double[][] resistanceMap, double[][] light, int startX, int startY, double radius, Radius radiusTechnique)
    Calculates the Field Of View for the provided map from the given x, y coordinates.
    static double[][] reuseLOS​(double[][] resistanceMap, double[][] light, int startX, int startY)
    Calculates which cells have line of sight from the given x, y coordinates.
    static double[][] reuseLOS​(double[][] resistanceMap, double[][] light, int startX, int startY, int minX, int minY, int maxX, int maxY)
    Calculates which cells have line of sight from the given x, y coordinates.
    static double[][] reuseRippleFOV​(double[][] resistanceMap, double[][] light, int rippleLooseness, int x, int y, double radius, Radius radiusTechnique)
    Like the reuseFOV(double[][], double[][], int, int, double, Radius) method, but this uses Ripple FOV with a configurable tightness/looseness (between 1, tightest, and 6, loosest).
    static double[][] reuseRippleFOV​(double[][] resistanceMap, double[][] light, int rippleLooseness, int x, int y, double radius, Radius radiusTechnique, double angle, double span)
    Like the reuseFOV(double[][], double[][], int, int, double, Radius, double, double) method, but this uses Ripple FOV with a configurable tightness/looseness (between 1, tightest, and 6, loosest).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

  • Method Details

    • calculateFOV

      public double[][] calculateFOV​(double[][] resistanceMap, int startx, int starty)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Returns a light map where the values represent a percentage of fully lit. The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations based on Euclidean calculations. The light will be treated as having infinite possible radius.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      startx - the horizontal component of the starting location
      starty - the vertical component of the starting location
      Returns:
      the computed light grid
    • calculateFOV

      public double[][] calculateFOV​(double[][] resistanceMap, int startx, int starty, double radius)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Returns a light map where the values represent a percentage of fully lit. The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations based on Euclidean calculations.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      startx - the horizontal component of the starting location
      starty - the vertical component of the starting location
      radius - the distance the light will extend to
      Returns:
      the computed light grid
    • calculateFOV

      public double[][] calculateFOV​(double[][] resistanceMap, int startX, int startY, double radius, Radius radiusTechnique)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Returns a light map where the values represent a percentage of fully lit. The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations are determined by the provided RadiusStrategy.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      radius - the distance the light will extend to
      radiusTechnique - provides a means to calculate the radius as desired
      Returns:
      the computed light grid
    • calculateFOV

      public double[][] calculateFOV​(double[][] resistanceMap, int startX, int startY, double radius, Radius radiusTechnique, double angle, double span)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Returns a light map where the values represent a percentage of fully lit. The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations are determined by the provided RadiusStrategy. A conical section of FOV is lit by this method if span is greater than 0.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      radius - the distance the light will extend to
      radiusTechnique - provides a means to calculate the radius as desired
      angle - the angle in degrees that will be the center of the FOV cone, 0 points right
      span - the angle in degrees that measures the full arc contained in the FOV cone
      Returns:
      the computed light grid
    • calculateFOV

      public static double[][] calculateFOV​(double[][] resistanceMap, double[][] light, int startx, int starty)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Assigns to, and returns, a light map where the values represent a percentage of fully lit. Always uses shadowcasting FOV, which allows this method to be static since it doesn't need to keep any state around, and can reuse the state the user gives it via the light parameter. The values in light are always cleared before this is run, because prior state can make this give incorrect results.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations based on Euclidean calculations. The light will be treated as having infinite possible radius.
      This static method is equivalent to the static method reuseFOV(double[][], double[][], int, int), but all of the overloads are called reuseFOV(), so this method name is discouraged for new code. Both delegate to reuseFOV(double[][], double[][], int, int, double, Radius) anyway.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - a non-null 2D double array that will have its contents overwritten, modified, and returned
      startx - the horizontal component of the starting location
      starty - the vertical component of the starting location
      Returns:
      the computed light grid (the same as light)
    • reuseFOV

      public static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startx, int starty)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Assigns to, and returns, a light map where the values represent a percentage of fully lit. Always uses shadowcasting FOV, which allows this method to be static since it doesn't need to keep any state around, and can reuse the state the user gives it via the light parameter. The values in light are always cleared before this is run, because prior state can make this give incorrect results.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations based on Euclidean calculations. The light will be treated as having infinite possible radius.
      This static method is equivalent to the static method calculateFOV(double[][], double[][], int, int), but all of the overloads are called reuseFOV(), so this method name is preferred in new code. Both delegate to reuseFOV(double[][], double[][], int, int, double, Radius) anyway.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - a non-null 2D double array that will have its contents overwritten, modified, and returned
      startx - the horizontal component of the starting location
      starty - the vertical component of the starting location
      Returns:
      the computed light grid (the same as light)
    • reuseFOV

      public static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startx, int starty, double radius)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Assigns to, and returns, a light map where the values represent a percentage of fully lit. Always uses shadowcasting FOV, which allows this method to be static since it doesn't need to keep any state around, and can reuse the state the user gives it via the light parameter. The values in light are always cleared before this is run, because prior state can make this give incorrect results.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations based on Euclidean calculations.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      startx - the horizontal component of the starting location
      starty - the vertical component of the starting location
      radius - the distance the light will extend to
      Returns:
      the computed light grid
    • reuseFOV

      public static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startX, int startY, double radius, Radius radiusTechnique)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Assigns to, and returns, a light map where the values represent a percentage of fully lit. Always uses shadowcasting FOV, which allows this method to be static since it doesn't need to keep any state around, and can reuse the state the user gives it via the light parameter. The values in light are always cleared before this is run, because prior state can make this give incorrect results.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations are determined by the provided RadiusStrategy.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - the grid of cells to assign to; may have existing values, and 0.0 is used to mean "unlit"
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      radius - the distance the light will extend to
      radiusTechnique - provides a means to calculate the radius as desired
      Returns:
      the computed light grid, which is the same 2D array as the value assigned to light
    • reuseFOVSymmetrical

      public static double[][] reuseFOVSymmetrical​(double[][] resistanceMap, double[][] light, int startX, int startY, double radius, Radius radiusTechnique)
      Calculates the Field Of View for the provided map from the given x, y coordinates. Assigns to, and returns, a light map where the values represent a percentage of fully lit. Always uses shadowcasting FOV, which allows this method to be static since it doesn't need to keep any state around, and can reuse the state the user gives it via the light parameter. The values in light are always cleared before this is run, because prior state can make this give incorrect results.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations are determined by the provided RadiusStrategy.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - the grid of cells to assign to; may have existing values, and 0.0 is used to mean "unlit"
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      radius - the distance the light will extend to
      radiusTechnique - provides a means to calculate the radius as desired
      Returns:
      the computed light grid, which is the same 2D array as the value assigned to light
    • reuseLOS

      public static double[][] reuseLOS​(double[][] resistanceMap, double[][] light, int startX, int startY)
      Calculates which cells have line of sight from the given x, y coordinates. Assigns to, and returns, a light map where the values are always either 0.0 for "not in line of sight" or 1.0 for "in line of sight," which doesn't mean a cell is actually visible if there's no light in that cell. Always uses shadowcasting FOV, which allows this method to be static since it doesn't need to keep any state around, and can reuse the state the user gives it via the light parameter. The values in light are always cleared before this is run, because prior state can make this give incorrect results.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations are pretty much irrelevant because the distance doesn't matter, only the presence of a clear line, but this uses Radius.SQUARE if it matters.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - the grid of cells to assign to; may have existing values, and 0.0 is used to mean "no line"
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      Returns:
      the computed light grid, which is the same 2D array as the value assigned to light
    • reuseLOS

      public static double[][] reuseLOS​(double[][] resistanceMap, double[][] light, int startX, int startY, int minX, int minY, int maxX, int maxY)
      Calculates which cells have line of sight from the given x, y coordinates. Assigns to, and returns, a light map where the values are always either 0.0 for "not in line of sight" or 1.0 for "in line of sight," which doesn't mean a cell is actually visible if there's no light in that cell. Always uses shadowcasting FOV, which allows this method to be static since it doesn't need to keep any state around, and can reuse the state the user gives it via the light parameter. The values in light are always cleared before this is run, because prior state can make this give incorrect results.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations are pretty much irrelevant because the distance doesn't matter, only the presence of a clear line, but this uses Radius.SQUARE if it matters.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - the grid of cells to assign to; may have existing values, and 0.0 is used to mean "no line"
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      Returns:
      the computed light grid, which is the same 2D array as the value assigned to light
    • reuseFOV

      public static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startX, int startY, double radius, Radius radiusTechnique, double angle, double span)
      Calculates the Field Of View for the provided map from the given x, y coordinates, lighting at the given angle in degrees and covering a span centered on that angle, also in degrees. Assigns to, and returns, a light map where the values represent a percentage of fully lit. Always uses shadowcasting FOV, which allows this method to be static since it doesn't need to keep any state around, and can reuse the state the user gives it via the light parameter. The values in light are cleared before this is run, because prior state can make this give incorrect results.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations are determined by the provided RadiusStrategy. A conical section of FOV is lit by this method if span is greater than 0.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - the grid of cells to assign to; may have existing values, and 0.0 is used to mean "unlit"
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      radius - the distance the light will extend to
      radiusTechnique - provides a means to shape the FOV by changing distance calculation (circle, square, etc.)
      angle - the angle in degrees that will be the center of the FOV cone, 0 points right
      span - the angle in degrees that measures the full arc contained in the FOV cone
      Returns:
      the computed light grid
    • reuseRippleFOV

      public static double[][] reuseRippleFOV​(double[][] resistanceMap, double[][] light, int rippleLooseness, int x, int y, double radius, Radius radiusTechnique)
      Like the reuseFOV(double[][], double[][], int, int, double, Radius) method, but this uses Ripple FOV with a configurable tightness/looseness (between 1, tightest, and 6, loosest). Other parameters are similar; you can get a resistance map from generateResistances(char[][]), light will be modified and returned (it will be overwritten, but its size should be the same as the resistance map), there's a starting x,y position, a radius in cells, and a Radius enum constant to choose the distance measurement.
      Parameters:
      resistanceMap - probably calculated with generateResistances(char[][]); 1.0 blocks light, 0.0 allows it
      light - will be overwritten! Should be initialized with the same size as resistanceMap
      rippleLooseness - affects spread; between 1 and 6, inclusive; 1 is tightest, 2 is normal, and 6 is loosest
      x - starting x position to look from
      y - starting y position to look from
      radius - the distance to extend from the starting x,y position
      radiusTechnique - how to measure distance; typically Radius.CIRCLE.
      Returns:
      light, after writing the FOV map into it; 1.0 is fully lit and 0.0 is unseen
    • reuseRippleFOV

      public static double[][] reuseRippleFOV​(double[][] resistanceMap, double[][] light, int rippleLooseness, int x, int y, double radius, Radius radiusTechnique, double angle, double span)
      Like the reuseFOV(double[][], double[][], int, int, double, Radius, double, double) method, but this uses Ripple FOV with a configurable tightness/looseness (between 1, tightest, and 6, loosest). Other parameters are similar; you can get a resistance map from generateResistances(char[][]), light will be modified and returned (it will be overwritten, but its size should be the same as the resistance map), there's starting x,y position, a radius in cells, a Radius enum constant to choose the distance measurement, and the angle/span combination to specify a conical section of FOV (span is the total in degrees, centered on angle).
      Parameters:
      resistanceMap - probably calculated with generateResistances(char[][]); 1.0 blocks light, 0.0 allows it
      light - will be overwritten! Should be initialized with the same size as resistanceMap
      rippleLooseness - affects spread; between 1 and 6, inclusive; 1 is tightest, 2 is normal, and 6 is loosest
      x - starting x position to look from
      y - starting y position to look from
      radius - the distance to extend from the starting x,y position
      radiusTechnique - how to measure distance; typically Radius.CIRCLE.
      angle - the angle to center the conical FOV on
      span - the total span in degrees for the conical FOV to cover
      Returns:
      light, after writing the FOV map into it; 1.0 is fully lit and 0.0 is unseen
    • bouncingLine

      public static double[][] bouncingLine​(double[][] resistanceMap, double[][] light, int startX, int startY, double distance, double angle)
      Reuses the existing light 2D array and fills it with a straight-line bouncing path of light that reflects its way through the given resistanceMap from startX, startY until it uses up the given distance. The angle the path takes is given in degrees, and the angle used can change as obstacles are hit (reflecting backwards if it hits a corner pointing directly into or away from its path). This can be used something like an LOS method, but because the path can be traveled back over, an array or Queue becomes somewhat more complex, and the decreasing numbers for a straight line that stack may make more sense for how this could be used (especially with visual effects). This currently allows the path to pass through single-cell wall-like obstacles without changing direction, e.g. it passes through pillars, but will bounce if it hits a bigger wall.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - the grid of cells to assign to; may have existing values, and 0.0 is used to mean "unlit"
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      distance - the distance the light will extend to
      angle - in degrees, the angle to start the path traveling in
      Returns:
      the given light parameter, after modifications
    • reuseFOV

      public static double[][] reuseFOV​(double[][] resistanceMap, double[][] light, int startX, int startY, double radius, Radius radiusTechnique, double angle, double forward, double sideForward, double side, double sideBack, double back)
      Calculates the Field Of View for the provided map from the given x, y coordinates, lighting with the view "pointed at" the given angle in degrees, extending to different ranges based on the direction the light is traveling. The direction ranges are forward, sideForward, side, sideBack, and back; all are multiplied by radius. Assigns to, and returns, a light map where the values represent a percentage of fully lit. The values in light are cleared before this is run, because prior state can make this give incorrect results. You can use addFOVsInto(double[][], double[][]...) if you want to mix FOV results, which works as an alternative to using the prior light state.
      The starting point for the calculation is considered to be at the center of the origin cell. Radius determinations are determined by the provided RadiusStrategy. If all direction ranges are the same, this acts like reuseFOV(double[][], double[][], int, int, double, Radius); otherwise may produce conical shapes (potentially more than one, or overlapping ones).
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      light - the grid of cells to assign to; may have existing values, and 0.0 is used to mean "unlit"
      startX - the horizontal component of the starting location
      startY - the vertical component of the starting location
      radius - the distance the light will extend to (roughly); direction ranges will be multiplied by this
      radiusTechnique - provides a means to shape the FOV by changing distance calculation (circle, square, etc.)
      angle - the angle in degrees that will be the center of the FOV cone, 0 points right
      forward - the range to extend when the light is within 22.5 degrees of angle; will be interpolated with sideForward
      sideForward - the range to extend when the light is between 22.5 and 67.5 degrees of angle; will be interpolated with forward or side
      side - the range to extend when the light is between 67.5 and 112.5 degrees of angle; will be interpolated with sideForward or sideBack
      sideBack - the range to extend when the light is between 112.5 and 157.5 degrees of angle; will be interpolated with side or back
      back - the range to extend when the light is more than 157.5 degrees away from angle; will be interpolated with sideBack
      Returns:
      the computed light grid (the same as light)
    • addFOVsInto

      public static double[][] addFOVsInto​(double[][] basis, double[][] addend)
      Adds an FOV map to another in the simplest way possible; does not check line-of-sight between FOV maps. Clamps the highest value for any single position at 1.0. Modifies the basis parameter in-place and makes no allocations; this is different from addFOVs(double[][][]), which creates a new 2D array.
      Parameters:
      basis - a 2D double array, which can be empty or returned by calculateFOV() or reuseFOV(); modified!
      addend - another 2D double array that will be added into basis; this one will not be modified
      Returns:
      the sum of the 2D double arrays passed, using the dimensions of basis if they don't match
    • addFOVs

      public static double[][] addFOVs​(double[][]... maps)
      Adds multiple FOV maps together in the simplest way possible; does not check line-of-sight between FOV maps. Clamps the highest value for any single position at 1.0. Allocates a new 2D double array and returns it.
      Parameters:
      maps - an array or vararg of 2D double arrays, each usually returned by calculateFOV()
      Returns:
      the sum of all the 2D double arrays passed, using the dimensions of the first if they don't all match
    • addFOVsInto

      public static double[][] addFOVsInto​(double[][] basis, double[][]... maps)
      Adds multiple FOV maps to basis cell-by-cell, modifying basis; does not check line-of-sight between FOV maps. Clamps the highest value for any single position at 1.0. Returns basis without allocating new objects.
      Parameters:
      basis - a 2D double array that will be modified by adding values in maps to it and clamping to 1.0 or less
      maps - an array or vararg of 2D double arrays, each usually returned by calculateFOV()
      Returns:
      basis, with all elements in all of maps added to the corresponding cells and clamped
    • addFOVs

      public static double[][] addFOVs​(Iterable<double[][]> maps)
      Adds multiple FOV maps together in the simplest way possible; does not check line-of-sight between FOV maps. Clamps the highest value for any single position at 1.0. Allocates a new 2D double array and returns it.
      Parameters:
      maps - an Iterable of 2D double arrays (most collections implement Iterable), each usually returned by calculateFOV()
      Returns:
      the sum of all the 2D double arrays passed, using the dimensions of the first if they don't all match
    • mixVisibleFOVs

      public static double[][] mixVisibleFOVs​(double[][] losMap, double[][]... maps)
      Adds together multiple FOV maps, but only adds to a position if it is visible in the given LOS map. Useful if you want distant lighting to be visible only if the player has line-of-sight to a lit cell. Typically the LOS map is calculated by reuseLOS(double[][], double[][], int, int), using the same resistance map used to calculate the FOV maps. Clamps the highest value for any single position at 1.0.
      Parameters:
      losMap - an LOS map such as one generated by reuseLOS(double[][], double[][], int, int)
      maps - an array or vararg of 2D double arrays, each usually returned by calculateFOV()
      Returns:
      the sum of all the 2D double arrays in maps where a cell was visible in losMap
    • mixVisibleFOVsInto

      public static double[][] mixVisibleFOVsInto​(double[][] losMap, double[][] basis, double[][]... maps)
      Adds together multiple FOV maps, but only adds to a position if it is visible in the given LOS map. Useful if you want distant lighting to be visible only if the player has line-of-sight to a lit cell. Typically the LOS map is calculated by reuseLOS(double[][], double[][], int, int), using the same resistance map used to calculate the FOV maps. Clamps the highest value for any single position at 1.0.
      Parameters:
      losMap - an LOS map such as one generated by reuseLOS(double[][], double[][], int, int)
      basis - an existing 2D double array that should have matching width and height to losMap; will be modified
      maps - an array or vararg of 2D double arrays, each usually returned by calculateFOV()
      Returns:
      the sum of all the 2D double arrays in maps where a cell was visible in losMap
    • mixVisibleFOVs

      public static double[][] mixVisibleFOVs​(double[][] losMap, Iterable<double[][]> maps)
      Adds together multiple FOV maps, but only adds to a position if it is visible in the given LOS map. Useful if you want distant lighting to be visible only if the player has line-of-sight to a lit cell. Typically the LOS map is calculated by reuseLOS(double[][], double[][], int, int), using the same resistance map used to calculate the FOV maps. Clamps the highest value for any single position at 1.0.
      Parameters:
      losMap - an LOS map such as one generated by reuseLOS(double[][], double[][], int, int)
      maps - an Iterable of 2D double arrays, each usually returned by calculateFOV()
      Returns:
      the sum of all the 2D double arrays in maps where a cell was visible in losMap
    • calculateLOSMap

      public double[][] calculateLOSMap​(double[][] resistanceMap, int startX, int startY)
      Calculates what cells are visible from (startX,startY) using the given resistanceMap; this can be given to mixVisibleFOVs() to limit extra light sources to those visible from the starting point. Just like calling calculateFOV(), this creates a new double[][]; there doesn't appear to be a way to work with Ripple FOV and avoid needing an empty double[][] every time, since it uses previously-placed light to determine how it should spread.
      Parameters:
      resistanceMap - the grid of cells to calculate on; the kind made by generateResistances(char[][])
      startX - the center of the LOS map; typically the player's x-position
      startY - the center of the LOS map; typically the player's y-position
      Returns:
      an LOS map with the given starting point
    • generateResistances

      public static double[][] generateResistances​(char[][] map)
      Given a char[][] for the map, produces a double[][] that can be used with most of the methods in FOV, like reuseFOV(double[][], double[][], int, int, double). It expects any doors to be represented by '+' if closed or '/' if open (which can be caused by calling DungeonUtility.closeDoors(char[][])), any walls to be '#' or box drawing characters, and it doesn't care what other chars are used (only doors, including open ones, and walls obscure light and thus have a resistance by default).
      Parameters:
      map - a dungeon, width by height, with any closed doors as '+' and open doors as '/' as per closeDoors()
      Returns:
      a resistance map suitable for use with the FOV class, with clear cells assigned 0.0 and blocked ones 1.0
    • generateResistances3x3

      public static double[][] generateResistances3x3​(char[][] map)
      Given a char[][] for the map that should use box drawing characters (as produced by DungeonUtility.hashesToLines(char[][], boolean)), produces a double[][] with triple width and triple height that can be used with FOV methods like reuseFOV(double[][], double[][], int, int, double) in classes that use subcell lighting. Importantly, this only considers a "thin line" of wall to be blocking (matching the box drawing character), instead of the whole 3x3 area. This expects any doors to be represented by '+' if closed or '/' if open (which can be caused by calling DungeonUtility.closeDoors(char[][])), thick vegetation or other concealing obstructions to be '"', any normal walls to be box drawing characters, any cells that block all subcells to be '#', and it doesn't care what other chars are used (only doors, including open ones, vegetation, and walls obscure light and thus have a resistance normally).
      Parameters:
      map - a dungeon, width by height, with any closed doors as '+' and open doors as '/' as per closeDoors()
      Returns:
      a resistance map suitable for use with the FOV class and subcell lighting, with triple width/height
    • generateSimpleResistances

      public static double[][] generateSimpleResistances​(char[][] map)
      Given a char[][] for the map, produces a double[][] that can be used with any FOV methods that expect a resistance map (like reuseFOV(double[][], double[][], int, int, double)), but does not treat any cells as partly transparent, only fully-blocking or fully-permitting light. This is mainly useful if you expect the FOV radius to be very high or (effectively) infinite, since anything less than complete blockage would be passed through by infinite-radius FOV. This expects any doors to be represented by '+' if closed or '/' if open (most door placement defaults to a mix of '+' and '/', so by calling DungeonUtility.closeDoors(char[][]) you can close all doors at the start), and any walls to be '#' or box drawing characters. This will assign 1.0 resistance to walls and closed doors or 0.0 for any other cell.
      Parameters:
      map - a dungeon, width by height, with any closed doors as '+' and open doors as '/' as per closeDoors()
      Returns:
      a resistance map suitable for use with the FOV class, but with no partially transparent cells
    • generateSimpleResistances3x3

      public static double[][] generateSimpleResistances3x3​(char[][] map)
      Given a char[][] for the map that should use box drawing characters (as produced by DungeonUtility.hashesToLines(char[][], boolean)), produces a double[][] with triple width and triple height that can be used with FOV's methods that expect a resistance map (like reuseFOV(double[][], double[][], int, int, double)) in classes that use subcell lighting. This expects any doors to be represented by '+' if closed or '/' if open (most door placement defaults to a mix of '+' and '/', so by calling DungeonUtility.closeDoors(char[][]) you can close all doors at the start), any walls to be box drawing characters, and any cells that block all subcells within their area to be '#'. This will assig 1.0 resistance to walls and closed doors where a line of the box drawing char would block light, or 0.0 for an other subcell.
      Parameters:
      map - a dungeon, width by height, with any closed doors as '+' and open doors as '/' as per closeDoors()
      Returns:
      a resistance map suitable for use with the FOV class and subcell lighting, with triple width/height