quarta-feira, 15 de outubro de 2014

Agents' shape

I created a new class, AgentShape and then I've added some shapes I found in the Internet. Now the agent HabitatCell, when created, passes an instance of the shape which is called in the HabitatStyleOGL2D.

  • The new class

package stupidmodel;

import java.awt.Shape;
import java.awt.geom.GeneralPath;

public class AgentShape {
private boolean fillshape;
public AgentShape(){
}
/**
* Adapted From 'http://www.gailer-net.de/tutorials/java3/Notes/chap74/ch74_9.html'
* @param size
* @return path shape
*/
public final Shape getStar(int size )
  {
  int endX,endY;
  fillshape = false;
  GeneralPath path = new GeneralPath();
    // Six lines radiating from (x,y)
  path.moveTo(0, 0);
    for ( int i = 0; i<6; i++ )
    {
      endX = (int)(size*Math.cos( (2*Math.PI/6)*i ));
      endY = (int)(size*Math.sin( (2*Math.PI/6)*i ));
      path.lineTo(endX, endY); 
      path.moveTo(0,0);
    }
    return path;
  }
/**
* Creating another star
* Adapted From 'http://zetcode.com/gfx/java2d/shapesandfills/'
* Size multiplies by the fixed distance between the points.
* Higher values of size_rate means a smaller figure.
* @param size_rate
* @return path shape
*/
/* First, I divided by 85, then I move the star to the center...*/
private static double points[][] = { 
    { -1.7647/2, 0+0.47059/2 }, { 0.88235-1.7647/2, 1-0.88235+0.47059/2 }, { 1.17647-1.7647/2, 1-0.117647+0.47059/2 }, { 1.47059-1.7647/2, 1-0.88235+0.47059/2}, 
    { 2.35294-1.7647/2, 1-1+0.47059/2 }, { 1.76471-1.7647/2, 1-1.47059+0.47059/2 }, { 1.88235-1.7647/2, 1-2.23530+0.47059/2 }, { 1.17647-1.7647/2, 1-1.7647+0.47059/2 }, 
    { 0.47059-1.7647/2, 1-2.3530+0.47059/2 }, { 0.58824-1.7647/2, 1-1.47059+0.47059/2 }, { -1.7647/2, 0+0.47059/2} 
  /* original: 
    { 0, 85 }, { 75, 75 }, { 100, 10 }, { 125, 75 }, 
    { 200, 85 }, { 150, 125 }, { 160, 190 }, { 100, 150 }, 
    { 40, 190 }, { 50, 125 }, { 0, 85 } 
   
   
   
    */
};
public final boolean isFilledShape()
{
return fillshape;
}
public final Shape getFilledStar(double size ){
fillshape = true;
GeneralPath path = new GeneralPath();
path.moveTo(points[0][0]*size, points[0][1]*size);
for (int k = 1; k < points.length; k++)
    path.lineTo(points[k][0]*size, points[k][1]*size);
path.closePath();
return path;
}
/**
* Adapted from ''
* It apparently doesn't work because it doesn't accept Quadratic Curves.
* @return
*/
public final Shape getQuadArrow(){
GeneralPath path = new GeneralPath();
        float p1x = 10, p1y = 10;   // P1
        float p2x = 100, p2y = 10;  // P2
        float cx = 55, cy = 50;     // Control point of the curve
        float arrSize = 5;          // Size of the arrow segments

        float adjSize = (float)(arrSize/Math.sqrt(2));
        float ex = p2x - cx;
        float ey = p2y - cy;
        float abs_e = (float)Math.sqrt(ex*ex + ey*ey);
        ex /= abs_e;
        ey /= abs_e;


        // Creating quad arrow
        path.moveTo(p1x, p1y);
        path.quadTo(cx, cy, p2x, p2y);
        path.lineTo(p2x + (ey-ex)*adjSize, p2y - (ex + ey)*adjSize);
        path.moveTo(p2x, p2y);
        path.lineTo(p2x - (ey + ex)*adjSize, p2y + (ex - ey)*adjSize);
return path;
}
/**
* Adapted from 'http://www.java-forums.org/awt-swing/5842-how-draw-arrow-mark-using-java-swing.html'
* @param length
* @param barb
* @return
*/
public final Shape getArrow(int length,int barb){
  double angle = Math.toRadians(20);
      GeneralPath path = new GeneralPath();
      path.moveTo(-length/2, 0);
      path.lineTo(length/2, 0);
      double x = length/2 - barb*Math.cos(angle);
      double y = barb*Math.sin(angle);
      path.lineTo(x, y);
      x = length/2 - barb*Math.cos(-angle);
      y = barb*Math.sin(-angle);
      path.moveTo(length/2, 0);
      path.lineTo(x, y);
      return path;
}

}

  • The new constructor for the HabitatCell with the new variable shape:
public class HabitatCell {
        private static final double maximumFoodProductionRate = 0.01;
        private final int x, y;
        private double foodAvailability = 0.0;
        private Shape shape;
       

        public HabitatCell(final int x, final int y, Shape shape) {
                this.x = x;
                this.y = y;
                this.shape = shape;
               
        }
...


  • It is in the class  StupidModelContextBuilder that the shape is decided. Nevertheless, the shape can always change if we set a new shape for the agent while running.  I add this lines before the  agents are created.
Arrow:

final Shape sh = new AgentShape().getArrow(10,5);

Or FilledStar:


final Shape sh = new AgentShape().getFilledStar(8.0);

And then, creating the agents with the predefined shape:

for (int i = 0; i < Constants.GRID_SIZE; ++i) {
for (int j = 0; j < Constants.GRID_SIZE; j++){
final HabitatCell cell = new HabitatCell(i,j,sh);
context.add(cell);
grid.moveTo(cell, i, j);

Sem comentários:

Enviar um comentário