Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

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;