Commit 843993c6 authored by hm-schuhba1's avatar hm-schuhba1

Merge branch 'master' into 151_diff_origin

parents 6a64416d ecb24671
......@@ -242,7 +242,8 @@ OnlineVis.msgDialogShowPotentialfield.target=Target Potential Field
OnlineVis.msgDialogShowPotentialfield.overall=Potential Field (OSM only)
OnlineVis.msgDialogShowPotentialfield.none=None
TopographyBoundDialog.title = Set Topography Bounds
TopographyBoundDialog.title=Width x Height
TopographyBoundDialog.tooltip=Set topography bounds
InformationDialogError.title=Internal Error
InformationDialogFileError=Could not load file!
......@@ -267,6 +268,7 @@ SettingsDialog.lblPedestrianNoTarget.text=Without Target (-1)
ProjectView.menuOpenFloorFieldFile.title=Add Floor Field File...
ProjectView.btnDrawVoronoiDiagram.tooltip=Draw and display a Voronoi Diagram
ProjectView.btnDrawMesh.tooltip=Draw and display a mesh
SettingsDialog.chbLogo.text=Show the Vadere logo
ProjectView.btnShowWalkingDirection.tooltip=Show the walking direction of all pedestrians
ProjectView.btnShowGroupInformation.tooltip=Draw pedestrians within one group with same shape and color
......
......@@ -237,7 +237,8 @@ OnlineVis.msgDialogShowPotentialfield.target=Zielpotential
OnlineVis.msgDialogShowPotentialfield.overall=Potential (OSM only)
OnlineVis.msgDialogShowPotentialfield.none=Keines
TopographyBoundDialog.title = Setze Topographie Grenzen
TopographyBoundDialog.title=Breite x H\u00F6he
TopographyBoundDialog.tooltip=Setze Topographie-Gr\u00F6\u00DFe
InformationDialogError.title=Interner Fehelr
InformationDialogFileError=Datei konnte nicht geladen werden!
......@@ -273,6 +274,8 @@ ProjectView.btnShowDensity.tooltip=Dichte anzeigen
ProjectView.btnSettings.tooltip=Einstellungen
ProjectView.btnOk=OK
ProjectView.btnCancel=Abbrechen
ProjectView.btnDrawVoronoiDiagram.tooltip=Voronoi-Diagramm zeichnen und anzeigen
ProjectView.btnDrawMesh.tooltip=Mesh zeichnen und anzeigen
TopographyCreator.btnMergeObstacles.tooltip=Hindernisse zusammenf\u00fchren
TopographyCreator.btnMinimizeTopography.tooltip=Select Viewport area
......
......@@ -6,40 +6,17 @@ import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.gui.components.control.*;
import org.vadere.gui.components.view.ISelectScenarioElementListener;
import org.vadere.simulator.models.potential.fields.IPotentialField;
import org.vadere.simulator.models.potential.fields.PotentialFieldDistancesBruteForce;
import org.vadere.simulator.utils.TexGraphGenerator;
import org.vadere.state.attributes.models.AttributesFloorField;
import org.vadere.state.scenario.Obstacle;
import org.vadere.state.scenario.ScenarioElement;
import org.vadere.state.scenario.Topography;
import org.vadere.state.types.ScenarioElementType;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape;
import org.vadere.meshing.mesh.gen.PFace;
import org.vadere.meshing.mesh.gen.PHalfEdge;
import org.vadere.meshing.mesh.gen.PVertex;
import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import org.vadere.util.geometry.shapes.VTriangle;
import org.vadere.util.data.cellgrid.CellGrid;
import org.vadere.util.data.cellgrid.CellState;
import org.vadere.util.data.cellgrid.PathFindingTag;
import org.vadere.util.math.DistanceFunction;
import org.vadere.util.math.IDistanceFunction;
import org.vadere.meshing.mesh.triangulation.improver.eikmesh.EikMeshPoint;
import org.vadere.meshing.mesh.triangulation.improver.eikmesh.impl.PEikMesh;
import org.vadere.util.voronoi.VoronoiDiagram;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.*;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
......@@ -63,8 +40,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
private boolean showVoroniDiagram;
private boolean showTriangulation;
private VPoint cursorWorldPosition;
private VPoint startSelectionPoint;
......@@ -87,12 +62,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
public T config;
private IIncrementalTriangulation<EikMeshPoint, PVertex<EikMeshPoint>, PHalfEdge<EikMeshPoint>, PFace<EikMeshPoint>> triangulation;
private Collection<VTriangle> triangles;
protected boolean triangulationTriggered = false;
public DefaultModel(final T config) {
this.config = config;
this.scaleFactor = 50;
......@@ -101,13 +70,11 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
this.cursorWorldPosition = VPoint.ZERO;
this.selectScenarioElementListener = new LinkedList<>();
this.voronoiDiagram = null;
this.showTriangulation = false;
this.showVoroniDiagram = true;
this.showSelection = false;
this.mouseSelectionMode = new DefaultSelectionMode(this);
this.viewportChangeListeners = new ArrayList<>();
this.scaleChangeListeners = new ArrayList<>();
this.triangulation = null;
}
@Override
......@@ -192,10 +159,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
}
}
public boolean isTriangulationVisible() {
return showTriangulation;
}
@Override
public void notifyScaleListeners() {
for (IScaleChangeListener listener : scaleChangeListeners) {
......@@ -385,18 +348,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
setChanged();
}
@Override
public void showTriangulation() {
showTriangulation = true;
setChanged();
}
@Override
public void hideTriangulation() {
showTriangulation = false;
setChanged();
}
@Override
public void showSelection() {
showSelection = true;
......@@ -543,95 +494,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
return config;
}
/*
* returns the adaptive triangulation (see persson-2004 'A Simple Mesh Generator in MATLAB.')
*/
public void startTriangulation() {
if(!triangulationTriggered) {
triangulationTriggered = true;
VRectangle bound = new VRectangle(getTopographyBound());
Collection<Obstacle> obstacles = Topography.createObstacleBoundary(getTopography());
obstacles.addAll(getTopography().getObstacles());
List<VShape> shapes = obstacles.stream().map(obstacle -> obstacle.getShape()).collect(Collectors.toList());
IPotentialField distanceField = new PotentialFieldDistancesBruteForce(
getTopography().getObstacles().stream().map(obs -> obs.getShape()).collect(Collectors.toList()),
new VRectangle(getTopography().getBounds()),
new AttributesFloorField());
Function<IPoint, Double> obstacleDistance = p -> distanceField.getPotential(p, null);
IDistanceFunction distanceFunc = new DistanceFunction(bound, shapes);
CellGrid cellGrid = new CellGrid(bound.getWidth(), bound.getHeight(), 0.1, new CellState(), bound.getMinX(), bound.getMinY());
cellGrid.pointStream().forEach(p -> cellGrid.setValue(p, new CellState(distanceFunc.apply(cellGrid.pointToCoord(p)), PathFindingTag.Reachable)));
Function<IPoint, Double> interpolationFunction = cellGrid.getInterpolationFunction();
IDistanceFunction approxDistance = p -> interpolationFunction.apply(p);
/*PPSMeshing meshImprover = new PPSMeshing(
distanceFunc,
p -> Math.min(1.0 + Math.pow(Math.max(-distanceFunc.apply(p), 0)*0.8, 2), 6.0),
0.3,
bound, getTopography().getObstacles().stream().map(obs -> obs.getShape()).collect(Collectors.toList()));*/
PEikMesh meshImprover = new PEikMesh(
distanceFunc,
p -> Math.min(1.0 + Math.max(approxDistance.apply(p)*approxDistance.apply(p), 0)*0.3, 5.0),
0.35,
bound, getTopography().getObstacles().stream().map(obs -> obs.getShape()).collect(Collectors.toList()));
/*PPSMeshing meshImprover = new PPSMeshing(
distanceFunc,
p -> 1.0,
1.0,
bound, getTopography().getObstacles().stream().map(obs -> obs.getShape()).collect(Collectors.toList()));*/
triangulation = meshImprover.getTriangulation();
Thread t = new Thread(() -> {
while(!meshImprover.isFinished()) {
meshImprover.improve();
/*try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
setChanged();
notifyObservers();
}
//meshImprover.improve();
Function<PFace<EikMeshPoint>, Color> colorFunction = f -> {
float grayScale = (float) meshImprover.faceToQuality(f);
return triangulation.isValid(f) ? new Color(grayScale, grayScale, grayScale) : Color.RED;
};
log.info(TexGraphGenerator.toTikz(meshImprover.getMesh(), colorFunction, 1.0f));
log.info("number of points = " + meshImprover.getMesh().getVertices().size());
log.info("number of triangle = " + meshImprover.getMesh().getFaces().size());
log.info("avg-quality = " + meshImprover.getQuality());
log.info("min-quality = " + meshImprover.getMinQuality());
});
t.start();
}
}
public Collection<VTriangle> getTriangles() {
if(triangulation == null) {
return Collections.EMPTY_LIST;
}
synchronized (triangulation.getMesh()) {
return triangulation.streamTriangles().collect(Collectors.toList());
}
}
public Collection<VPolygon> getHoles() {
if(triangulation == null) {
return Collections.EMPTY_LIST;
}
synchronized (triangulation.getMesh()) {
return triangulation.getMesh().streamHoles().map(f -> triangulation.getMesh().toPolygon(f)).collect(Collectors.toList());
}
}
/*public void startTriangulation() {
if(!triangulationTriggered) {
triangulationTriggered = true;
......
......@@ -26,6 +26,7 @@ public class DefaultSimulationConfig extends DefaultConfig {
private boolean showPedestrians = true;
private boolean showWalkdirection = false;
private boolean showTargetPotentialField = false;
private boolean showTargetPotentielFieldMesh = false;
private boolean showPotentialField = false;
private boolean showTrajectories = false;
private boolean showGrid = false;
......@@ -64,6 +65,7 @@ public class DefaultSimulationConfig extends DefaultConfig {
this.showStairs = config.showStairs;
this.showGroups = config.showGroups;
this.showPotentialField = config.showPotentialField;
this.showTargetPotentielFieldMesh = config.showTargetPotentielFieldMesh;
}
public boolean isShowGroups() {
......@@ -110,6 +112,15 @@ public class DefaultSimulationConfig extends DefaultConfig {
return showTargets;
}
public void setShowTargetPotentielFieldMesh(final boolean showTargetPotentielFieldMesh) {
this.showTargetPotentielFieldMesh = showTargetPotentielFieldMesh;
setChanged();
}
public boolean isShowTargetPotentielFieldMesh() {
return showTargetPotentielFieldMesh;
}
public void setShowTargets(boolean showTargets) {
this.showTargets = showTargets;
setChanged();
......
......@@ -297,9 +297,5 @@ public interface IDefaultModel<T extends DefaultConfig> extends Iterable<Scenari
*/
void notifyObservers(final Object args);
void hideTriangulation();
void showTriangulation();
T getConfig();
}
......@@ -4,7 +4,11 @@ package org.vadere.gui.components.model;
import java.util.Collection;
import java.util.function.Function;
import org.vadere.meshing.mesh.gen.PMesh;
import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.simulator.models.potential.solver.calculators.mesh.PotentialPoint;
import org.vadere.state.scenario.Agent;
import org.vadere.util.data.cellgrid.IPotentialPoint;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
......@@ -38,8 +42,8 @@ public abstract class SimulationModel<T extends DefaultSimulationConfig> extends
return config;
}
public double getPotential(final int x, final int y) {
return getPotentialField().apply(pixelToWorld(new VPoint(x, y)));
public IMesh<? extends IPotentialPoint, ?, ?, ?> getDiscretization() {
return new PMesh<IPotentialPoint>((x,y) -> new PotentialPoint(x,y));
}
/*public double getPotential(final int x, final int y) {
......
......@@ -2,9 +2,12 @@ package org.vadere.gui.components.view;
import org.jetbrains.annotations.NotNull;
import org.vadere.gui.components.model.IDefaultModel;
import org.vadere.meshing.mesh.gen.MeshRenderer;
import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.ScenarioElement;
import org.vadere.state.scenario.Stairs;
import org.vadere.util.data.cellgrid.IPotentialPoint;
import org.vadere.util.geometry.shapes.Vector2D;
import org.vadere.util.geometry.shapes.VCircle;
import org.vadere.util.geometry.shapes.VLine;
......@@ -63,7 +66,6 @@ public abstract class DefaultRenderer {
targetGraphics2D.dispose();
}
public void renderGraphics(final Graphics2D targetGraphics2D, final int width, final int height) {
targetGraphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
......@@ -594,6 +596,14 @@ public abstract class DefaultRenderer {
}
}
protected void renderMesh(
@NotNull final Graphics2D g,
@NotNull final IMesh<? extends IPotentialPoint, ?, ?, ?> mesh,
@NotNull final VRectangle bound) {
MeshRenderer<? extends IPotentialPoint, ?, ?, ?> meshRenderer = new MeshRenderer<>(mesh);
meshRenderer.renderGraphics(g, bound);
}
protected void renderVoronoiDiagram(final Graphics2D g, final VoronoiDiagram voronoiDiagram) {
synchronized (voronoiDiagram) {
if (voronoiDiagram != null) {
......
......@@ -99,6 +99,10 @@ public abstract class SimulationRenderer extends DefaultRenderer {
renderVoronoiDiagram(graphics, model.getVoronoiDiagram());
}
if(model.config.isShowTargetPotentielFieldMesh()) {
renderMesh(graphics, model.getDiscretization(), new VRectangle(model.getTopographyBound()));
}
renderSimulationContent(graphics);
if (model.isElementSelected()) {
......@@ -177,7 +181,7 @@ public abstract class SimulationRenderer extends DefaultRenderer {
private void renderPotentialFieldOnViewport(final Graphics2D g, final int xPos, final int yPos, final int width, final int height) {
logger.info("resolution = " + width + ", " + height);
//logger.info("resolution = " + width + ", " + height);
/*
* This calculation we need since the viewport.y = 0 if the user scrolls to the bottom
*/
......
......@@ -7,13 +7,17 @@ import org.jetbrains.annotations.Nullable;
import org.vadere.gui.onlinevisualization.model.OnlineVisualizationModel;
import org.vadere.gui.onlinevisualization.view.MainPanel;
import org.vadere.gui.onlinevisualization.view.OnlineVisualisationWindow;
import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.simulator.control.PassiveCallback;
import org.vadere.simulator.models.potential.fields.IPotentialField;
import org.vadere.simulator.models.potential.fields.IPotentialFieldTarget;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Topography;
import org.vadere.util.data.cellgrid.IPotentialPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import java.util.function.Function;
public class OnlineVisualization implements PassiveCallback {
/**
......@@ -28,18 +32,21 @@ public class OnlineVisualization implements PassiveCallback {
public final IPotentialField potentialFieldTarget;
public final Agent selectedAgent;
public final IPotentialField potentialField;
public final Function<Agent, IMesh<? extends IPotentialPoint, ?, ?, ?>> discretizations;
public ObservationAreaSnapshotData(
final double simTimeInSec,
@NotNull final Topography scenario,
@Nullable final IPotentialField potentialFieldTarget,
@Nullable final IPotentialField potentialField,
@Nullable final Agent selectedAgent) {
@Nullable final Agent selectedAgent,
@Nullable final Function<Agent, IMesh<? extends IPotentialPoint, ?, ?, ?>> discretizations) {
this.simTimeInSec = simTimeInSec;
this.scenario = scenario;
this.potentialFieldTarget = potentialFieldTarget;
this.potentialField = potentialField;
this.selectedAgent = selectedAgent;
this.discretizations = discretizations;
}
}
......@@ -117,15 +124,19 @@ public class OnlineVisualization implements PassiveCallback {
synchronized (model.getDataSynchronizer()) {
/* Push new snapshot of the observation area to the draw thread. */
IPotentialField pft = (model.config.isShowTargetPotentialField() && potentialFieldTarget != null) ? potentialFieldTarget.getSolution() : null;
Function<Agent, IMesh<? extends IPotentialPoint, ?, ?, ?>> discretizations = (model.config.isShowTargetPotentielFieldMesh() && potentialFieldTarget != null) ? potentialFieldTarget.getDiscretization() : null;
IPotentialField pedPotentialField = null;
Agent selectedAgent = null;
if(model.config.isShowPotentialField() && model.getSelectedElement() instanceof Agent && potentialField != null) {
if(model.getSelectedElement() instanceof Agent){
selectedAgent = (Agent)model.getSelectedElement();
}
if(model.config.isShowPotentialField() && selectedAgent != null && potentialField != null) {
pedPotentialField = IPotentialField.copyAgentField(potentialField, selectedAgent, new VRectangle(model.getTopographyBound()), 0.1);
}
ObservationAreaSnapshotData data = new ObservationAreaSnapshotData(simTimeInSec, scenario.clone(), pft, pedPotentialField, selectedAgent);
ObservationAreaSnapshotData data = new ObservationAreaSnapshotData(simTimeInSec, scenario.clone(), pft, pedPotentialField, selectedAgent, discretizations);
model.pushObservationAreaSnapshot(data);
}
}
......
package org.vadere.gui.onlinevisualization.control;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.gui.components.control.simulation.ActionVisualization;
import org.vadere.gui.components.model.DefaultSimulationConfig;
import org.vadere.gui.components.model.SimulationModel;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ActionShowMesh extends ActionVisualization {
private static Logger logger = LogManager.getLogger(ActionShowMesh.class);
public ActionShowMesh(final String name, Icon icon, final SimulationModel<? extends DefaultSimulationConfig> model) {
super(name, icon, model);
}
@Override
public void actionPerformed(final ActionEvent e) {
model.config.setShowTargetPotentielFieldMesh(!model.config.isShowTargetPotentielFieldMesh());
model.notifyObservers();
super.actionPerformed(e);
}
}
......@@ -11,8 +11,12 @@ import java.util.stream.Collectors;
import org.vadere.gui.components.model.DefaultSimulationConfig;
import org.vadere.gui.components.model.SimulationModel;
import org.vadere.gui.onlinevisualization.OnlineVisualization;
import org.vadere.meshing.mesh.gen.PMesh;
import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.simulator.models.potential.fields.IPotentialField;
import org.vadere.simulator.models.potential.solver.calculators.mesh.PotentialPoint;
import org.vadere.state.scenario.*;
import org.vadere.util.data.cellgrid.IPotentialPoint;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.voronoi.VoronoiDiagram;
......@@ -33,6 +37,8 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC
private IPotentialField potentialField = null;
private Function<Agent, IMesh<? extends IPotentialPoint, ?, ?, ?>> discretizations = null;
private Agent agent = null;
/**
......@@ -112,6 +118,7 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC
potentialFieldTarget = observationAreaSnapshot.potentialFieldTarget;
potentialField = observationAreaSnapshot.potentialField;
agent = observationAreaSnapshot.selectedAgent;
discretizations = observationAreaSnapshot.discretizations;
/*
* if(topography == null ||
......@@ -188,7 +195,7 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC
public Function<IPoint, Double> getPotentialField() {
Function<IPoint, Double> f = pos -> 0.0;
if(potentialField != null && config.isShowPotentialField() && agent.equals(getSelectedElement())) {
if(agent != null && potentialField != null && config.isShowPotentialField() && agent.equals(getSelectedElement())) {
f = pos -> potentialField.getPotential(pos, agent);
}
else if(potentialFieldTarget != null && config.isShowTargetPotentialField()) {
......@@ -201,6 +208,15 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC
return f;
}
@Override
public IMesh<? extends IPotentialPoint, ?, ?, ?> getDiscretization() {
if(agent != null && discretizations != null && config.isShowTargetPotentielFieldMesh() && agent.equals(getSelectedElement())) {
return discretizations.apply(agent);
}
return new PMesh<IPotentialPoint>((x, y) -> new PotentialPoint(x, y));
}
@Override
public double getGridResolution() {
return config.getGridWidth();
......
......@@ -17,6 +17,7 @@ import org.vadere.gui.components.control.simulation.ActionGeneratePNG;
import org.vadere.gui.components.control.simulation.ActionGenerateSVG;
import org.vadere.gui.components.control.simulation.ActionGenerateTikz;
import org.vadere.gui.onlinevisualization.control.ActionOnlineVisMenu;
import org.vadere.gui.onlinevisualization.control.ActionShowMesh;
import org.vadere.gui.onlinevisualization.control.ActionShowPotentialField;
import org.vadere.gui.onlinevisualization.model.OnlineVisualizationModel;
import org.vadere.gui.components.control.simulation.ActionSwapSelectionMode;
......@@ -126,6 +127,9 @@ public class OnlineVisualisationWindow extends JPanel implements Observer {
AbstractAction drawVoronoiDiagram = new ActionSwapSelectionMode("draw_voronoi_diagram", resources.getIcon("voronoi.png", iconWidth, iconHeight), model);
AbstractAction drawMesh = new ActionShowMesh("draw_mesh", resources.getIcon("triangulation.png", iconWidth, iconHeight), model);
AbstractAction paintGridAction = new AbstractAction("paintGridAction",
resources.getIcon("grid.png", iconWidth, iconHeight)) {
......@@ -204,7 +208,8 @@ public class OnlineVisualisationWindow extends JPanel implements Observer {
Messages.getString("ProjectView.btnShowGroupInformation.tooltip"));
SwingUtils.addActionToToolbar(toolbar, drawVoronoiDiagram,
Messages.getString("ProjectView.btnDrawVoronoiDiagram.tooltip"));
SwingUtils.addActionToToolbar(toolbar, drawMesh,
Messages.getString("ProjectView.btnDrawMesh.tooltip"));
toolbar.addSeparator();
......
......@@ -145,10 +145,6 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
}
public void init(final Scenario vadere, final String projectPath) {
// avoid the long computation
this.hideTriangulation();
this.triangulationTriggered = false;
this.vadere = vadere;
this.agentsByStep = new HashMap<>();
this.steps = new ArrayList<>();
......
......@@ -81,7 +81,7 @@ public class TikzGenerator {
tikzCode += generateTikzColorDefinitions(model);
tikzCode += convertScenarioElementsToTikz();
String output = (generateCompleteDocument) ? String.format(texTemplate, tikzCode) : tikzCode;
String output = (generateCompleteDocument) ? String.format(Locale.US, texTemplate, tikzCode) : tikzCode;
// TODO: maybe uses Java's resources notation (in general, writing the file should be done by the caller not here).
try {
......@@ -102,19 +102,19 @@ public class TikzGenerator {
String colorTextPattern = "\\definecolor{%s}{RGB}{%d,%d,%d}\n";
Color sourceColor = model.getConfig().getSourceColor();
colorDefinitions += String.format(colorTextPattern, "SourceColor", sourceColor.getRed(), sourceColor.getGreen(), sourceColor.getBlue());
colorDefinitions += String.format(Locale.US, colorTextPattern, "SourceColor", sourceColor.getRed(), sourceColor.getGreen(), sourceColor.getBlue());
Color targetColor = model.getConfig().getTargetColor();
colorDefinitions += String.format(colorTextPattern, "TargetColor", targetColor.getRed(), targetColor.getGreen(), targetColor.getBlue());
colorDefinitions += String.format(Locale.US, colorTextPattern, "TargetColor", targetColor.getRed(), targetColor.getGreen(), targetColor.getBlue());
Color obstacleColor = model.getConfig().getObstacleColor();
colorDefinitions += String.format(colorTextPattern, "ObstacleColor", obstacleColor.getRed(), obstacleColor.getGreen(), obstacleColor.getBlue());
colorDefinitions += String.format(Locale.US, colorTextPattern, "ObstacleColor", obstacleColor.getRed(), obstacleColor.getGreen(), obstacleColor.getBlue());
Color stairColor = model.getConfig().getStairColor();
colorDefinitions += String.format(colorTextPattern, "StairColor", stairColor.getRed(), stairColor.getGreen(), stairColor.getBlue());
colorDefinitions += String.format(Locale.US, colorTextPattern, "StairColor", stairColor.getRed(), stairColor.getGreen(), stairColor.getBlue());
Color agentColor = model.getConfig().getPedestrianDefaultColor();
colorDefinitions += String.format(colorTextPattern, "AgentColor", agentColor.getRed(), agentColor.getGreen(), agentColor.getBlue());
colorDefinitions += String.format(Locale.US, colorTextPattern, "AgentColor", agentColor.getRed(), agentColor.getGreen(), agentColor.getBlue());
return colorDefinitions;
}
......@@ -128,7 +128,7 @@ public class TikzGenerator {
// Clip everything outside of topography bound.
generatedCode += "% Clipping\n";
String clipTextPattern = "\\clip (%f,%f) rectangle (%f,%f);\n";
generatedCode += String.format(clipTextPattern,
generatedCode += String.format(Locale.US, clipTextPattern,
topography.getBounds().x,
topography.getBounds().y,
topography.getBounds().x + topography.getBounds().width,
......@@ -137,7 +137,7 @@ public class TikzGenerator {
// Draw background elements first, then other scenario elements.
generatedCode += "% Ground\n";
String groundTextPattern = (config.isShowGrid()) ? "\\draw[help lines] (%f,%f) grid (%f,%f);\n" : "\\fill[white] (%f,%f) rectangle (%f,%f);\n";
generatedCode += String.format(groundTextPattern,
generatedCode += String.format(Locale.US, groundTextPattern,
topography.getBounds().x,
topography.getBounds().y,
topography.getBounds().x + topography.getBounds().width,
......@@ -146,7 +146,7 @@ public class TikzGenerator {
if (config.isShowSources()) {
generatedCode += "% Sources\n";
for (Source source : topography.getSources()) {
generatedCode += String.format("\\fill[SourceColor] %s;\n", generatePathForScenarioElement(source));
generatedCode += String.format(Locale.US, "\\fill[SourceColor] %s;\n", generatePathForScenarioElement(source));
}
} else {
generatedCode += "% Sources (not enabled in config)\n";
......@@ -155,7 +155,7 @@ public class TikzGenerator {
if (config.isShowTargets()) {
generatedCode += "% Targets\n";
for (Target target : topography.getTargets()) {
generatedCode += String.format("\\fill[TargetColor] %s;\n", generatePathForScenarioElement(target));
generatedCode += String.format(Locale.US, "\\fill[TargetColor] %s;\n", generatePathForScenarioElement(target));
}
} else {
generatedCode += "% Targets (not enabled in config)\n";
......@@ -164,7 +164,7 @@ public class TikzGenerator {
if (config.isShowObstacles()) {
generatedCode += "% Obstacles\n";
for (Obstacle obstacle : topography.getObstacles()) {
generatedCode += String.format("\\fill[ObstacleColor] %s;\n", generatePathForScenarioElement(obstacle));
generatedCode += String.format(Locale.US, "\\fill[ObstacleColor] %s;\n", generatePathForScenarioElement(obstacle));
}
} else {
generatedCode += "% Obstacles (not enabled in config)\n";
......@@ -173,8 +173,8 @@ public class TikzGenerator {
if (config.isShowStairs()) {
generatedCode += "% Stairs\n";
for (Stairs stair : topography.getStairs()) {
generatedCode += String.format("\\fill[black] %s;\n", generatePathForScenarioElement(stair));
generatedCode += String.format("\\fill[StairColor] %s;\n", generatePathForStairs(stair));
generatedCode += String.format(Locale.US, "\\fill[black] %s;\n", generatePathForScenarioElement(stair));
generatedCode += String.format(Locale.US, "\\fill[StairColor] %s;\n", generatePathForStairs(stair));
}
} else {
generatedCode += "% Stairs (not enabled in config)\n";
......@@ -186,7 +186,7 @@ public class TikzGenerator {
if (model instanceof PostvisualizationModel) {
generatedCode += drawTrajectories((PostvisualizationModel)model);
} else {
generatedCode += String.format("%% Passed model %s does not contain trajectories\n", model.getClass().getSimpleName());
generatedCode += String.format(Locale.US, "%% Passed model %s does not contain trajectories\n", model.getClass().getSimpleName());
}
} else {
generatedCode += "% Trajectories (not enabled in config)\n";
......@@ -215,7 +215,7 @@ public class TikzGenerator {
// Use a newline ("to\n") for joining because TeX could possibly choke up on long lines.
String trajectoryAsTikzString = trajectoryPoints
.map(point -> String.format("(%f,%f)", point.x, point.y))
.map(point -> String.format(Locale.US, "(%f,%f)", point.x, point.y))
.collect(Collectors.joining(" to\n"));
String coloredTrajectory = applyAgentColorToTrajectory(trajectoryAsTikzString, trajectory.getAgent(currentTimeStep));
......@@ -225,7 +225,7 @@ public class TikzGenerator {
String trajectoryEndStepAsString = (trajectoryEndStep.isPresent()) ? "" + trajectoryEndStep.get().toString() : "unknown end step" ;
String currentTimeStepAsString = currentTimeStep.toString();