Package org.cmj.flowy.simulation

Source Code of org.cmj.flowy.simulation.IndexGrid

/*
* IndexGrid.java
*
* Copyright 2011 Chris Martin.
*
* This file is part of Flowy.
*
* Flowy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Flowy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Flowy. If not, see <http://www.gnu.org/licenses/>.
*
*
*/

package org.cmj.flowy.simulation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.cmj.flowy.simulation.math.RectangleF;
import org.cmj.flowy.simulation.particles.FluidParticle;

/**
* Class to represent a 2-d grid of discrete points in space. The particles are
* mapped to this grid based on their position in 2-d space. This eases the job
* of finding out their neighbours.
* @author Chris Martin.
*/
public class IndexGrid {

    /** The grid itself. Each list contains the particles at that position in space. */
    private List<Integer>[][] theGrid;

    /** The distance between the cell points. */
    private float theCellSpacing;

    /** The simulation domain */
    private RectangleF theDomain;

    /** The width of the grid (in cells) */
    public int theWidth;
   
    /** The height of the grid (in cells) */
    public int theHeight;

    /** A map which maps a particle to a list containing all it's neighbouring particles. */
    private Map<FluidParticle, List<Integer>> theNeighboursIndex = new HashMap<FluidParticle, List<Integer>>();
   
    /**
     * Create a new Grid, using the dimensions layed out in the domain and using
     * the supplied cell spacing
     * @param cellSpace  The spacing between cells to use.
     * @param domain The simulation domain.
     */
    public IndexGrid(final float cellSpace, final RectangleF domain) {
        theCellSpacing = cellSpace;
        theDomain = domain;
        theWidth = (int) (theDomain.width / theCellSpacing);
        theHeight = (int) (theDomain.height / theCellSpacing);
    }

    /**
     * Update the grid using the new list of particles.
     * @param particles The new particles with which to update the grid.
     */
    @SuppressWarnings("unchecked")
    public void refresh(final List<FluidParticle> particles) {
        theGrid = new ArrayList[this.theWidth][this.theHeight];
        theNeighboursIndex.clear();
        final int numOfParticles = particles.size();
        for (int i = 0; i < numOfParticles; ++i) {
            final FluidParticle thisParticle = particles.get(i);
            thisParticle.gridIndexX = GetGridIndexX(thisParticle);
            thisParticle.gridIndexY = GetGridIndexY(thisParticle);

            // Add particle to list
            if (theGrid[thisParticle.gridIndexX][thisParticle.gridIndexY] == null) {
                theGrid[thisParticle.gridIndexX][thisParticle.gridIndexY] = new ArrayList<Integer>();
            }
            theGrid[thisParticle.gridIndexX][thisParticle.gridIndexY].add(i);
        }

       
        // Build up the cache of neighbours for each fluid particle.
        for (int i = 0; i < numOfParticles; ++i) {
            final FluidParticle thisParticle = particles.get(i);
            theNeighboursIndex.put(thisParticle, getNeighbourIndexForCache(thisParticle));
        }
    }
   
    /**
     * Get the x-point on the simulation grid for the supplied particle. If the
     * particle is outside the grid then it will appear at the edge of the grid.
     * @param particle The particle whose position on the grid is to be determined.
     * @return The x-point on the grid which represents the position of this particle
     */
    private int GetGridIndexX(final FluidParticle particle) {
        int gridIndexX = (int) (particle.position.x /theCellSpacing);
       
        // Clamp
        if (gridIndexX < 0) {
            gridIndexX = 0;
        }
        else if (gridIndexX >= theWidth) {
            gridIndexX = theWidth - 1;
        }
       
        return gridIndexX;
    }

    /**
     * Get the y-point on the simulation grid for the supplied particle. If the
     * particle is outside the grid then it will appear at the edge of the grid.
     * @param particle The particle whose position on the grid is to be determined.
     * @return The y-point on the grid which represents the position of this particle
     */
    private int GetGridIndexY(final FluidParticle particle) {
        int gridIndexY = (int) (particle.position.y / theCellSpacing);
       
        // Clamp
        if (gridIndexY < 0) {
            gridIndexY = 0;
        }
        else if (gridIndexY >= this.theHeight) {
            gridIndexY = this.theHeight - 1;
        }
        return gridIndexY;
    }

    /**
     * Returns the indexes (in the particle list) of all of the particles which
     * are neighbours of the supplied particle. Also included in this list will
     * be the particle itself.
     * @param particle The particle whose neighbours are to be returned.
     * @return The list of indexes for particles that neighbour the supplied particle.
     */
    private List<Integer> getNeighbourIndexForCache(FluidParticle particle)
     {
        List<Integer> neighbourIndices = new ArrayList<Integer>();
      
        for (int xOff = -1; xOff < 2; xOff++)
        {
           for (int yOff = -1; yOff < 2; yOff++)
           {
              // Neighbour index
              int x = particle.gridIndexX + xOff;
              int y = particle.gridIndexY + yOff;
             
              // Clamp
              if (x > -1 && x < this.theWidth && y > -1 && y < this.theHeight)
              {
                 List<Integer> indexList = theGrid[x][y];
                 if (indexList != null)
                 {
                    // Return neighbours index
                    for(int i=0; i<indexList.size(); ++i)
                    {
                        neighbourIndices.add(indexList.get(i));
                    }
                 }
              }
           }
        }
        return neighbourIndices;
     }

    /**
     * Returns the indexes (in the particle list) of all of the particles which
     * are neighbours of the supplied particle. Also included in this list will
     * be the particle itself.  This method should be relatively quick as the results should have been cached.
     * @param particle The particle whose neighbours are to be returned.
     * @return The list of indexes for particles that neighbour the supplied particle.
     */
    public List<Integer> GetNeighbourIndex(FluidParticle particle) {
        return theNeighboursIndex.get(particle);
    }
}
TOP

Related Classes of org.cmj.flowy.simulation.IndexGrid

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.