[Home]Hanji/AGravEngine

Robo Home | Hanji | Changes | Preferences | AllPages

This class encapsulates the AntiGravityMovement Algorithm. Hopefully the comments will make things clear enough, but feel free to ask questions. I also have a subclass, /AGravEngineGL, which draws GravPoints? to the screen using RobocodeGLV014
 package neh;

 import java.util.Vector;
 import neh.RobocodeUtils;
 import neh.GravPoint;

 /**
 * AGravEngine -> an engine encapsulating the Anti-gravity movement
 * algorithm. By NEH (aka Hanji)
 **/
 public class AGravEngine {
		
	/**The Points that it is concerned with.**/
	protected Vector gravPoints = new Vector();

	/**
	 * The force, if any, of the walls. It is assumed that the walls will
	 * never attract, so this is always positive (meaning repulsion in this
	 * case).
	 **/
	protected double wallForce = 0.0;
	
	/**The width of the battlefield.**/
	protected double width;

	/**The height of the battlefield**/
	protected double height;
	
	/*The components of the force**/
	protected double xForce = 0.0;
	protected double yForce = 0.0;
	
	/**
	 * The exponent used in cacluating a point's effect on a location.
	 * The effect is proportionate to distance^pointDropoff. This field 
	 * has an initial value of 2.0.
	 **/
	protected double pointDropoff = 2.0;
	
	/**
	 * The exponent used in cacluating the walls' effect on a location.
	 * The effect is proportionate to distance^wallDropoff. This field
	 * has an initial value of 3.0.
	 **/ 
	protected double wallDropoff = 3.0;
	
	/**Initializes the width and height to 0**/
	public AGravEngine() {
		this(0,0);
	}

	/**Initializes the dimensions to the specified values**/
	public AGravEngine(double width, double height) {
		this.width = width;
		this.height = height;
	}
	
	/**Adds a point to the list.**/
	public void addPoint(GravPoint g) {
		gravPoints.add(g);
	}
	
	/**Removes a point from the list.**/
	public boolean removePoint(GravPoint g) {
		return gravPoints.remove(g);
	}
	
	/**Returns the number of points currently contained.**/
	public long getNumPoints() {
		return gravPoints.size();
	}
	
	/**Returns the force with which the walls repel.**/
	public double getWallForce() {
		return wallForce;
	}
	
	/**Sets the force with which the walls repel.**/
	public void setWallForce(double wf) {
		wallForce = wf;
	}
	
	/**Returns the value of the point dropoff exponent.**/
	public double getPointDropoff() {
		return pointDropoff;
	}
	
	/**Sets the value of the point dropoff exponent.**/
	public void setPointDropoff(double pdf) {
		pointDropoff = pdf;
	}
	
	/**Returns the value of the wall dropoff exponent.**/
	public double getWallDropoff() {
		return wallDropoff;
	}
	
	/**Sets the value of the wall dropoff exponent.**/
	public void setWallDropoff(double wdf) {
		wallDropoff = wdf;
	}
	
	/**Removes all points from the list.**/
	public void reset() {
		gravPoints = new Vector();
	}
	
	/**
	 * Calculates the current force and kills any GravPoints
	 * that have gone past their lifetimes
	 * @param curX The X coordinate of the point for which
	 * gravity is being calculated.
	 * @param curY The Y coordinate of the point for which
	 * gravity is being calculated.
	 * @param time The current time.
	 **/
	public void update(double curX, double curY, long time) {
		xForce = 0.0;
		yForce = 0.0;
		Vector deadPoints = new Vector();
		GravPoint g;
		double force;
		double angle;
		for(int i=0;i<gravPoints.size();i++) {
			g = (GravPoint) gravPoints.elementAt(i);
			if(g.update(time)) {
				deadPoints.add(g);
				continue;
			}
			force = g.strength/Math.pow(
								RobocodeUtils.dist(curX, curY, g.x, g.y),
								pointDropoff);		
			angle = RobocodeUtils.getBearing(curX, curY, g.x, g.y);
			xForce += force * Math.sin(angle);
			yForce += force * Math.cos(angle);
		}
		xForce += wallForce/Math.pow(curX, wallDropoff);
	    xForce -= wallForce/Math.pow(width-curX, wallDropoff);
	    yForce -= wallForce/Math.pow(height-curY, wallDropoff);
	    yForce += wallForce/Math.pow(curY, wallDropoff);
		
		for(int i=0;i<deadPoints.size();i++) {
			gravPoints.remove(deadPoints.elementAt(i));
		}
	}
	
	/**
	 * Returns the force in the X direction (calculated in
	 * update())
	 **/
	public double getXForce() {
		return xForce;
	}
	
	/**
	 * Returns the force in the Y direction (calculated in
	 * update())
	 **/
	public double getYForce() {
		return yForce;
	}	
	
 }
This class also requires the /GravPoint class, and you will have to either replace the calls to RobocodeUtils.* with your own equivalents, or grab that class as well.
Questions or comments:

I'm working on a bot with this engine. It took me quite a while to find some good values for the dropoffs and wallforce. I neeeded to change the lines:

xForce += force * Math.sin(angle); yForce += force * Math.cos(angle);

into:

xForce -= force * Math.sin(angle); yForce -= force * Math.cos(angle);

otherwise other bots attracted my bot. It works pretty good if you place some additional points (e.g. center and corners).

Noran


Robo Home | Hanji | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited May 16, 2005 2:25 EST by XLittleP (diff)
Search: