Commit db61fbc7 authored by gsavin's avatar gsavin

Add degree limitation. Separate 2D/3D NTree.

parent 117f00d6
......@@ -49,8 +49,8 @@ import org.miv.pherd.geom.Point3;
* 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 BoidForces} are used to compute the boid position.
* position, creating links toward other boids/nodes that it sees, whereas the
* {@link BoidForces} are used to compute the boid position.
* </p>
*
* @author Guilhelm Savin
......@@ -109,7 +109,7 @@ public class Boid extends AdjacencyListNode {
}
public void checkNeighborhood(Boid... boids) {
if(getGraph().getNode(getId()) == null) {
if (getGraph().getNode(getId()) == null) {
System.err.printf("I do not exist any more !!!%n");
return;
}
......@@ -146,10 +146,13 @@ public class Boid extends AdjacencyListNode {
}
for (Boid b2 : boids) {
if (getEdgeBetween(b2) == null) {
if(getGraph().getNode(b2.getId())!= null)
if (getEdgeBetween(b2) == null
&& getDegree() < species.maxNeighborhood) {
if (getGraph().getNode(b2.getId()) != null)
getGraph().addEdge(getEdgeId(this, b2), this, b2);
else System.err.printf("%s does not exists !!%n", b2.getId());
else
System.err
.printf("%s does not exists !!%n", b2.getId());
}
}
} else {
......
......@@ -133,8 +133,8 @@ public abstract class BoidForces {
direction.scalarDiv(countAtt);
attraction
.set(barycenter.x - boid.getPosition().x, barycenter.y
- boid.getPosition().y, barycenter.z
- boid.getPosition().z);
- boid.getPosition().y,
barycenter.z - boid.getPosition().z);
}
if (countRep > 0) {
......@@ -262,6 +262,8 @@ public abstract class BoidForces {
nextPos.y = hi.y - aarea;
dir.data[1] = -dir.data[1];
}
if (is3D()) {
if (nextPos.z + dir.data[2] <= lo.z + aarea) {
nextPos.z = lo.z + aarea;
dir.data[2] = -dir.data[2];
......@@ -270,6 +272,7 @@ public abstract class BoidForces {
dir.data[2] = -dir.data[2];
}
}
}
/**
* True if the given position is visible by the boid.
......@@ -345,4 +348,6 @@ public abstract class BoidForces {
public abstract Point3 getNextPosition();
public abstract Collection<Boid> getNeighborhood();
public abstract boolean is3D();
}
\ No newline at end of file
......@@ -549,6 +549,16 @@ public class BoidGraph extends AdjacencyListGraph {
public void step() {
step++;
for (BoidSpecies sp : boidSpecies.values()) {
sp.terminateStep(step);
}
for (BoidGraphListener listener : boidGraphListeners) {
listener.step(step);
}
forcesFactory.step();
stepBegins(step);
}
......@@ -720,23 +730,6 @@ public class BoidGraph extends AdjacencyListGraph {
set(key, null);
}
}
/*
* (non-Javadoc)
*
* @see org.graphstream.stream.SinkAdapter#stepBegins(java.lang.String,
* long, double)
*/
public void stepBegins(String sourceId, long timeId, double step) {
for (BoidSpecies sp : boidSpecies.values()) {
sp.terminateStep(step);
}
for (BoidGraphListener listener : boidGraphListeners) {
listener.step(step);
}
forcesFactory.step();
}
}
private class BoidFactory implements NodeFactory<Boid> {
......@@ -762,7 +755,7 @@ public class BoidGraph extends AdjacencyListGraph {
BoidGraph ctx = new BoidGraph();
try {
ctx.loadDGSConfiguration("configExampleWithTwoSpecies.dgs");
ctx.loadDGSConfiguration("configExample.dgs");
} catch (Exception e1) {
e1.printStackTrace();
}
......
......@@ -46,7 +46,7 @@ public class BoidSpecies implements Iterable<Boid> {
* Kinds of parameters.
*/
public static enum Parameter {
COUNT, ANGLE_OF_VIEW, VIEW_ZONE, SPEED_FACTOR, MAX_SPEED, MIN_SPEED, DIRECTION_FACTOR, ATTRACTION_FACTOR, REPULSION_FACTOR, INERTIA, FEAR_FACTOR, ADD_SPECIES_NAME_IN_UI_CLASS
COUNT, ANGLE_OF_VIEW, VIEW_ZONE, SPEED_FACTOR, MAX_SPEED, MIN_SPEED, DIRECTION_FACTOR, ATTRACTION_FACTOR, REPULSION_FACTOR, INERTIA, FEAR_FACTOR, ADD_SPECIES_NAME_IN_UI_CLASS, MAX_NEIGHBORHOOD
}
/**
......@@ -158,6 +158,8 @@ public class BoidSpecies implements Iterable<Boid> {
protected int initialCount = 0;
int maxNeighborhood = 20;
/**
* New default species with a random color.
*
......@@ -270,6 +272,13 @@ public class BoidSpecies implements Iterable<Boid> {
case ADD_SPECIES_NAME_IN_UI_CLASS:
addSpeciesNameInUIClass = Boolean.parseBoolean(val);
break;
case MAX_NEIGHBORHOOD:
maxNeighborhood = (int) Double.parseDouble(val);
if (maxNeighborhood <= 0)
maxNeighborhood = Integer.MAX_VALUE;
break;
}
}
......
......@@ -5,7 +5,7 @@ null 0 0
# GraphStream attributes
#
cg ui.quality ui.antialias
#cg ui.quality ui.antialias
cg ui.stylesheet="node { size: 4px; } node.moustik { fill-color: #1d1d1d; } edge { fill-color: grey; }"
#
......@@ -13,7 +13,7 @@ cg ui.stylesheet="node { size: 4px; } node.moustik { fill-color: #1d1d1d; } edge
#
cg boids.max_steps=8000
cg boids.random_seed=2132134879
#cg boids.random_seed=2132134879
cg boids.area=1
cg boids.sleep_time=30
......@@ -22,7 +22,7 @@ cg boids.sleep_time=30
#
cg boids.species.moustik=org.graphstream.boids.BoidSpecies # Create a new species using class BoidSpecies
cg boids.species.moustik.angle_of_view=0 # Set angleOfView of this species to 0
cg boids.species.moustik.angle_of_view=0.25 # Set angleOfView of this species to 0
cg boids.species.moustik.view_zone=0.15 # Set viewZone
cg boids.species.moustik.speed_factor=0.3 # Set speedFactor
cg boids.species.moustik.max_speed=1 # Set maxSpeed
......@@ -31,10 +31,13 @@ cg boids.species.moustik.direction_factor=0.1 # Set directionFactor
cg boids.species.moustik.attraction_factor=0.5 # Set attractionFactor
cg boids.species.moustik.repulsion_factor=0.001 # Set repulsionFactor
cg boids.species.moustik.inertia=1.1 # Set inertia
cg boids.species.moustik.max_neighborhood=10
cg boids.species.moustik.add_species_name_in_ui_class=true # Tell species to add its name in the 'ui.class' attribute
# of node, so we can define a custom css for each species.
#
# This last command create 100 boids of the moustik species
#
cg boids.species.moustik.count=100
cg boids.species.moustik.count=1000
cg boids.forces_factory=org.graphstream.boids.forces.ntree.NTreeForcesFactory
\ No newline at end of file
......@@ -5,7 +5,7 @@ null 0 0
# GraphStream attributes
#
cg ui.quality ui.antialias
#cg ui.quality ui.antialias
cg ui.stylesheet="node.bee { size: 10px; fill-color: orange; } node.moustik { size: 4px; fill-color: #1d1d1d; } edge { fill-color: grey; }"
#
......@@ -22,7 +22,7 @@ cg boids.sleep_time=30
#
cg boids.species.moustik=org.graphstream.boids.BoidSpecies
cg boids.species.moustik.angle_of_view=0
cg boids.species.moustik.angle_of_view=0.1
cg boids.species.moustik.view_zone=0.15
cg boids.species.moustik.speed_factor=0.3
cg boids.species.moustik.max_speed=0.9
......@@ -44,7 +44,7 @@ cg boids.species.bee.speed_factor=0.3
cg boids.species.bee.max_speed=1
cg boids.species.bee.min_speed=0.1
cg boids.species.bee.direction_factor=0.2
cg boids.species.bee.attraction_factor=0.3
cg boids.species.bee.attraction_factor=0.4
cg boids.species.bee.repulsion_factor=0.005
cg boids.species.bee.inertia=1.1
cg boids.species.bee.add_species_name_in_ui_class=true
......@@ -53,7 +53,7 @@ cg boids.species.bee.add_species_name_in_ui_class=true
# This last command create 100 boids of the moustik species
#
cg boids.species.moustik.count=100
cg boids.species.moustik.count=1000
cg boids.species.bee.count=100
cg boids.forces_factory=org.graphstream.boids.forces.greedy.GreedyForcesFactory
cg boids.forces_factory=org.graphstream.boids.forces.ntree.NTreeForcesFactory
......@@ -103,4 +103,13 @@ public class GreedyForces extends BoidForces {
public Point3 getNextPosition() {
return nextPosition;
}
/*
* (non-Javadoc)
*
* @see org.graphstream.boids.BoidForces#is3D()
*/
public boolean is3D() {
return false;
}
}
......@@ -150,17 +150,13 @@ public class NTreeForces extends BoidForces {
double x1 = cell.getSpace().getLoAnchor().x;
double y1 = cell.getSpace().getLoAnchor().y;
double z1 = cell.getSpace().getLoAnchor().z;
double x2 = cell.getSpace().getHiAnchor().x;
double y2 = cell.getSpace().getHiAnchor().y;
double z2 = cell.getSpace().getHiAnchor().z;
double X1 = source.getPosition().x - vz;
double Y1 = source.getPosition().y - vz;
double Z1 = source.getPosition().z - vz;
double X2 = source.getPosition().x + vz;
double Y2 = source.getPosition().y + vz;
double Z2 = source.getPosition().z + vz;
// Only when the area is before or after the cell there cannot
// exist an intersection (case a and b). Else there must be an
......@@ -182,9 +178,6 @@ public class NTreeForces extends BoidForces {
if (Y2 < y1 || Y1 > y2)
return false;
if (Z2 < z1 || Z1 > z2)
return false;
return true;
}
......@@ -202,4 +195,13 @@ public class NTreeForces extends BoidForces {
return neigh;
}
/*
* (non-Javadoc)
*
* @see org.graphstream.boids.BoidForces#is3D()
*/
public boolean is3D() {
return false;
}
}
\ No newline at end of file
/*
* 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.forces.ntree;
import org.graphstream.boids.Boid;
import org.miv.pherd.ntree.Cell;
/**
* 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.
* </p>
*
* @author Guilhelm Savin
* @author Antoine Dutot
*/
public class NTreeForces3D extends NTreeForces {
public NTreeForces3D(BoidParticle p) {
super(p);
}
/**
* A rectangular intersection function, is the boid view area intersecting
* the given cell?. This provides a quick lookup function to test if a cell
* must be explored or not. Later, a better test according to a spherical
* view zone will be done.
*
* @param cell
* The cell to test for intersection with the boid rectangular
* view area.
* @return True if there is an intersection.
*/
protected boolean intersection(Boid source, Cell cell) {
double vz = source.getSpecies().getViewZone();
double x1 = cell.getSpace().getLoAnchor().x;
double y1 = cell.getSpace().getLoAnchor().y;
double z1 = cell.getSpace().getLoAnchor().z;
double x2 = cell.getSpace().getHiAnchor().x;
double y2 = cell.getSpace().getHiAnchor().y;
double z2 = cell.getSpace().getHiAnchor().z;
double X1 = source.getPosition().x - vz;
double Y1 = source.getPosition().y - vz;
double Z1 = source.getPosition().z - vz;
double X2 = source.getPosition().x + vz;
double Y2 = source.getPosition().y + vz;
double Z2 = source.getPosition().z + vz;
// Only when the area is before or after the cell there cannot
// exist an intersection (case a and b). Else there must be an
// intersection (cases c, d, e and f).
//
// |-a-| +---------+ |-b-|
// | |
// |-c-| |-d-|
// | |
// | |-e-| |
// | |
// |-+----f----+-|
// | |
// +---------+
if (X2 < x1 || X1 > x2)
return false;
if (Y2 < y1 || Y1 > y2)
return false;
if (Z2 < z1 || Z1 > z2)
return false;
return true;
}
/*
* (non-Javadoc)
*
* @see org.graphstream.boids.BoidForces#is3D()
*/
public boolean is3D() {
return true;
}
}
\ No newline at end of file
......@@ -39,6 +39,7 @@ import org.miv.pherd.geom.Point3;
import org.miv.pherd.ntree.Anchor;
import org.miv.pherd.ntree.CellSpace;
import org.miv.pherd.ntree.OctreeCellSpace;
import org.miv.pherd.ntree.QuadtreeCellSpace;
public class NTreeForcesFactory implements BoidForcesFactory, ElementSink {
......@@ -50,12 +51,25 @@ public class NTreeForcesFactory implements BoidForcesFactory, ElementSink {
protected BoidGraph ctx;
protected boolean is3D;
public NTreeForcesFactory(BoidGraph ctx) {
this(ctx, false);
}
public NTreeForcesFactory(BoidGraph ctx, boolean is3D) {
double area = ctx.getArea();
int maxParticlesPerCell = 10;
this.is3D = is3D;
if (is3D)
this.space = new OctreeCellSpace(new Anchor(-area, -area, -area),
new Anchor(area, area, area));
else
this.space = new QuadtreeCellSpace(new Anchor(-area, -area, 0),
new Anchor(area, area, 0));
this.pbox = new ParticleBox(maxParticlesPerCell, space,
new BoidCellData());
this.ctx = ctx;
......@@ -84,7 +98,7 @@ public class NTreeForcesFactory implements BoidForcesFactory, ElementSink {
*/
public BoidForces createNewForces(Boid b) {
BoidParticle p = new BoidParticle(ctx, b);
NTreeForces f = new NTreeForces(p);
NTreeForces f = is3D ? new NTreeForces3D(p) : new NTreeForces(p);
return f;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment