/*
* Datei: PanicAgent.java
* Autor(en): Lukas König, Daniel Pathmaperuma
* Java-Version: 6.0
* Erstellt: 2010_10_28
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* =========================================================================
* Copyright note from phys2D:
*
* Phys2D - a 2D physics engine based on the work of Erin Catto.
*
* This source is also provided under the terms of the BSD License.
*
* Copyright (c) 2006, Phys2D
* All rights reserved.
*
* Where the licenses differ from each other, the more restrictive license
* version has to be concerned.
* =========================================================================
*
* In a nutshell (for the EAS framework)
* -------------
* You are free:
* - to Share - to copy, distribute and transmit the work
* - to Remix - to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
* author or licensor (but not in any way that suggests that they endorse
* you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
* distribute the resulting work only under the same or a similar license to
* this one.
*
* + Detailed license conditions (Germany):
* http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
* http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/
package eas.users.demos.panicSimulation;
import java.awt.Color;
import java.util.Random;
import eas.math.geometry.Polygon2D;
import eas.math.geometry.Vector2D;
import eas.simulation.Wink;
import eas.simulation.agent.GenericSensor;
import eas.simulation.spatial.sim2D.physicalSimulation.physicsEngine.net.phys2d.math.Vector2f;
import eas.simulation.spatial.sim2D.physicalSimulation.standardAgents.PhysicsAgent2D;
import eas.simulation.spatial.sim2D.physicalSimulation.standardEnvironments.PhysicsEnvironment2D;
import eas.simulation.spatial.sim2D.standardEnvironments.AbstractEnvironment2D;
import eas.startSetup.ParCollection;
/**
* @author Lukas König
*
*/
public class PanicAgent extends PhysicsAgent2D<PhysicsEnvironment2D<?>> {
/**
*
*/
private static final long serialVersionUID = 2849190904537383988L;
private Polygon2D pacman;
/**
* @param id
* @param env
* @param m
*/
public PanicAgent(final int id, final PhysicsEnvironment2D<PhysicsAgent2D<?>> env, final float m, ParCollection params) {
super(id, env, m, params);
rand = new Random();
setRotDamping(1.0f);
setDamping(0.1f);
setFriction(0);
addSensor(new GenericSensor<Double, PanicEnvironment, PanicAgent>() {
/**
*
*/
private static final long serialVersionUID = 8915063334820660797L;
@Override
public Double sense(final PanicEnvironment env, final PanicAgent agent) {
return env.getOutsideForce(agent.id());
}
@Override
public String id() {
return "Outside-Force";
}
});
addSensor(new GenericSensor<Boolean, PanicEnvironment, PanicAgent>() {
/**
*
*/
private static final long serialVersionUID = -7245444196090387009L;
@Override
public Boolean sense(final PanicEnvironment env, final PanicAgent agent) {
return env.isPanic() && !dead;
}
@Override
public String id() {
return "IsInPanic?";
}
});
addSensor(new GenericSensor<Boolean, PanicEnvironment, PanicAgent>() {
/**
*
*/
private static final long serialVersionUID = -5533913809113705949L;
@Override
public Boolean sense(PanicEnvironment env, PanicAgent agent) {
return PanicAgent.this.dead;
}
@Override
public String id() {
return "IsDead?";
}
});
}
private Vector2f forceNormal;
private Vector2f forceGetAwayFromFire;
private Vector2f forceGetTowardsExit;
private Random rand;
protected static Vector2f fireLocation = new Vector2f(5, 5);
protected static Vector2f exitLocation = new Vector2f(180, 40);
@SuppressWarnings("rawtypes")
@Override
public synchronized void step(final Wink simTime) {
if (!dead) {
final double force = ((PanicEnvironment) ((AbstractEnvironment2D) getEnvironment())).getOutsideForce(id());
if (force > 590) {
dead = true;
}
}
if (forceNormal == null) {
forceNormal = new Vector2f();
}
if (forceGetAwayFromFire == null) {
forceGetAwayFromFire = new Vector2f();
}
if (forceGetTowardsExit == null) {
forceGetTowardsExit = new Vector2f();
}
final double distanceFire = ((AbstractEnvironment2D) getEnvironment()).getAgentPosition(id()).distance(new Vector2D(fireLocation.x, fireLocation.y));
final double distanceExit = ((AbstractEnvironment2D) getEnvironment()).getAgentPosition(id()).distance(new Vector2D(exitLocation.x, exitLocation.y));
if ((Boolean) this.sense("IsInPanic?")) {
forceNormal.x = 0;
forceNormal.y = 0;
forceGetAwayFromFire.x = (float) ((AbstractEnvironment2D) getEnvironment()).getAgentPosition(id()).x - fireLocation.x;
forceGetAwayFromFire.y = (float) ((AbstractEnvironment2D) getEnvironment()).getAgentPosition(id()).y - fireLocation.y;
forceGetAwayFromFire.scale(100 / (float) distanceFire);
forceGetTowardsExit.scale(100 / (float) distanceExit);
forceGetTowardsExit.x = exitLocation.x - (float) ((AbstractEnvironment2D) getEnvironment()).getAgentPosition(id()).x;
forceGetTowardsExit.y = exitLocation.y - (float) ((AbstractEnvironment2D) getEnvironment()).getAgentPosition(id()).y;
} else {
forceNormal.x = rand.nextFloat() * 50 - 25f;
forceNormal.y = rand.nextFloat() * 50 - 25f;
}
if (!dead) {
addForce(forceNormal);
addForce(forceGetAwayFromFire);
addForce(forceGetTowardsExit);
addForce(new Vector2f((float) (rand.nextDouble() * mult - mult / 2), (float) (rand.nextDouble() * mult - mult / 2)));
} else {
// setForce(0, 0);
// setDamping(0.85f);
}
}
final double mult = 30;
public static final double precision = 40;
public static final double radius = 2;
@Override
public synchronized Polygon2D getAgentShape() {
if (pacman == null) {
pacman = new Polygon2D();
for (double d = 0; d < Math.PI * 1.75; d += Math.PI * 2 / precision) {
pacman.add(new Vector2D(Math.sin(d) * radius, Math.cos(d) * radius));
}
pacman.add(new Vector2D(0, 0));
pacman.rotate(Vector2D.NULL_VECTOR, -Math.PI * 0.125);
}
return pacman;
}
private boolean dead = false;
/**
* @return Returns the dead.
*/
public boolean isDead() {
return dead;
}
@SuppressWarnings("rawtypes")
@Override
public Color getAgentColor() {
double force = ((PanicEnvironment) ((AbstractEnvironment2D) getEnvironment())).getOutsideForce(id());
if (dead) {
return Color.black;
}
force = Math.min(force / 3, 255);
return new Color(
(255f) / 255,
(255f - (float) force) / 255,
0f / 255);
}
}