All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sim.app.mousetraps.MouseTraps Maven / Gradle / Ivy

Go to download

MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.

The newest version!
/*
  Copyright 2006 by Sean Luke and George Mason University
  Licensed under the Academic Free License version 3.0
  See the file "LICENSE" for more information
*/

package sim.app.mousetraps;
import sim.util.*;
import sim.engine.*;
import sim.field.continuous.Continuous3D;
import sim.field.grid.*;
import ec.util.*;


public class MouseTraps extends SimState
    {
    private static final long serialVersionUID = 1;

    /** the number of balls a trap will throw in the air when triggered */
    public static final int BALLS_PER_TRAP = 2;
    /** the initial velocity of a ball when thrown by a trap
     * I was going to model trap's dispensed energy
     * E = 0.5 * BALLS_PER_TRAP * ball's_weight * INITIAL_VELOCITY^2 
     * But since all are contants, i skip the math and
     * set INITIAL_VELOCITY and save some math,
     * without loss in generality */
    public final double initialVelocity;
        
    public static final double GRAVITY_ACC = 9.8;
    public static final double TWO_OVER_G = 2.0/GRAVITY_ACC;
        
    public static final double TIME_STEP_DURATION = 1.0/64; 
    public static final double TIME_STEP_FREQUENCY = 1.0/TIME_STEP_DURATION; 
        
    public static final double TWO_PI = Math.PI * 2.0;
    public static final double HALF_PI = Math.PI * 0.5;
        
    public final boolean toroidalWorld;
    public final boolean modelBalls;

    /** @todo handle realocation of grids when these two are changed */
    public final int trapGridHeight;
    public final int trapGridWidth;
    public final double spaceWidth, spaceHeight, spaceLength;
    public final double oneOverSpaceWidth, oneOverSpaceHeight, oneOverSpaceLength;

    public final double trapSizeX, trapSizeY;

    public IntGrid2D trapStateGrid;
    public Continuous3D ballSpace;
    public static final int ARMED_TRAP = 0;
    public static final int OFF_TRAP = 1;
        
        
    /** Creates a HeatBugs simulation with the given random number seed. */
    public MouseTraps(long seed)
        {
        this(seed, 0.7, 100, 100, true);
        }
            
    public MouseTraps(long seed, double initialVelocity, int width, int height, boolean toroidal)
        {
        super(seed);
        this.initialVelocity = initialVelocity;
        toroidalWorld = toroidal;
        modelBalls = false;
        trapGridWidth = width;
        trapGridHeight = height;
        spaceWidth  = 1;
        spaceHeight = 1;
        spaceLength = 1;
        createGrids();
        trapSizeX = spaceWidth/trapGridWidth;
        trapSizeY = spaceHeight/trapGridHeight;
        oneOverSpaceHeight = 1.0/spaceHeight;
        oneOverSpaceWidth  = 1.0/spaceWidth;
        oneOverSpaceLength = 1.0/spaceLength;
        }
                
    public MouseTraps(  long seed, 
        double initialVelocity, 
        int trapsX, 
        int trapsY,
        double width, 
        double height, 
        boolean toroidal)
        {
        super(seed);
        this.initialVelocity = initialVelocity;
        toroidalWorld = toroidal;
        trapGridWidth = trapsX;
        trapGridHeight = trapsY;
        modelBalls  = true;
        spaceWidth  = width;
        spaceHeight = height;
        spaceLength = computeFishTankCeiling();
        createGrids();
        trapSizeX = spaceWidth/trapGridWidth;
        trapSizeY = spaceHeight/trapGridHeight;
        oneOverSpaceHeight = 1.0/spaceHeight;
        oneOverSpaceWidth  = 1.0/spaceWidth;
        oneOverSpaceLength = 1.0/spaceLength;
        }
        
    /** computes how high should be the ceiling of the
     * fishtank so the balls don't hit it., even if they
     * are shot straight up.
     * 
     * Y = V0T-.5gT^2   //y0=0
     * V = V0-gT
     * => Ttop = V0/g
     * => Ytop = .5V0^2/g;
     * 
     * or in one line using energy conservation 
     * 
     */
    public double computeFishTankCeiling()
        {
        return 0.5 * initialVelocity * initialVelocity / GRAVITY_ACC;
        }
        
    void createGrids()
        {
        trapStateGrid = new IntGrid2D(trapGridWidth, trapGridHeight,ARMED_TRAP);        
        if(modelBalls)
            ballSpace = new Continuous3D(Math.max(trapGridHeight, trapGridWidth)*2, spaceWidth, spaceHeight, spaceLength);
        }
        
    /**
     * determines on what trap a certain location belongs to
     * @param position = distance in continuous space.
     * @return  [0..width-1] trap index
     * 
     * note: boundary between traps belong to the one in the right,
     * 
     * if space is toroidal, wrap "distance" around the space using %
     * if is not, the ball would bounce off the wall => 
     *  - it is like it did not bounce, but it entered a mirrored grid 
     *    (this explains trapGridWidth-i)
     *  - after two bounces everything is back, so I wrap the distance around 2 grids 
     *    (this explains i %= (2*trapGridWidth))
     */
    public int discretizeX(double position)
        {
        int i =(int)(position* oneOverSpaceWidth* trapGridWidth);
        if(toroidalWorld)
            return (i+trapGridWidth) % trapGridWidth;
        i+=2*trapGridWidth;
        i %= (2*trapGridWidth);
        if( i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy