Commit 965fe344 authored by gsavin's avatar gsavin

Some clean after merge-for-conflict time :)

parent e4e34fd9
......@@ -86,9 +86,12 @@
<resources>
<!-- Resources other than classes are included here. -->
<!--<resource>
<resource>
<directory>src</directory>
</resource>-->
<includes>
<include>org/graphstream/boids/configExample.dgs</include>
</includes>
</resource>
</resources>
<plugins>
......@@ -97,9 +100,6 @@
<configuration>
<source>1.5</source>
<target>1.5</target>
<excludes>
<exclude>org/graphstream/boids/gui/**</exclude>
</excludes>
</configuration>
</plugin>
......
/*
* Copyright 2006 - 2011
* Julien Baudry <julien.baudry@graphstream-project.org>
* Copyright 2006 - 2012
* Antoine Dutot <antoine.dutot@graphstream-project.org>
* Yoann Pigné <yoann.pigne@graphstream-project.org>
* Guilhelm Savin <guilhelm.savin@graphstream-project.org>
*
* This file is part of GraphStream <http://graphstream-project.org>.
* This file is part of gs-boids <http://graphstream-project.org>.
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
* gs-boids is a library whose purpose is to provide a boid behavior to a set of
* particles.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
......@@ -33,7 +31,6 @@ package org.graphstream.boids;
import java.util.Iterator;
import java.util.LinkedList;
import org.graphstream.graph.Graph;
import org.graphstream.graph.implementations.AbstractGraph;
import org.graphstream.graph.implementations.AdjacencyListNode;
import org.miv.pherd.Particle;
......@@ -44,18 +41,19 @@ import org.miv.pherd.geom.Vector3;
* Represents a single bird-oid object.
*
* <p>
* A boid is both a particle in the forces system used to compute the position and motion
* of the object, and a GraphStream node. This allows to consider a graph made of
* all the boids.
* A boid is both a particle in the forces system used to compute the position
* and motion of the object, and a GraphStream node. This allows to consider a
* graph made of all the boids.
* </p>
*
* <p>
* The boid is in fact split in two parts, the {@link Boid} class itself and the
* {@link BoidParticle} inner class that represents the boid in the forces system. The
* boid particle in turn contains a {@link Forces} object that represents all the forces
* exercising on the boid. Globally, the {@link Boid} class acts on the graph and updates
* its position, creating links toward other boids/nodes that it sees, whereas the
* {@link BoidParticle} and the {@link Forces} are used to compute the boid position.
* The boid is in fact split in two parts, the {@link Boid} class itself and the
* {@link BoidParticle} inner class that represents the boid in the forces
* system. The boid particle in turn contains a {@link BoidForces} object that
* represents all the forces exercising on the boid. Globally, the {@link Boid}
* class acts on the graph and updates its position, creating links toward other
* boids/nodes that it sees, whereas the {@link BoidParticle} and the
* {@link BoidForces} are used to compute the boid position.
* </p>
*
* @author Guilhelm Savin
......@@ -65,42 +63,52 @@ public class Boid extends AdjacencyListNode {
protected final BoidSpecies species;
protected BoidParticle particle;
/** Parameters of this group of boids. */
/** The set of forces acting on this particle. */
protected Forces forces;
protected BoidForces forces;
/**
* New boid as a node in the given graph.
*
* @param graph The graph this boids pertains to.
* @param id The boid identifier in the graph and in the force system.
*
* @param graph
* The graph this boids pertains to.
* @param id
* The boid identifier in the graph and in the force system.
*/
super((AbstractGraph) graph, id);
public Boid(AbstractGraph graph, BoidSpecies species, String id) {
super(graph, id);
this.particle = new BoidParticle((Context) graph);
this.particle = new BoidParticle((BoidGraph) graph);
this.species = species;
this.forces = getDefaultForces();
}
/** Force the position of the boid in space. */
/**
* Force the position of the boid in space.
*/
public void setPosition(double x, double y, double z) {
particle.setPosition(x, y, z);
}
/** Actual position of the boid in space. */
/**
* Actual position of the boid in space.
*/
public Point3 getPosition() {
return particle.getPosition();
}
/** Set of parameters used by this boid group. */
/**
* Set of parameters used by this boid group.
*/
public BoidSpecies getSpecies() {
return species;
}
/** Change boid group and set of parameters. */
/** The underlying particle of the force system this boids is linked to. */
/**
* The underlying particle of the force system this boids is linked to.
*/
public BoidParticle getParticle() {
return particle;
}
......@@ -109,8 +117,8 @@ public class Boid extends AdjacencyListNode {
* The forces acting on the boids, this is a set of vectors and parameters
* computed at each time step.
*/
public Forces getDefaultForces() {
return new Forces.BasicForces();
public BoidForces getDefaultForces() {
return new BoidForces.BasicForces();
}
protected void checkNeighborhood(BoidParticle... particles) {
......@@ -154,9 +162,10 @@ public class Boid extends AdjacencyListNode {
}
/**
* Compute the edge identifier between two boids knowing their individual identifiers.
* This method ensures the identifiers are always in the same order so that we get the
* same edge whatever the order of the parameters b1 and b2.
* Compute the edge identifier between two boids knowing their individual
* identifiers. This method ensures the identifiers are always in the same
* order so that we get the same edge whatever the order of the parameters
* b1 and b2.
*/
public static final String getEdgeId(Boid b1, Boid b2) {
if (b1.hashCode() > b2.hashCode()) {
......@@ -169,29 +178,40 @@ public class Boid extends AdjacencyListNode {
}
/**
* Internal representation of the boid position, and direction in the forces system.
* Internal representation of the boid position, and direction in the forces
* system.
*
* @author Guilhelm Savin
* @author Antoine Dutot
*/
class BoidParticle extends Particle {
/** Direction of the boid. */
/**
* Direction of the boid.
*/
protected Vector3 dir;
/** Set of global parameters. */
protected Context ctx;
/** Number of boids in view at each step. */
/**
* Set of global parameters.
*/
protected BoidGraph ctx;
/**
* Number of boids in view at each step.
*/
protected int contacts = 0;
/** Number of boids of my group in view at each step. */
/**
* Number of boids of my group in view at each step.
*/
protected int mySpeciesContacts = 0;
/**
/**
* New particle.
* @param ctx The set of global parameters.
*
* @param ctx
* The set of global parameters.
*/
public BoidParticle(Context ctx) {
public BoidParticle(BoidGraph ctx) {
super(Boid.this.getId(), ctx.random.nextDouble() * (ctx.area * 2)
- ctx.area, ctx.random.nextDouble() * (ctx.area * 2)
- ctx.area, 0);
......
/*
* Copyright 2006 - 2012
* Antoine Dutot <antoine.dutot@graphstream-project.org>
* Guilhelm Savin <guilhelm.savin@graphstream-project.org>
*
* This file is part of gs-boids <http://graphstream-project.org>.
*
* gs-boids is a library whose purpose is to provide a boid behavior to a set of
* particles.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/
package org.graphstream.boids;
import java.util.Iterator;
......
/*
* Copyright 2006 - 2011
* Julien Baudry <julien.baudry@graphstream-project.org>
* Copyright 2006 - 2012
* Antoine Dutot <antoine.dutot@graphstream-project.org>
* Yoann Pigné <yoann.pigne@graphstream-project.org>
* Guilhelm Savin <guilhelm.savin@graphstream-project.org>
*
* This file is part of GraphStream <http://graphstream-project.org>.
* This file is part of gs-boids <http://graphstream-project.org>.
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
* gs-boids is a library whose purpose is to provide a boid behavior to a set of
* particles.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
......@@ -44,37 +42,52 @@ import org.miv.pherd.ntree.Cell;
* Models the forces applied to a boid at each step.
*
* <p>
* This object is modified at each computation step to represent the forces applied to
* a boid particle in the forces system. It is in charge of going down the n-tree used
* to represent space and collect all the other boids in the field of view that could influence
* this boid. It then integrates these forces and compute a direction and barycenter (the
* point the boid tries to reach).
* This object is modified at each computation step to represent the forces
* applied to a boid particle in the forces system. It is in charge of going
* down the n-tree used to represent space and collect all the other boids in
* the field of view that could influence this boid. It then integrates these
* forces and compute a direction and barycenter (the point the boid tries to
* reach).
* </p>
*
*
* @author Guilhelm Savin
* @author Antoine Dutot
*/
public abstract class Forces {
/** The position the boid tries to reach at each step. */
public abstract class BoidForces {
/**
* The position the boid tries to reach at each step.
*/
public Point3 barycenter;
/** The direction of the boid at each step. */
/**
* The direction of the boid at each step.
*/
public Vector3 direction;
/** The integrated attraction toward other boids in view at each step. */
/**
* The integrated attraction toward other boids in view at each step.
*/
public Vector3 attraction;
/** The integrated repulsion from the other boids in view at each step. */
/**
* The integrated repulsion from the other boids in view at each step.
*/
public Vector3 repulsion;
/** The number of boids we are attracted to. */
/**
* The number of boids we are attracted to.
*/
public int countAtt;
/** The number of boids we are repulsed from. */
/**
* The number of boids we are repulsed from.
*/
public int countRep;
/** Forces all set at zero. */
public Forces() {
/**
* Forces all set at zero.
*/
public BoidForces() {
barycenter = new Point3();
direction = new Vector3();
attraction = new Vector3();
......@@ -111,45 +124,56 @@ public abstract class Forces {
boid.setAttribute("force2", repulsion);
}
/** Integrate a repulsion vector. */
/**
* Integrate a repulsion vector.
*/
public void addRepulsion(Vector3 rep) {
repulsion.add(rep);
countRep++;
}
/** Integrate a direction influence. */
/**
* Integrate a direction influence.
*/
public void addDirection(Vector3 dir) {
direction.add(dir);
countAtt++;
}
/** Integrate an attraction vector. */
/**
* Integrate an attraction vector.
*/
public void addAttraction(Vector3 att) {
attraction.add(att);
countAtt++;
}
/** Integrate a new point of influence. */
/**
* Integrate a new point of influence.
*/
public void moveBarycenter(Point3 p) {
barycenter.move(p);
}
/** Is the another point is space in the field of view? */
public abstract boolean isVisible(BoidParticle boid, Point3 other);
/**
* Is the another point is space in the field of view?
*/
public abstract boolean isVisible(BoidParticle boid, Point3 other);
/**
* A basic definition of forces for a boid.
*
* <p>
* The kind of forces exercising on a boid can be changed to either use a n-tree or not,
* or to account for other kind of forces or another force model. This is the default
* force system that matches the basic boid definition as defined by Craig Reynolds.
* The kind of forces exercising on a boid can be changed to either use a
* n-tree or not, or to account for other kind of forces or another force
* model. This is the default force system that matches the basic boid
* definition as defined by Craig Reynolds.
* </p>
*
* @author Guilhelm Savin
* @author Antoine Dutot
*/
public static class BasicForces extends Forces {
public static class BasicForces extends BoidForces {
@Override
public void compute(Boid source, Cell startCell) {
barycenter.set(0, 0, 0);
......@@ -158,13 +182,14 @@ public abstract class Forces {
repulsion.fill(0);
countAtt = 0;
countRep = 0;
Set<BoidParticle> contacts = new HashSet<BoidParticle>();
exploreTree(source, startCell, contacts);
source.checkNeighborhood(contacts.toArray(new BoidParticle[contacts.size()]));
source.checkNeighborhood(contacts.toArray(new BoidParticle[contacts
.size()]));
if (countAtt > 0) {
barycenter.scale(1f / countAtt, 1f / countAtt, 1f / countAtt);
direction.scalarDiv(countAtt);
......@@ -187,7 +212,8 @@ public abstract class Forces {
* @param cell
* The cell to explore recursively.
*/
protected void exploreTree(Boid source, Cell cell, Set<BoidParticle> contacts) {
protected void exploreTree(Boid source, Cell cell,
Set<BoidParticle> contacts) {
if (intersection(source, cell)) {
if (cell.isLeaf()) {
forcesFromCell(source.getParticle(), cell, contacts);
......@@ -209,18 +235,19 @@ public abstract class Forces {
* @param cell
* The cell.
*/
protected void forcesFromCell(BoidParticle source, Cell cell, Set<BoidParticle> contacts) {
protected void forcesFromCell(BoidParticle source, Cell cell,
Set<BoidParticle> contacts) {
// BoidCellData data = (BoidCellData) cell.getData();
Iterator<? extends Particle> particles = cell.getParticles();
Vector3 rep = new Vector3();
//LinkedList<BoidParticle> contacts = null;
// LinkedList<BoidParticle> contacts = null;
while (particles.hasNext()) {
Particle particle = particles.next();
if (particle instanceof BoidParticle) {
//if (contacts == null)
// contacts = new LinkedList<BoidParticle>();
// if (contacts == null)
// contacts = new LinkedList<BoidParticle>();
if (source != particle
&& isVisible(source, particle.getPosition())) {
......@@ -266,14 +293,14 @@ public abstract class Forces {
// intersection (cases c, d, e and f).
//
// |-a-| +---------+ |-b-|
// | |
// |-c-| |-d-|
// | |
// | |-e-| |
// | |
// |-+----f----+-|
// | |
// +---------+
// | |
// |-c-| |-d-|
// | |
// | |-e-| |
// | |
// |-+----f----+-|
// | |
// +---------+
if (X2 < x1 || X1 > x2)
return false;
......@@ -291,17 +318,17 @@ public abstract class Forces {
* True if the given position is visible by the boid.
*
* <p>
* This method first check if the given point is under the max distance of
* view. If so, it checks if the point is in the angle of view. The angle
* of view is specified as the cosine of the angle between the boid direction
* vector and the vector between the boid and the given point. This means
* that -1 is equal to a 360 degree of vision (the angle of view test is
* deactivated in this case), 0 means 180 degree angle, and 0.5 a 90 degree
* angle for example.
* This method first check if the given point is under the max distance
* of view. If so, it checks if the point is in the angle of view. The
* angle of view is specified as the cosine of the angle between the
* boid direction vector and the vector between the boid and the given
* point. This means that -1 is equal to a 360 degree of vision (the
* angle of view test is deactivated in this case), 0 means 180 degree
* angle, and 0.5 a 90 degree angle for example.
* </p>
*
* @param source
* The source boid.
* The source boid.
* @param point
* The point to consider.
*
......@@ -309,44 +336,52 @@ public abstract class Forces {
*/
@Override
public boolean isVisible(BoidParticle source, Point3 point) {
// Check both the distance and angle of view according to the direction
// Check both the distance and angle of view according to the
// direction
// of the source.
BoidSpecies species = source.getBoid().getSpecies();
Point3 pos = source.getPosition();
double d = pos.distance(point);
double d = pos.distance(point);
// At good distance.
if(d <= species.viewZone) {
if (d <= species.viewZone) {
// If there is an angle of view.
if(species.angleOfView > -1) {
Vector3 dir = new Vector3(source.dir);
Vector3 light = new Vector3(point.x - pos.x, point.y - pos.y, point.z - pos.z);//(pos.x - point.x, pos.y - point.y, pos.z - point.z);
if (species.angleOfView > -1) {
Vector3 dir = new Vector3(source.dir);
Vector3 light = new Vector3(point.x - pos.x, point.y
- pos.y, point.z - pos.z);// (pos.x - point.x, pos.y
// - point.y, pos.z -
// point.z);
dir.normalize();
light.normalize();
double angle = dir.dotProduct(light);
double angle = dir.dotProduct(light);
// In the field of view.
if(angle > species.angleOfView)
if (angle > species.angleOfView)
return true;
} else {
return true;
}
}
// Not in view.
return false;
}
/**
* A boid particle p2 that is visible by p1 as been found, integrate it in the forces that
* apply to the boid p1.
* @param p1 The source boid.
* @param p2 the boid visible by p1.
* @param rep The repulsion to compute.
* A boid particle p2 that is visible by p1 as been found, integrate it
* in the forces that apply to the boid p1.
*
* @param p1
* The source boid.
* @param p2
* the boid visible by p1.
* @param rep
* The repulsion to compute.
*/
protected void actionWithNeighboor(BoidParticle p1, BoidParticle p2,
Vector3 rep) {
......@@ -355,21 +390,22 @@ public abstract class Forces {
BoidSpecies p2Species = p2.getBoid().getSpecies();
double v = p1.getBoid().getSpecies().viewZone;
rep.set(p1.getPosition().x - pp.x, p1.getPosition().y - pp.y,
p1.getPosition().z - pp.z);
rep.set(p1.getPosition().x - pp.x, p1.getPosition().y - pp.y, p1
.getPosition().z
- pp.z);
double len = rep.length();
if (len != 0) {
if (p1Species != p2Species)
rep.scalarMult(1 / (len * len) * p2Species.getFearFactor());
else
rep.scalarMult(1 / (len * len));
}
double a = Math.log(Math.min(len, v)) / Math.log(v);
rep.scalarMult(a);
repulsion.add(rep);
countRep++;
......
/*
* Copyright 2006 - 2011
* Julien Baudry <julien.baudry@graphstream-project.org>
* Copyright 2006 - 2012
* Antoine Dutot <antoine.dutot@graphstream-project.org>
* Yoann Pigné <yoann.pigne@graphstream-project.org>
* Guilhelm Savin <guilhelm.savin@graphstream-project.org>
*
* This file is part of GraphStream <http://graphstream-project.org>.
* This file is part of gs-boids <http://graphstream-project.org>.
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
* gs-boids is a library whose purpose is to provide a boid behavior to a set of
* particles.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
......@@ -57,7 +55,7 @@ import java.util.Random;
* @author Guilhelm Savin
* @author Antoine Dutot
*/
public class Context extends AdjacencyListGraph {
public class BoidGraph extends AdjacencyListGraph {
public static enum Parameter {
MAX_STEPS, AREA, SLEEP_TIME, STORE_FORCES_ATTRIBUTES, REMOVE_CAUGHT_BOIDS, NORMALIZE_MODE, RANDOM_SEED
......@@ -131,7 +129,7 @@ public class Context extends AdjacencyListGraph {
/**
* New context.
*/
public Context() {
public BoidGraph() {
super("boids-context");
setNodeFactory(new BoidFactory());
......@@ -153,7 +151,7 @@ public class Context extends AdjacencyListGraph {
pbox = new ParticleBox(maxParticlesPerCell, space, new BoidCellData());
}
public Context(String dgsConfig) throws IOException {
public BoidGraph(String dgsConfig) throws IOException {