Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 3a6093c1 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck
Browse files

refactor groupSpawn to use a polygon as source shape

parent 75c7c2b3
...@@ -59,6 +59,8 @@ public class AgentRender implements Renderer { ...@@ -59,6 +59,8 @@ public class AgentRender implements Renderer {
} }
private void renderGroup(Pedestrian ped, Graphics2D g) { private void renderGroup(Pedestrian ped, Graphics2D g) {
g.setColor(Color.DARK_GRAY);
g.fill(ped.getShape());
g.setColor(getGroupColor(ped)); g.setColor(getGroupColor(ped));
DefaultRenderer.fill(getShape(ped), g); DefaultRenderer.fill(getShape(ped), g);
} }
......
...@@ -5,7 +5,8 @@ import org.vadere.simulator.models.groups.GroupModel; ...@@ -5,7 +5,8 @@ import org.vadere.simulator.models.groups.GroupModel;
import org.vadere.state.attributes.scenario.AttributesDynamicElement; import org.vadere.state.attributes.scenario.AttributesDynamicElement;
import org.vadere.state.scenario.Source; import org.vadere.state.scenario.Source;
import org.vadere.state.scenario.Topography; import org.vadere.state.scenario.Topography;
import org.vadere.state.util.SpawnArray; import org.vadere.state.util.GroupSpawnArray;
import org.vadere.util.geometry.PointPositioned;
import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle; import org.vadere.util.geometry.shapes.VRectangle;
...@@ -13,12 +14,13 @@ import java.util.Iterator; ...@@ -13,12 +14,13 @@ import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.stream.Collectors;
public class GroupSourceController extends SourceController { public class GroupSourceController extends SourceController {
private final GroupModel groupModel; private final GroupModel groupModel;
private LinkedList<Integer> groupsToSpawn; private LinkedList<Integer> groupsToSpawn;
protected final SpawnArray spawnArray; protected final GroupSpawnArray spawnArray;
public GroupSourceController(Topography scenario, Source source, public GroupSourceController(Topography scenario, Source source,
DynamicElementFactory dynamicElementFactory, DynamicElementFactory dynamicElementFactory,
...@@ -30,8 +32,9 @@ public class GroupSourceController extends SourceController { ...@@ -30,8 +32,9 @@ public class GroupSourceController extends SourceController {
VRectangle elementBound = new VRectangle(dynamicElementFactory.getDynamicElementRequiredPlace(new VPoint(0,0)).getBounds2D()); VRectangle elementBound = new VRectangle(dynamicElementFactory.getDynamicElementRequiredPlace(new VPoint(0,0)).getBounds2D());
this.spawnArray = new SpawnArray(new VRectangle(source.getShape().getBounds2D()), this.spawnArray = new GroupSpawnArray(source.getShape(),
new VRectangle(0, 0,elementBound.getWidth() , elementBound.getHeight() )); new VRectangle(0, 0,elementBound.getWidth() , elementBound.getHeight()),
dynamicElementFactory::getDynamicElementRequiredPlace);
} }
...@@ -47,7 +50,14 @@ public class GroupSourceController extends SourceController { ...@@ -47,7 +50,14 @@ public class GroupSourceController extends SourceController {
Iterator<Integer> iter = groupsToSpawn.iterator(); Iterator<Integer> iter = groupsToSpawn.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
int groupSize = iter.next(); int groupSize = iter.next();
List<VPoint> newGroup = spawnArray.getNextFreeGroup(groupSize, random, getDynElementsAtSource()); List<VPoint> newGroup = spawnArray.getNextFreeGroup(
groupSize,
random,
getDynElementsAtSource().stream()
.map(PointPositioned::getPosition)
.map(dynamicElementFactory::getDynamicElementRequiredPlace)
.collect(Collectors.toList())
);
if (newGroup.size() > 0) { if (newGroup.size() > 0) {
// add immediately to Scenario to update DynElementsAtSource // add immediately to Scenario to update DynElementsAtSource
addElementToScenario(newGroup); addElementToScenario(newGroup);
...@@ -60,7 +70,14 @@ public class GroupSourceController extends SourceController { ...@@ -60,7 +70,14 @@ public class GroupSourceController extends SourceController {
Iterator<Integer> iter = groupsToSpawn.iterator(); Iterator<Integer> iter = groupsToSpawn.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
int groupSize = iter.next(); int groupSize = iter.next();
List<VPoint> newGroup = spawnArray.getNextGroup(groupSize, random, getDynElementsAtSource()); List<VPoint> newGroup = spawnArray.getNextGroup(
groupSize,
random,
getDynElementsAtSource().stream()
.map(PointPositioned::getPosition)
.map(dynamicElementFactory::getDynamicElementRequiredPlace)
.collect(Collectors.toList())
);
if (newGroup.isEmpty()) if (newGroup.isEmpty())
throw new RuntimeException("Cannot spawn new Group. Source " + source.getId() + " is set " + throw new RuntimeException("Cannot spawn new Group. Source " + source.getId() + " is set " +
"to useFreeSpaceOnly == false but no space is left to spawn group without exactly" + "to useFreeSpaceOnly == false but no space is left to spawn group without exactly" +
...@@ -77,7 +94,13 @@ public class GroupSourceController extends SourceController { ...@@ -77,7 +94,13 @@ public class GroupSourceController extends SourceController {
Iterator<Integer> iter = groupsToSpawn.iterator(); Iterator<Integer> iter = groupsToSpawn.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
int groupSize = iter.next(); int groupSize = iter.next();
List<VPoint> newGroup = spawnArray.getNextFreeGroup(groupSize, getDynElementsAtSource()); List<VPoint> newGroup = spawnArray.getNextFreeGroup(
groupSize,
getDynElementsAtSource().stream()
.map(PointPositioned::getPosition)
.map(dynamicElementFactory::getDynamicElementRequiredPlace)
.collect(Collectors.toList())
);
if (newGroup != null && !newGroup.isEmpty()) { if (newGroup != null && !newGroup.isEmpty()) {
// add immediately to Scenario to update DynElementsAtSource // add immediately to Scenario to update DynElementsAtSource
addElementToScenario(newGroup); addElementToScenario(newGroup);
...@@ -90,7 +113,13 @@ public class GroupSourceController extends SourceController { ...@@ -90,7 +113,13 @@ public class GroupSourceController extends SourceController {
Iterator<Integer> iter = groupsToSpawn.iterator(); Iterator<Integer> iter = groupsToSpawn.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
int groupSize = iter.next(); int groupSize = iter.next();
List<VPoint> newGroup = spawnArray.getNextGroup(groupSize, getDynElementsAtSource()); List<VPoint> newGroup = spawnArray.getNextGroup(
groupSize,
getDynElementsAtSource().stream()
.map(PointPositioned::getPosition)
.map(dynamicElementFactory::getDynamicElementRequiredPlace)
.collect(Collectors.toList())
);
if (newGroup == null || newGroup.isEmpty()) if (newGroup == null || newGroup.isEmpty())
throw new RuntimeException("Cannot spawn new Group. Source " + source.getId() + " is set " + throw new RuntimeException("Cannot spawn new Group. Source " + source.getId() + " is set " +
"to useFreeSpaceOnly == false but no space is left to spawn group without exactly" + "to useFreeSpaceOnly == false but no space is left to spawn group without exactly" +
......
package org.vadere.simulator.control; package org.vadere.simulator.control;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.system.CallbackI;
import org.vadere.simulator.models.DynamicElementFactory; import org.vadere.simulator.models.DynamicElementFactory;
import org.vadere.state.attributes.scenario.AttributesDynamicElement; import org.vadere.state.attributes.scenario.AttributesDynamicElement;
import org.vadere.state.scenario.Obstacle; import org.vadere.state.scenario.Obstacle;
import org.vadere.state.scenario.Source; import org.vadere.state.scenario.Source;
import org.vadere.state.scenario.Topography; import org.vadere.state.scenario.Topography;
import org.vadere.state.util.SingleSourceSpawnArray; import org.vadere.state.util.SingleSourceSpawnArray;
import org.vadere.state.util.SpawnArray;
import org.vadere.util.geometry.PointPositioned; import org.vadere.util.geometry.PointPositioned;
import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle; import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape; import org.vadere.util.geometry.shapes.VShape;
import java.awt.*;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -22,7 +19,6 @@ import java.util.List; ...@@ -22,7 +19,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Random; import java.util.Random;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SingleSourceController extends SourceController { public class SingleSourceController extends SourceController {
...@@ -37,7 +33,6 @@ public class SingleSourceController extends SourceController { ...@@ -37,7 +33,6 @@ public class SingleSourceController extends SourceController {
AttributesDynamicElement attributesDynamicElement, AttributesDynamicElement attributesDynamicElement,
Random random) { Random random) {
super(scenario, source, dynamicElementFactory, attributesDynamicElement, random); super(scenario, source, dynamicElementFactory, attributesDynamicElement, random);
this.dynamicElementFactory = dynamicElementFactory;
VRectangle elementBound = new VRectangle(dynamicElementFactory.getDynamicElementRequiredPlace(new VPoint(0,0)).getBounds2D()); VRectangle elementBound = new VRectangle(dynamicElementFactory.getDynamicElementRequiredPlace(new VPoint(0,0)).getBounds2D());
this.spawnArray = new SingleSourceSpawnArray(source.getShape(), this.spawnArray = new SingleSourceSpawnArray(source.getShape(),
new VRectangle(0, 0,elementBound.getWidth(), elementBound.getHeight()), new VRectangle(0, 0,elementBound.getWidth(), elementBound.getHeight()),
...@@ -106,7 +101,7 @@ public class SingleSourceController extends SourceController { ...@@ -106,7 +101,7 @@ public class SingleSourceController extends SourceController {
List<VPoint> positions = new ArrayList<>(numberToSpawn); List<VPoint> positions = new ArrayList<>(numberToSpawn);
for(int i = 0; i < numberToSpawn; i++) { for(int i = 0; i < numberToSpawn; i++) {
Optional<VPoint> optPosition = getNextPosition(blockPedestrianShapes, spawnArray.getSpawnPoints()); Optional<VPoint> optPosition = getNextPosition(blockPedestrianShapes, spawnArray.getAllowedSpawnPoints());
if (optPosition.isPresent()) { if (optPosition.isPresent()) {
VPoint position = optPosition.get(); VPoint position = optPosition.get();
......
...@@ -2,7 +2,6 @@ package org.vadere.simulator.control; ...@@ -2,7 +2,6 @@ package org.vadere.simulator.control;
import org.apache.commons.math3.distribution.RealDistribution; import org.apache.commons.math3.distribution.RealDistribution;
import org.vadere.simulator.models.DynamicElementFactory; import org.vadere.simulator.models.DynamicElementFactory;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.attributes.scenario.AttributesDynamicElement; import org.vadere.state.attributes.scenario.AttributesDynamicElement;
import org.vadere.state.attributes.scenario.AttributesSource; import org.vadere.state.attributes.scenario.AttributesSource;
import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Agent;
...@@ -12,11 +11,8 @@ import org.vadere.state.scenario.DynamicElement; ...@@ -12,11 +11,8 @@ import org.vadere.state.scenario.DynamicElement;
import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Source; import org.vadere.state.scenario.Source;
import org.vadere.state.scenario.Topography; import org.vadere.state.scenario.Topography;
import org.vadere.state.util.SpawnArray;
import org.vadere.util.geometry.LinkedCellsGrid; import org.vadere.util.geometry.LinkedCellsGrid;
import org.vadere.util.geometry.shapes.VCircle;
import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -29,7 +25,7 @@ public abstract class SourceController { ...@@ -29,7 +25,7 @@ public abstract class SourceController {
// public static final double SPAWN_BUFFER_SIZE = 0.03; // public static final double SPAWN_BUFFER_SIZE = 0.03;
protected final Source source; protected final Source source;
private final DynamicElementFactory dynamicElementFactory; protected final DynamicElementFactory dynamicElementFactory;
private final Topography topography; private final Topography topography;
protected final Random random; protected final Random random;
......
package org.vadere.state.util;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.function.Function;
public abstract class AbstractSpawnArray {
private static Logger logger = LogManager.getLogger(AbstractSpawnArray.class);
protected final VRectangle spawnElementBound;
protected final VRectangle bound;
// number of spawn elements in x and y Dimension.
protected int xDim;
protected int yDim;
protected final ArrayList<VPoint> allowedSpawnPoints;
protected VPoint firstSpawnPoint;
protected double eX, eY;
// map valid boundGrid coordinates to #allowedSpawnPoints ArrayList index.
protected HashMap<Integer,Integer> validSpawnPointMapInBoundShape;
protected Function<VPoint, VShape> shapeProducer;
public AbstractSpawnArray(final VShape boundShape, final VRectangle spawnElementBound,
Function<VPoint, VShape> shapeProducer) {
this.spawnElementBound = spawnElementBound;
this.bound = new VRectangle(boundShape.getBounds2D());
this.shapeProducer = shapeProducer;
xDim = (int) (bound.width / spawnElementBound.width);
yDim = (int) (bound.height / spawnElementBound.height);
if (xDim * yDim <= 0) {
xDim = (xDim == 0) ? 1 : xDim;
yDim = (yDim == 0) ? 1 : yDim;
allowedSpawnPoints = new ArrayList<>(xDim * yDim);
//offset left upper corner to center point.
eX = (xDim == 1) ? bound.getCenterX() : spawnElementBound.x + spawnElementBound.width / 2;
eY = (yDim == 1) ? bound.getCenterY() : spawnElementBound.y + spawnElementBound.height / 2;
logger.info(String.format(
"Dimension of Source is to small for at least one dimension to contain designated spawnElement with Bound (%.2f x %.2f) Set to (%d x %d)",
spawnElementBound.width, spawnElementBound.height, xDim, yDim));
} else {
allowedSpawnPoints = new ArrayList<>(xDim * yDim);
//offset left upper corner to center point.
eX = spawnElementBound.x + spawnElementBound.width / 2;
eY = spawnElementBound.y + spawnElementBound.height / 2;
}
firstSpawnPoint = new VPoint(bound.x + eX, bound.y + eY);
validSpawnPointMapInBoundShape = new HashMap<>();
int validIndex = 0;
for (int i = 0; i < (xDim * yDim); i++) {
VPoint candidatePoint = firstSpawnPoint.add(new VPoint(2 * eX * (i % xDim), 2 * eY * (i / xDim)));
VShape candidateShape = shapeProducer.apply(candidatePoint);
if (boundShape.containsShape(candidateShape)) {
validSpawnPointMapInBoundShape.put(i, validIndex);
allowedSpawnPoints.add(candidatePoint);
validIndex++;
}
}
allowedSpawnPoints.trimToSize();
}
public List<VPoint> getAllowedSpawnPoints(){
return allowedSpawnPoints;
}
}
package org.vadere.state.util; package org.vadere.state.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/** /**
* Simplifies placement of a group within a {@link SpawnArray}. There are two placement strategies * Simplifies placement of a group within a There are two placement strategies
* supported. * supported.
* <li>NoneOverlapping:</li> * <li>NoneOverlapping:</li>
* With this strategy a group spawns do not overlap. E.g The first 2x2 Group will start at (0,0) and * With this strategy a group spawns do not overlap. E.g The first 2x2 Group will start at (0,0) and
...@@ -13,8 +17,8 @@ package org.vadere.state.util; ...@@ -13,8 +17,8 @@ package org.vadere.state.util;
*/ */
public class GroupPlacementHelper { public class GroupPlacementHelper {
private final int xBound; private final int boundedShapeGridCellsX;
private final int yBound; private final int boundedShapeGridCellsY;
private final int groupSize; private final int groupSize;
private final int groupDimX; private final int groupDimX;
...@@ -23,97 +27,96 @@ public class GroupPlacementHelper { ...@@ -23,97 +27,96 @@ public class GroupPlacementHelper {
private final int noneOverlapXGroupCount; private final int noneOverlapXGroupCount;
private final int noneOverlapYGroupCount; private final int noneOverlapYGroupCount;
private final int overlapXGroupCount; private final int groupPlacementCountX;
private final int overlapYGroupCount; private final int groupPlacementCountY;
private ArrayList<Integer> validSpawnPointsForGroupInBound;
public GroupPlacementHelper(int xBound, int yBound, int groupSize) { public GroupPlacementHelper(int boundedShapeGridCellsX, int boundedShapeGridCellsY,
if (groupSize > xBound * yBound) int groupSize, HashMap<Integer, Integer> validSpawnPointMapInBoundShape) {
if (groupSize > boundedShapeGridCellsX * boundedShapeGridCellsY)
throw new IndexOutOfBoundsException("GroupSize: " + groupSize throw new IndexOutOfBoundsException("GroupSize: " + groupSize
+ "to big for given Bound " + xBound + " x " + yBound); + "to big for given Bound " + boundedShapeGridCellsX + " x " + boundedShapeGridCellsY);
this.xBound = xBound; this.boundedShapeGridCellsX = boundedShapeGridCellsX;
this.yBound = yBound; this.boundedShapeGridCellsY = boundedShapeGridCellsY;
this.groupSize = groupSize; this.groupSize = groupSize;
int dimGx, dimGy; int dimGx, dimGy;
// dimension of smallest square contain a group of size groupSize
dimGx = (int) Math.ceil(Math.sqrt(groupSize)); dimGx = (int) Math.ceil(Math.sqrt(groupSize));
dimGx = (dimGx > xBound) ? xBound : dimGx; dimGx = (dimGx > boundedShapeGridCellsX) ? boundedShapeGridCellsX : dimGx;
// dimGy set to minimize lost space in resulting rectangle (or square if groupSize is a square number) // dimGy set to minimize lost space in resulting rectangle (or square if groupSize is a square number)
dimGy = dimGx * (dimGx - 1) < groupSize ? dimGx : dimGx - 1; dimGy = dimGx * (dimGx - 1) < groupSize ? dimGx : dimGx - 1;
this.groupDimX = dimGx; this.groupDimX = dimGx;
this.groupDimY = dimGy; this.groupDimY = dimGy;
this.noneOverlapXGroupCount = xBound / dimGx; this.noneOverlapXGroupCount = boundedShapeGridCellsX / dimGx;
this.noneOverlapYGroupCount = yBound / dimGy; this.noneOverlapYGroupCount = boundedShapeGridCellsY / dimGy;
this.overlapXGroupCount = xBound - (dimGx - 1); //
this.overlapYGroupCount = yBound - (dimGy - 1); this.groupPlacementCountX = boundedShapeGridCellsX - (dimGx - 1);
} this.groupPlacementCountY = boundedShapeGridCellsY - (dimGy - 1);
/** validSpawnPointsForGroupInBound = new ArrayList<>();
* @param groupNumber zero-Based number of group of groupSize with the noneOverlapping strategy for(int i = 0; i < getOverlappingGroupCount(); i++){ // i group spawn location
* @return zero-Based index within {@link SpawnArray} corresponding to start index of if (isGridCellWithinSource(validSpawnPointMapInBoundShape, i)){
* groupNumber. validSpawnPointsForGroupInBound.add(i);
*/ }
public int getNoneOverlappingStart(int groupNumber) { }
return (groupNumber % noneOverlapXGroupCount) * groupDimX + // offset in x
(groupNumber / noneOverlapXGroupCount) * xBound * groupDimY; // offset in y
} }
/** /**
* NoneOverlapping strategy
* *
* @param groupNumber zero-Based number of group * @param validSpawnPointMapInBoundShape mapping of rectangular bound grid to valid coordinates
* @param i zero-Based index within group. Must be smaller than groupSize * within the source shape
* @return zero-Based index within {@link SpawnArray} corresponding to groupNumber and index * @param groupIndex groupIndex specifying the first ped within one group.
* i * @return true if all positions within the group are contained
* within the source shape.
*/ */
public int getNoneOverlappingIndex(int groupNumber, int i) { boolean isGridCellWithinSource(HashMap<Integer, Integer> validSpawnPointMapInBoundShape, int groupIndex){
assert i < groupSize; for (int pedIndexInGroup = 0; pedIndexInGroup < groupSize; pedIndexInGroup++){
int start = getNoneOverlappingStart(groupNumber); boolean isValid = validSpawnPointMapInBoundShape.containsKey(getOverlappingIndex(groupIndex, pedIndexInGroup));
return start + (i % groupDimX) + (i / groupDimX) * xBound; if (!isValid){
return false;
}
}
return true;
} }
public int nextNoneOverlappingGroupNumber(int oldGroupNumber) {
return (oldGroupNumber + 1) % (noneOverlapXGroupCount * noneOverlapYGroupCount);
}
/**
* @return Number of groups based on noneOverlapping strategy
*/
public int getNoneOverlappingGroupCount() {
return noneOverlapXGroupCount * noneOverlapYGroupCount;
}
/** /**
* @param groupNumber zero-Based number of group of groupSize with the overlapping strategy * @param groupNumber zero-Based number of group of groupSize with the overlapping strategy
* @return zero-Based index within {@link SpawnArray} corresponding to groupNumber and index i * @return zero-Based index within {@link GroupSpawnArray} corresponding to groupNumber and index i
*/ */
public int getOverlappingStart(int groupNumber) { public int getOverlappingStart(int groupNumber) {
return (groupNumber % overlapXGroupCount) + // offset in x return (groupNumber % groupPlacementCountX) + // offset in x
(groupNumber / overlapXGroupCount) * xBound; // offset in y (groupDimY not needed) (groupNumber / groupPlacementCountX) * boundedShapeGridCellsX; // offset in y (groupDimY not needed)
} }
/** /**
* Overlapping strategy * Overlapping strategy
* *
* @param groupNumber zero-Based number of group * @param groupNumberInBound zero-Based number of group
* @param i zero-Based index within group. Must be smaller than groupSize * @param i zero-Based index within group. Must be smaller than groupSize
* @return zero-Based index within {@link SpawnArray} corresponding to groupNumber and index * @return zero-Based index within {@link GroupSpawnArray} corresponding to groupNumber and index
* i * i
*/ */
public int getOverlappingIndex(int groupNumber, int i) { public int getOverlappingIndex(int groupNumberInBound, int i) {
assert i < groupSize; assert i < groupSize;
int start = getOverlappingStart(groupNumber); int start = getOverlappingStart(groupNumberInBound);
return start + (i % groupDimX) + (i / groupDimX) * xBound; return start + (i % groupDimX) + (i / groupDimX) * boundedShapeGridCellsX;
} }
public int getOverlappingGroupCount() { public int getOverlappingGroupCount() {
return overlapXGroupCount * overlapYGroupCount; return groupPlacementCountX * groupPlacementCountY;
}
public ArrayList<Integer> getValidSpawnPointsForGroupInBound(){
return validSpawnPointsForGroupInBound;
} }
public int getGroupSize() { public int getGroupSize() {
......
package org.vadere.state.util; package org.vadere.state.util;
import org.apache.log4j.LogManager; import com.oracle.jrockit.jfr.Producer;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.vadere.state.scenario.DynamicElement; import org.vadere.state.scenario.DynamicElement;
import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle; import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections