java - Find inside coordinates of polygon in tile based map -


if have of outer edges of polygons in list how go finding inside coordinates?? make matters simple drew following image represent problem:

enter image description here

i need find inside of 'buildings' in tilebased game.

  • outside walls - grey shaded cells.
  • inside building - light blue cells.

in event building not shown in view (right building) have solved issue adding entire green section (-1,-1, 0,-1, etc.) list.

without following insane if search tree have no idea how solve this. posting here tips, code, or psuedo code. appreciated. much! :)


edit

@andrew thompson: think miswrote situaton. not duplicate linked to. don't have image. excel drawing did above example. example:

i have list containing brown values: ie. {"1,1", "2,1", "3,1", "1,2", etc.}

and need corresponding list of blue values: ie. {"2,2", "2,6", "3,6", "4,6", etc.}

i toyed around a* algorithm week. there may other solutions request, since have code, matter of adapting needs. however, specific requirement use primitive flood-fill algorithm , classify cells way, see method in algorithm code.

the a* algorithm finds path given start given goal. in case start goal, means it's reference point classifies "outside" cell. there on search can traverse.

i left path finding code in example, maybe it's of use further needs.

here's code:

demo.java

import java.util.list; import java.util.set;   public class demo {      public static void main(string[] args) {          // create grid in example         int cols = 9;         int rows = 9;          grid grid = new grid( cols, rows);          // create walls in example         grid.getcell( 1, 1).settraversable( false);         grid.getcell( 2, 1).settraversable( false);         grid.getcell( 3, 1).settraversable( false);         grid.getcell( 1, 2).settraversable( false);         grid.getcell( 3, 2).settraversable( false);         grid.getcell( 6, 2).settraversable( false);         grid.getcell( 7, 2).settraversable( false);         grid.getcell( 8, 2).settraversable( false);         grid.getcell( 1, 3).settraversable( false);         grid.getcell( 2, 3).settraversable( false);         grid.getcell( 3, 3).settraversable( false);         grid.getcell( 6, 3).settraversable( false);         grid.getcell( 6, 4).settraversable( false);         grid.getcell( 7, 4).settraversable( false);         grid.getcell( 1, 5).settraversable( false);         grid.getcell( 2, 5).settraversable( false);         grid.getcell( 3, 5).settraversable( false);         grid.getcell( 4, 5).settraversable( false);         grid.getcell( 5, 5).settraversable( false);         grid.getcell( 7, 5).settraversable( false);         grid.getcell( 8, 5).settraversable( false);         grid.getcell( 1, 6).settraversable( false);         grid.getcell( 5, 6).settraversable( false);         grid.getcell( 1, 7).settraversable( false);         grid.getcell( 2, 7).settraversable( false);         grid.getcell( 3, 7).settraversable( false);         grid.getcell( 4, 7).settraversable( false);         grid.getcell( 5, 7).settraversable( false);          // find traversables         // -------------------------          astaralgorithm alg = new astaralgorithm();          cell start;         cell goal;          // reference point = 0/0         start = grid.getcell(0, 0);         set<cell> visited = alg.getfloodfillcells(grid, start, true);          // find inside cells         for( int row=0; row < rows; row++) {             for( int col=0; col < cols; col++) {                  cell cell = grid.getcell(col, row);                  if( !cell.traversable) {                     cell.settype(type.wall);                 }                 else if( visited.contains( cell)) {                     cell.settype(type.outside);                 }                  else {                     cell.settype(type.inside);                 }              }         }          // log inside cells         for( int row=0; row < rows; row++) {             for( int col=0; col < cols; col++) {                 cell cell = grid.getcell(col, row);                 if( cell.gettype() == type.inside) {                     system.out.println("inside: " + cell);                 }             }         }          // path finding         // -------------------------          // start = top/left, goal = bottom/right         start = grid.getcell(0, 0);         goal = grid.getcell(8, 8);          // find a* path         list<cell> path = alg.findpath(grid, start, goal, true);          // log path         system.out.println(path);          system.exit(0);      }  } 

type.java

public enum type {      outside,     wall,     inside,  } 

cell.java

public class cell implements cloneable {      int col;     int row;     boolean traversable;     type type;      double g;     double f;     double h;      cell camefrom;      public cell( int col, int row, boolean traversable) {         this.col=col;         this.row=row;         this.traversable = traversable;     }      public double getf() {         return f;     }      public double getg() {         return g;     }      public double geth() {         return h;     }      public void settraversable( boolean traversable) {         this.traversable = traversable;     }      public void settype( type type) {         this.type = type;     }      public type gettype() {         return this.type;     }      public string tostring() {         return col + "/" + row;     } } 

grid.java

public class grid {      cell[][] cells;      int cols;     int rows;      public grid( int cols, int rows) {         this.cols = cols;         this.rows = rows;         cells = new cell[rows][cols];          for( int row=0; row < rows; row++) {             for( int col=0; col < cols; col++) {                 cells[row][col] = new cell( col, row, true);              }         }     }      public cell getcell( int col, int row) {         return cells[row][col];     }      /**      * neighboring cells relative given cell. default top/right/bottom/left.       * if allowdiagonals enabled, top-left, top-right, bottom-left, bottom-right cells in results.      * @param cell      * @param allowdiagonals      * @return      */     public cell[] getneighbors(cell cell, boolean allowdiagonals) {          cell[] neighbors = new cell[ allowdiagonals ? 8 : 4];          int currentcolumn = cell.col;         int currentrow = cell.row;          int neighborcolumn;         int neighborrow;          // top         neighborcolumn = currentcolumn;         neighborrow = currentrow - 1;          if (neighborrow >= 0) {             if( cells[neighborrow][neighborcolumn].traversable) {                 neighbors[0] = cells[neighborrow][neighborcolumn];             }         }          // bottom         neighborcolumn = currentcolumn;         neighborrow = currentrow + 1;          if (neighborrow < rows) {             if( cells[neighborrow][neighborcolumn].traversable) {                 neighbors[1] = cells[neighborrow][neighborcolumn];             }         }          // left         neighborcolumn = currentcolumn - 1;         neighborrow = currentrow;          if ( neighborcolumn >= 0) {             if( cells[neighborrow][neighborcolumn].traversable) {                 neighbors[2] = cells[neighborrow][neighborcolumn];             }         }          // right         neighborcolumn = currentcolumn + 1;         neighborrow = currentrow;          if ( neighborcolumn < cols) {             if( cells[neighborrow][neighborcolumn].traversable) {                 neighbors[3] = cells[neighborrow][neighborcolumn];             }         }          if (allowdiagonals) {              // top/left             neighborcolumn = currentcolumn - 1;             neighborrow = currentrow - 1;              if (neighborrow >= 0 && neighborcolumn >= 0) {                 if( cells[neighborrow][neighborcolumn].traversable) {                     neighbors[4] = cells[neighborrow][neighborcolumn];                 }             }              // bottom/right             neighborcolumn = currentcolumn + 1;             neighborrow = currentrow + 1;              if (neighborrow < rows && neighborcolumn < cols) {                 if( cells[neighborrow][neighborcolumn].traversable) {                     neighbors[5] = cells[neighborrow][neighborcolumn];                 }             }              // top/right             neighborcolumn = currentcolumn + 1;             neighborrow = currentrow - 1;              if (neighborrow >= 0 && neighborcolumn < cols) {                 if( cells[neighborrow][neighborcolumn].traversable) {                     neighbors[6] = cells[neighborrow][neighborcolumn];                 }             }              // bottom/left             neighborcolumn = currentcolumn - 1;             neighborrow = currentrow + 1;              if (neighborrow < rows && neighborcolumn >= 0) {                 if( cells[neighborrow][neighborcolumn].traversable) {                     neighbors[7] = cells[neighborrow][neighborcolumn];                 }             }          }           return neighbors;     }  } 

astaralgorithm.java

import java.util.arraylist; import java.util.comparator; import java.util.hashset; import java.util.list; import java.util.priorityqueue; import java.util.set;  /**  * a* algorithm http://en.wikipedia.org/wiki/a*_search_algorithm  */ public class astaralgorithm {      public class cellcomparator implements comparator<cell>     {         @override         public int compare(cell a, cell b)         {             return double.compare(a.f, b.f);         }      }      /**      * find cells can traverse given reference start point that's outside cell.      * algorithm a* path finding, don't stop when found goal, neither consider calculation of distance.      * @param g      * @param start      * @param goal      * @param allowdiagonals      * @return      */     public set<cell> getfloodfillcells(grid g, cell start, boolean allowdiagonals) {          cell current = null;          set<cell> closedset = new hashset<>();          set<cell> openset = new hashset<cell>();         openset.add(start);          while (!openset.isempty()) {              current = openset.iterator().next();              openset.remove(current);              closedset.add(current);              (cell neighbor : g.getneighbors(current, allowdiagonals)) {                  if (neighbor == null) {                     continue;                 }                  if (closedset.contains(neighbor)) {                     continue;                 }                  openset.add(neighbor);             }          }          return closedset;      }      /**      * find path start goal.      * @param g      * @param start      * @param goal      * @param allowdiagonals      * @return      */     public list<cell> findpath( grid g, cell start, cell goal, boolean allowdiagonals) {          cell current = null;         boolean containsneighbor;          int cellcount = g.rows * g.cols;          set<cell> closedset = new hashset<>( cellcount);          priorityqueue<cell> openset = new priorityqueue<cell>( cellcount, new cellcomparator());         openset.add( start);          start.g = 0d;         start.f = start.g + heuristiccostestimate(start, goal);           while( !openset.isempty()) {              current = openset.poll();              if( current == goal) {                 return reconstructpath( goal);             }              closedset.add( current);              for( cell neighbor: g.getneighbors( current, allowdiagonals)) {                  if( neighbor == null) {                     continue;                 }                  if( closedset.contains( neighbor)) {                     continue;                 }                  double tentativescoreg = current.g + distbetween( current, neighbor);                  if( !(containsneighbor=openset.contains( neighbor)) || double.compare(tentativescoreg, neighbor.g) < 0) {                      neighbor.camefrom = current;                      neighbor.g = tentativescoreg;                      neighbor.h = heuristiccostestimate(neighbor, goal);                     neighbor.f = neighbor.g + neighbor.h;                      if( !containsneighbor) {                         openset.add( neighbor);                     }                 }             }          }          return new arraylist<>();     }      private list<cell> reconstructpath( cell current) {          list<cell> totalpath = new arraylist<>(200); // arbitrary value, we'll have more 10 default java          totalpath.add( current);          while( (current = current.camefrom) != null) {              totalpath.add( current);          }          return totalpath;     }      private double distbetween(cell current, cell neighbor) {         return heuristiccostestimate( current, neighbor); // todo: dist_between heuristic_cost_estimate our use-case; use various other heuristics     }      private double heuristiccostestimate(cell from, cell to) {          return math.sqrt((from.col-to.col)*(from.col-to.col) + (from.row - to.row)*(from.row-to.row));      }  } 

the result inside cell logging is

inside: 2/2 inside: 7/3 inside: 8/3 inside: 8/4 inside: 2/6 inside: 3/6 inside: 4/6 

the result path 0/0 8/8 is

[8/8, 7/7, 7/6, 6/5, 5/4, 5/3, 5/2, 4/1, 3/0, 2/0, 1/0, 0/0] 

i wrote editor in javafx, come blog post soon, if interested. grid this:

enter image description here

where

  • black cells = walls
  • green cells = traversable cells
  • blue cells = path start end
  • white cells = cells inside walls

the numbers ones a* algorithm:

  • top/left = g (from start current cell)
  • top/right = h (from current cell goal)
  • center = f = g + h

and if don't allow diagonal movement:

enter image description here

but that's off-topic :-)


Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -