
fr.vergne.downhill.impl.WaveDownhillCollider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of downhill-core Show documentation
Show all versions of downhill-core Show documentation
Implementation of the downhill collider algorithm.
The newest version!
package fr.vergne.downhill.impl;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import fr.vergne.downhill.DownhillCollider;
/**
* The {@link WaveDownhillCollider} aims at creating {@link Ball}s by waves: all
* the {@link Ball}s available at an iteration t
are collided (when
* possible) to create new {@link Ball}s (the ones already known are discarded)
* for t+1
. Then all the {@link Ball}s at t+1
are used
* to create the ones at t+2
, etc. Finally, when no new
* {@link Ball} is created, the last non-empty wave is returned.
*
* @author Matthieu Vergne
*
* @param
*/
public class WaveDownhillCollider implements DownhillCollider {
private final boolean isOrderIndependent;
public WaveDownhillCollider() {
this(false);
}
/**
* The argument allows to optimize the process by reducing the number of
* evaluations: if evaluating two {@link Ball}s b1
and
* b2
gives exactly the same result independently of their
* order ( areColliding(b1,b2) == areColliding(b2,b1)
and
* collides(b1,b2) == collides(b2,b1)
) then you can switch the
* argument to true
to evaluate only one order. If the order
* matter (or if you don't know), you can set it the argument to
* false
to ask the evaluation of both the orders. The default
* case ({@link #WaveDownhillCollider()}) set the argument to
* false
.
*
* @param isOrderIndependent
* if true
, then only one couple of ball (b1, b2) is
* collided, otherwise we also collide (b2, b1).
*/
public WaveDownhillCollider(boolean isOrderIndependent) {
this.isOrderIndependent = isOrderIndependent;
}
@Override
public Collection rolls(Collection balls,
Collider... colliders) {
Collection result;
if (isOrderIndependent) {
result = rollsIndependent(balls, colliders);
} else {
result = rollsDependent(balls, colliders);
}
return new ReductionDownhillCollider().rolls(result, colliders);
}
public Collection rollsDependent(Collection balls,
Collider... colliders) {
Collection oldBalls = null;
Collection newBalls = new HashSet(balls);
do {
oldBalls = newBalls;
newBalls = new HashSet();
for (Ball b1 : oldBalls) {
for (Ball b2 : oldBalls) {
for (Collider collider : colliders) {
if (collider.areColliding(b1, b2)) {
Ball collided = collider.collide(b1, b2);
newBalls.add(collided);
} else {
// not able to merge them
}
}
}
}
newBalls.removeAll(oldBalls);
} while (!newBalls.isEmpty());
return oldBalls;
}
public Collection rollsIndependent(Collection balls,
Collider... colliders) {
Collection oldBalls = null;
Collection newBalls = new HashSet(balls);
do {
oldBalls = newBalls;
newBalls = new HashSet();
LinkedList remaining = new LinkedList(oldBalls);
while (!remaining.isEmpty()) {
Ball b1 = remaining.removeFirst();
for (Ball b2 : remaining) {
for (Collider collider : colliders) {
if (collider.areColliding(b1, b2)) {
Ball collided = collider.collide(b1, b2);
newBalls.add(collided);
} else {
// not able to merge them
}
}
}
}
newBalls.removeAll(oldBalls);
} while (!newBalls.isEmpty());
return oldBalls;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy