Commit eda455bd authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

change the spawn algorithm if useRandomPosition and useFreeSpace is true i.e....

change the spawn algorithm if useRandomPosition and useFreeSpace is true i.e. generate real random position inside the rectangle.
parent 065dabd4
Pipeline #69972 failed with stages
in 48 seconds
package org.vadere.simulator.control;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.system.CallbackI;
import org.vadere.simulator.models.DynamicElementFactory;
import org.vadere.state.attributes.scenario.AttributesDynamicElement;
import org.vadere.state.scenario.Source;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SingleSourceController extends SourceController {
private int numberToSpawn;
private DynamicElementFactory dynamicElementFactory;
private static final int NUMBER_OF_REPOSITION_TRIES = 10;
public SingleSourceController(Topography scenario, Source source,
DynamicElementFactory dynamicElementFactory,
AttributesDynamicElement attributesDynamicElement,
Random random) {
super(scenario, source, dynamicElementFactory, attributesDynamicElement, random);
this.dynamicElementFactory = dynamicElementFactory;
}
@Override
......@@ -25,18 +37,28 @@ public class SingleSourceController extends SourceController {
if (!isSourceFinished(simTimeInSec)) {
if (simTimeInSec >= timeOfNextEvent || numberToSpawn > 0) {
determineNumberOfSpawnsAndNextEvent(simTimeInSec);
LinkedList<VPoint> spawnPoints = new LinkedList<>();
List<VPoint> spawnPoints = new LinkedList<>();
if (sourceAttributes.isSpawnAtRandomPositions()) {
if (sourceAttributes.isUseFreeSpaceOnly()) {
spawnPoints = spawnArray.getNextFreeRandomSpawnPoints(numberToSpawn, random, getDynElementsAtSource());
//spawnPoints = spawnArray.getNextFreeRandomSpawnPoints(numberToSpawn, random, getDynElementsAtSource());
spawnPoints = getRealRandomPositions(
numberToSpawn,
random,
getDynElementsAtSource().stream()
.map(element -> element.getPosition())
.map(position -> dynamicElementFactory.getDynamicElementRequiredPlace(position))
.collect(Collectors.toList())
);
numberToSpawn -= spawnPoints.size();
assert (numberToSpawn >= 0);
} else {
spawnPoints = spawnArray.getNextRandomSpawnPoints(numberToSpawn, random, getDynElementsAtSource());
throw new IllegalArgumentException("use random position without free space only makes no sense.");
/*spawnPoints = spawnArray.getNextRandomSpawnPoints(numberToSpawn, random, getDynElementsAtSource());
numberToSpawn -= spawnPoints.size();
assert (numberToSpawn >= 0);
assert (numberToSpawn >= 0);*/
}
} else {
......@@ -63,6 +85,47 @@ public class SingleSourceController extends SourceController {
}
}
/**
* Computes numberToSpawn or less random positions based on the blockPedestrianShapes which contains the shapes representing the required space of each pedestrian.
* For each required position the algorithms tries {@link SingleSourceController#NUMBER_OF_REPOSITION_TRIES} times to get a feasible free position.
*
* @param numberToSpawn number of required spawn positions
* @param random random generator
* @param blockPedestrianShapes the required space of other pedestrians
* @return numberToSpawn or less random feasible positions
*/
private List<VPoint> getRealRandomPositions(final int numberToSpawn, @NotNull final Random random, @NotNull final List<VShape> blockPedestrianShapes) {
List<VPoint> randomPositions = new ArrayList<>(numberToSpawn);
for(int i = 0; i < numberToSpawn; i++) {
Optional<VPoint> optRandomPosition = getNextRandomPosition(random, blockPedestrianShapes, NUMBER_OF_REPOSITION_TRIES);
if (optRandomPosition.isPresent()) {
VPoint randomPosition = optRandomPosition.get();
blockPedestrianShapes.add(dynamicElementFactory.getDynamicElementRequiredPlace(randomPosition));
randomPositions.add(randomPosition);
}
}
return randomPositions;
}
private Optional<VPoint> getNextRandomPosition(@NotNull final Random random, @NotNull final List<VShape> blockPedestrianShapes, final int tries) {
Rectangle2D rec = source.getShape().getBounds2D();
for(int i = 0; i < tries; i++) {
VPoint randomPoint = new VPoint(rec.getMinX() + random.nextDouble() * rec.getWidth(), rec.getMinY() + random.nextDouble() * rec.getHeight());
VShape freeSpaceRequired = dynamicElementFactory.getDynamicElementRequiredPlace(randomPoint);
// no intersection with other free spaces.
if(blockPedestrianShapes.stream().noneMatch(shape -> shape.intersects(freeSpaceRequired))) {
return Optional.of(randomPoint);
}
}
return Optional.empty();
}
@Override
protected boolean isQueueEmpty() {
......
package org.vadere.simulator.models;
import org.jetbrains.annotations.NotNull;
import org.vadere.state.scenario.DynamicElement;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
public interface DynamicElementFactory {
......@@ -11,5 +13,13 @@ public interface DynamicElementFactory {
* Note: Every attribute of the given element should be cloned for each individual in this
* method, because some fields are individual.
*/
public <T extends DynamicElement> DynamicElement createElement(VPoint position, int id, Class<T> type);
<T extends DynamicElement> DynamicElement createElement(VPoint position, int id, Class<T> type);
/**
* Returns the shape which represents the (free) place required by each element.
*
* @param position the position of the shape i.e. the next created {@link DynamicElement}
* @return the shape which represents the (free) place required by each element.
*/
VShape getDynamicElementRequiredPlace(@NotNull final VPoint position);
}
......@@ -6,9 +6,11 @@ import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import org.jetbrains.annotations.NotNull;
import org.vadere.annotation.factories.models.ModelClass;
import org.vadere.simulator.models.MainModel;
import org.vadere.simulator.models.Model;
import org.vadere.simulator.models.osm.PedestrianOSM;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.models.AttributesBHM;
import org.vadere.state.attributes.scenario.AttributesAgent;
......@@ -17,6 +19,7 @@ import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Target;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
@ModelClass(isMainModel = true)
public class BehaviouralHeuristicsModel implements MainModel {
......@@ -70,13 +73,23 @@ public class BehaviouralHeuristicsModel implements MainModel {
AttributesAgent pedAttributes = new AttributesAgent(
this.attributesPedestrian, id > 0 ? id : pedestrianIdCounter);
PedestrianBHM pedestrian = new PedestrianBHM(topography, pedAttributes, attributesBHM, random);
PedestrianBHM pedestrian = createElement(position, pedAttributes);
pedestrian.setPosition(position);
this.pedestrianEventsQueue.add(pedestrian);
return pedestrian;
}
private PedestrianBHM createElement(VPoint position, @NotNull final AttributesAgent pedAttributes) {
PedestrianBHM pedestrian = new PedestrianBHM(topography, pedAttributes, attributesBHM, random);
pedestrian.setPosition(position);
return pedestrian;
}
@Override
public VShape getDynamicElementRequiredPlace(@NotNull final VPoint position) {
return createElement(position, new AttributesAgent(attributesPedestrian, -1)).getShape();
}
@Override
public void preLoop(final double simTimeInSec) {
this.lastSimTimeInSec = simTimeInSec;
......
......@@ -4,9 +4,11 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import org.jetbrains.annotations.NotNull;
import org.vadere.annotation.factories.models.ModelClass;
import org.vadere.simulator.models.MainModel;
import org.vadere.simulator.models.Model;
import org.vadere.simulator.models.bhm.PedestrianBHM;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.models.AttributesBHM;
import org.vadere.state.attributes.models.AttributesBMM;
......@@ -15,6 +17,7 @@ import org.vadere.state.scenario.DynamicElement;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
/**
*
......@@ -61,14 +64,22 @@ public class BiomechanicsModel implements MainModel {
AttributesAgent pedAttributes = new AttributesAgent(
this.attributesPedestrian, id > 0 ? id : pedestrianIdCounter);
PedestrianBMM pedestrian = new PedestrianBMM(position, topography, pedAttributes,
attributesBMM, attributesBHM, random);
PedestrianBMM pedestrian = createElement(position, pedAttributes);
this.pedestriansBMM.add(pedestrian);
return pedestrian;
}
private PedestrianBMM createElement(@NotNull final VPoint position, @NotNull final AttributesAgent pedAttributes) {
PedestrianBMM pedestrian = new PedestrianBMM(position, topography, pedAttributes, attributesBMM, attributesBHM, random);
return pedestrian;
}
@Override
public VShape getDynamicElementRequiredPlace(@NotNull final VPoint position) {
return createElement(position, new AttributesAgent(attributesPedestrian, -1)).getShape();
}
@Override
public void preLoop(final double simTimeInSec) {
this.lastSimTimeInSec = simTimeInSec;
......
package org.vadere.simulator.models.gnm;
import org.jetbrains.annotations.NotNull;
import org.vadere.annotation.factories.models.ModelClass;
import org.vadere.simulator.models.Model;
import org.vadere.simulator.models.ode.IntegratorFactory;
......@@ -19,6 +20,7 @@ import org.vadere.state.scenario.Target;
import org.vadere.state.scenario.Topography;
import org.vadere.state.types.GradientProviderType;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
import org.vadere.util.parallel.ParallelWorkerUtil;
import org.vadere.util.potential.gradients.GradientProvider;
......@@ -160,11 +162,21 @@ public class GradientNavigationModel extends ODEModel<Pedestrian, AttributesAgen
throw new IllegalArgumentException("GNM cannot initialize " + type.getCanonicalName());
this.pedestrianIdCounter++;
AttributesAgent pedAttributes = new AttributesAgent(elementAttributes, id > 0 ? id : pedestrianIdCounter);
Pedestrian result = new Pedestrian(pedAttributes, random);
result.setPosition(position);
Pedestrian result = create(position, pedAttributes);
return result;
}
private Pedestrian create(@NotNull final VPoint point, @NotNull final AttributesAgent attributesAgent) {
Pedestrian pedestrian = new Pedestrian(attributesAgent, random);
pedestrian.setPosition(point);
return pedestrian;
}
@Override
public VShape getDynamicElementRequiredPlace(@NotNull VPoint position) {
return create(position, new AttributesAgent(elementAttributes, -1)).getShape();
}
@Override
public List<Model> getSubmodels() {
return models;
......
......@@ -36,6 +36,7 @@ import org.vadere.state.scenario.Topography;
import org.vadere.state.types.OptimizationType;
import org.vadere.state.types.UpdateType;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
import java.util.Comparator;
import java.util.LinkedList;
......@@ -250,13 +251,21 @@ public class OptimalStepsModel implements MainModel, PotentialFieldModel, Dynami
AttributesAgent pedAttributes = new AttributesAgent(
this.attributesPedestrian, id > 0 ? id : pedestrianIdCounter);
PedestrianOSM pedestrianOSM = createElement(position, pedAttributes);
return pedestrianOSM;
}
@Override
public VShape getDynamicElementRequiredPlace(@NotNull final VPoint position) {
return createElement(position, new AttributesAgent(attributesPedestrian, -1)).getShape();
}
private PedestrianOSM createElement(VPoint position, @NotNull final AttributesAgent attributesAgent) {
PedestrianOSM pedestrian = new PedestrianOSM(attributesOSM,
pedAttributes, topography, random, potentialFieldTarget,
attributesAgent, topography, random, potentialFieldTarget,
potentialFieldObstacle.copy(), potentialFieldPedestrian,
speedAdjusters, stepCircleOptimizer.clone());
pedestrian.setPosition(position);
return pedestrian;
}
......
......@@ -3,6 +3,7 @@
*/
package org.vadere.simulator.models.ovm;
import org.jetbrains.annotations.NotNull;
import org.vadere.annotation.factories.models.ModelClass;
import org.vadere.simulator.models.Model;
import org.vadere.simulator.models.ode.IntegratorFactory;
......@@ -16,6 +17,7 @@ import org.vadere.state.scenario.Car;
import org.vadere.state.scenario.DynamicElement;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
import org.vadere.util.parallel.ParallelWorkerUtil;
import java.util.Collection;
......@@ -81,7 +83,6 @@ public class OptimalVelocityModel extends ODEModel<Car, AttributesCar> {
models = Collections.singletonList(this);
}
@Override
/*
Creates a single car with given attributes
......@@ -101,6 +102,11 @@ public class OptimalVelocityModel extends ODEModel<Car, AttributesCar> {
return result;
}
@Override
public VShape getDynamicElementRequiredPlace(@NotNull VPoint position) {
return new Car(new AttributesCar(elementAttributes, -1), random).getShape();
}
@Override
public void preLoop(final double simTimeInSec) {
super.preLoop(simTimeInSec);
......
......@@ -6,6 +6,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Random;
import org.jetbrains.annotations.NotNull;
import org.vadere.annotation.factories.models.ModelClass;
import org.vadere.simulator.models.MainModel;
import org.vadere.simulator.models.Model;
......@@ -23,6 +24,7 @@ import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.Vector2D;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
@ModelClass(isMainModel = true)
public class ReynoldsSteeringModel implements MainModel {
......@@ -117,11 +119,21 @@ public class ReynoldsSteeringModel implements MainModel {
this.pedestrianIdCounter++;
AttributesAgent pedAttributes = new AttributesAgent(
attributesPedestrian, id > 0 ? id : pedestrianIdCounter);
Pedestrian result = new PedestrianReynolds(pedAttributes, random);
result.setPosition(position);
Pedestrian result = create(position, pedAttributes);
return result;
}
private Pedestrian create(@NotNull final VPoint position, @NotNull final AttributesAgent attributesAgent) {
Pedestrian pedestrian = new PedestrianReynolds(attributesPedestrian, random);
pedestrian.setPosition(position);
return pedestrian;
}
@Override
public VShape getDynamicElementRequiredPlace(@NotNull final VPoint position) {
return create(position, new AttributesAgent(attributesPedestrian, -1)).getShape();
}
@Override
public List<Model> getSubmodels() {
return submodels;
......
package org.vadere.simulator.models.sfm;
import org.jetbrains.annotations.NotNull;
import org.vadere.annotation.factories.models.ModelClass;
import org.vadere.simulator.models.Model;
import org.vadere.simulator.models.ode.IntegratorFactory;
......@@ -8,6 +9,7 @@ import org.vadere.simulator.models.potential.FloorGradientProviderFactory;
import org.vadere.simulator.models.potential.fields.IPotentialFieldTargetGrid;
import org.vadere.simulator.models.potential.fields.PotentialFieldAgent;
import org.vadere.simulator.models.potential.fields.PotentialFieldObstacle;
import org.vadere.simulator.models.reynolds.PedestrianReynolds;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.models.AttributesSFM;
import org.vadere.state.attributes.scenario.AttributesAgent;
......@@ -17,7 +19,9 @@ import org.vadere.state.scenario.Target;
import org.vadere.state.scenario.Topography;
import org.vadere.state.types.GradientProviderType;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
import org.vadere.util.potential.gradients.GradientProvider;
import org.w3c.dom.Attr;
import java.util.Collection;
import java.util.HashMap;
......@@ -153,11 +157,21 @@ public class SocialForceModel extends ODEModel<Pedestrian, AttributesAgent> {
this.pedestrianIdCounter++;
AttributesAgent pedAttributes = new AttributesAgent(elementAttributes, id > 0 ? id : pedestrianIdCounter);
Pedestrian result = new Pedestrian(pedAttributes, random);
result.setPosition(position);
Pedestrian result = create(position, pedAttributes);
return result;
}
private Pedestrian create(@NotNull final VPoint position, @NotNull final AttributesAgent pedAttributes) {
Pedestrian pedestrian = new Pedestrian(pedAttributes, random);
pedestrian.setPosition(position);
return pedestrian;
}
@Override
public VShape getDynamicElementRequiredPlace(@NotNull final VPoint position) {
return create(position, new AttributesAgent(elementAttributes, -1)).getShape();
}
@Override
public List<Model> getSubmodels() {
return models;
......
......@@ -5,6 +5,7 @@ import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Random;
import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.Test;
import org.vadere.simulator.control.factory.SingleSourceControllerFactory;
......@@ -19,6 +20,7 @@ import org.vadere.state.scenario.Source;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape;
public class TestSourceControllerUsingConstantSpawnRate {
......@@ -64,6 +66,11 @@ public class TestSourceControllerUsingConstantSpawnRate {
ped.setPosition(position);
return ped;
}
@Override
public VShape getDynamicElementRequiredPlace(@NotNull VPoint position) {
return createElement(position, -1, Pedestrian.class).getShape();
}
};
d.sourceControllerFactory = getSourceControllerFactory(d);
......
......@@ -254,4 +254,15 @@ public class VCircle implements VShape, ICircleSector {
public ShapeType getType() {
return ShapeType.CIRCLE;
}
@Override
public boolean intersects(VShape shape) {
if(shape instanceof VCircle) {
VCircle otherCircle = (VCircle)shape;
return otherCircle.getCenter().distance(this.getCenter()) < (otherCircle.getRadius() + this.getRadius());
}
else {
return VShape.super.intersects(shape);
}
}
}
Supports Markdown
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