The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated 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 c5e9ad8e authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

add poly files to further test EikMesh, fix issue #257.

parent dd62dfb7
Pipeline #137533 passed with stages
in 118 minutes and 23 seconds
...@@ -47,7 +47,6 @@ public class ActionGeneratePNG extends AbstractAction implements IRendererChange ...@@ -47,7 +47,6 @@ public class ActionGeneratePNG extends AbstractAction implements IRendererChange
SimpleDateFormat formatter = new SimpleDateFormat(CONFIG.getString("SettingsDialog.dataFormat")); SimpleDateFormat formatter = new SimpleDateFormat(CONFIG.getString("SettingsDialog.dataFormat"));
String formattedDate = formatter.format(todaysDate); String formattedDate = formatter.format(todaysDate);
File outputFile = new File(Messages.getString("FileDialog.filenamePrefix") + formattedDate + ".png"); File outputFile = new File(Messages.getString("FileDialog.filenamePrefix") + formattedDate + ".png");
fileChooser.setSelectedFile(outputFile); fileChooser.setSelectedFile(outputFile);
...@@ -62,6 +61,7 @@ public class ActionGeneratePNG extends AbstractAction implements IRendererChange ...@@ -62,6 +61,7 @@ public class ActionGeneratePNG extends AbstractAction implements IRendererChange
try { try {
ImageIO.write(bi, "png", outputFile); ImageIO.write(bi, "png", outputFile);
VadereConfig.getConfig().setProperty("SettingsDialog.snapshotDirectory.path", outputFile.getParentFile().getAbsolutePath());
logger.info("generate new png: " + outputFile.getAbsolutePath()); logger.info("generate new png: " + outputFile.getAbsolutePath());
} catch (IOException e1) { } catch (IOException e1) {
logger.error(e1.getMessage()); logger.error(e1.getMessage());
......
package org.vadere.gui.components.control.simulation; package org.vadere.gui.components.control.simulation;
import org.apache.commons.configuration2.Configuration;
import org.vadere.gui.components.model.DefaultSimulationConfig; import org.vadere.gui.components.model.DefaultSimulationConfig;
import org.vadere.gui.components.model.SimulationModel; import org.vadere.gui.components.model.SimulationModel;
import org.vadere.gui.components.utils.Messages; import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.components.utils.Resources; import org.vadere.gui.components.utils.Resources;
import org.vadere.gui.components.view.SimulationRenderer; import org.vadere.gui.components.view.SimulationRenderer;
import org.vadere.gui.postvisualization.PostVisualisation; import org.vadere.gui.postvisualization.PostVisualisation;
import org.vadere.meshing.mesh.impl.PSLG;
import org.vadere.meshing.utils.io.poly.PSLGGenerator; import org.vadere.meshing.utils.io.poly.PSLGGenerator;
import org.vadere.state.scenario.Obstacle; import org.vadere.state.scenario.Obstacle;
import org.vadere.util.config.VadereConfig;
import org.vadere.util.geometry.shapes.VPolygon; import org.vadere.util.geometry.shapes.VPolygon;
import org.vadere.util.geometry.shapes.VRectangle; import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.logging.Logger; import org.vadere.util.logging.Logger;
...@@ -21,6 +24,7 @@ import java.io.OutputStreamWriter; ...@@ -21,6 +24,7 @@ import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
...@@ -30,7 +34,7 @@ import javax.swing.*; ...@@ -30,7 +34,7 @@ import javax.swing.*;
public class ActionGeneratePoly extends AbstractAction { public class ActionGeneratePoly extends AbstractAction {
private static Logger logger = Logger.getLogger(ActionGeneratePNG.class); private static Logger logger = Logger.getLogger(ActionGeneratePNG.class);
private static Resources resources = Resources.getInstance("global"); private static final Configuration CONFIG = VadereConfig.getConfig();
private final SimulationModel<? extends DefaultSimulationConfig> model; private final SimulationModel<? extends DefaultSimulationConfig> model;
public ActionGeneratePoly(final String name, Icon icon, final SimulationRenderer renderer, public ActionGeneratePoly(final String name, Icon icon, final SimulationRenderer renderer,
...@@ -41,10 +45,10 @@ public class ActionGeneratePoly extends AbstractAction { ...@@ -41,10 +45,10 @@ public class ActionGeneratePoly extends AbstractAction {
@Override @Override
public void actionPerformed(final ActionEvent e) { public void actionPerformed(final ActionEvent e) {
JFileChooser fileChooser = new JFileChooser(Preferences.userNodeForPackage(PostVisualisation.class).get("SettingsDialog.snapshotDirectory.path", ".")); JFileChooser fileChooser = new JFileChooser(CONFIG.getString("SettingsDialog.snapshotDirectory.path"));
Date todaysDate = new java.util.Date(); Date todaysDate = new java.util.Date();
SimpleDateFormat formatter = new SimpleDateFormat(resources.getProperty("SettingsDialog.dataFormat")); SimpleDateFormat formatter = new SimpleDateFormat(CONFIG.getString("SettingsDialog.dataFormat"));
String formattedDate = formatter.format(todaysDate); String formattedDate = formatter.format(todaysDate);
...@@ -67,17 +71,27 @@ public class ActionGeneratePoly extends AbstractAction { ...@@ -67,17 +71,27 @@ public class ActionGeneratePoly extends AbstractAction {
List<Obstacle> obstacles = new ArrayList<>(model.getTopography().getObstacles()); List<Obstacle> obstacles = new ArrayList<>(model.getTopography().getObstacles());
obstacles.removeAll(model.getTopography().getBoundaryObstacles()); obstacles.removeAll(model.getTopography().getBoundaryObstacles());
List<VPolygon> obsShapes = obstacles.stream()
.map(obs -> obs.getShape())
.map(shape -> new VPolygon(shape))
.collect(Collectors.toList());
// this computes the union of intersecting obstacles.
obsShapes = PSLG.constructHoles(obsShapes);
// this will help to construct a valid non-rectangular bound.
List<VPolygon> polygons = PSLG.constructBound(new VPolygon(bound), obsShapes);
String polyString = PSLGGenerator.toPSLG( String polyString = PSLGGenerator.toPSLG(
new VPolygon(bound), polygons.get(0),
obstacles.stream() polygons.size() > 1 ? polygons.subList(1, polygons.size()) : Collections.emptyList());
.map(obs -> obs.getShape())
.map(shape -> new VPolygon(shape))
.collect(Collectors.toList()));
try { try {
outputFile.createNewFile(); outputFile.createNewFile();
Writer out = new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8"); Writer out = new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8");
out.write(polyString); out.write(polyString);
out.flush(); out.flush();
VadereConfig.getConfig().setProperty("SettingsDialog.snapshotDirectory.path", outputFile.getParentFile().getAbsolutePath());
logger.info("generate new Poly.file: " + outputFile.getAbsolutePath()); logger.info("generate new Poly.file: " + outputFile.getAbsolutePath());
} catch (IOException e1) { } catch (IOException e1) {
logger.error(e1.getMessage()); logger.error(e1.getMessage());
......
...@@ -47,6 +47,7 @@ public class ActionGenerateSVG extends AbstractAction implements IRendererChange ...@@ -47,6 +47,7 @@ public class ActionGenerateSVG extends AbstractAction implements IRendererChange
outputFile = fileChooser.getSelectedFile().toString().endsWith(".svg") ? fileChooser.getSelectedFile() outputFile = fileChooser.getSelectedFile().toString().endsWith(".svg") ? fileChooser.getSelectedFile()
: new File(fileChooser.getSelectedFile().toString() + ".svg"); : new File(fileChooser.getSelectedFile().toString() + ".svg");
svgGenerator.generateSVG(outputFile); svgGenerator.generateSVG(outputFile);
VadereConfig.getConfig().setProperty("SettingsDialog.snapshotDirectory.path", outputFile.getParentFile().getAbsolutePath());
} }
} }
......
...@@ -51,6 +51,7 @@ public class ActionGenerateTikz extends AbstractAction implements IRendererChang ...@@ -51,6 +51,7 @@ public class ActionGenerateTikz extends AbstractAction implements IRendererChang
: new File(fileChooser.getSelectedFile().toString() + ".tex"); : new File(fileChooser.getSelectedFile().toString() + ".tex");
tikzGenerator.generateTikz(outputFile); tikzGenerator.generateTikz(outputFile);
VadereConfig.getConfig().setProperty("SettingsDialog.snapshotDirectory.path", outputFile.getParentFile().getAbsolutePath());
} }
} }
......
...@@ -31,6 +31,7 @@ public class MovRecorder implements IRecorder { ...@@ -31,6 +31,7 @@ public class MovRecorder implements IRecorder {
private Rectangle2D.Double imageSize; private Rectangle2D.Double imageSize;
private Rectangle2D.Double viewport; private Rectangle2D.Double viewport;
private boolean finished; private boolean finished;
private File outputFile;
public MovRecorder(final PostvisualizationRenderer renderer) { public MovRecorder(final PostvisualizationRenderer renderer) {
this.model = renderer.getModel(); this.model = renderer.getModel();
...@@ -76,6 +77,7 @@ public class MovRecorder implements IRecorder { ...@@ -76,6 +77,7 @@ public class MovRecorder implements IRecorder {
try { try {
this.finished = true; this.finished = true;
enc.finish(); enc.finish();
VadereConfig.getConfig().setProperty("SettingsDialog.snapshotDirectory.path", outputFile.getParentFile().getAbsolutePath());
} catch (IndexOutOfBoundsException error) { } catch (IndexOutOfBoundsException error) {
logger.debug("Nothing recorded! " + error.getMessage()); logger.debug("Nothing recorded! " + error.getMessage());
throw error; throw error;
...@@ -108,7 +110,7 @@ public class MovRecorder implements IRecorder { ...@@ -108,7 +110,7 @@ public class MovRecorder implements IRecorder {
SimpleDateFormat formatter = new SimpleDateFormat(CONFIG.getString("SettingsDialog.dataFormat")); SimpleDateFormat formatter = new SimpleDateFormat(CONFIG.getString("SettingsDialog.dataFormat"));
String formattedDate = formatter.format(todaysDate); String formattedDate = formatter.format(todaysDate);
JFileChooser fileChooser = new JFileChooser(VadereConfig.getConfig().getString("SettingsDialog.snapshotDirectory.path", ".")); JFileChooser fileChooser = new JFileChooser(VadereConfig.getConfig().getString("SettingsDialog.snapshotDirectory.path", "."));
File outputFile = new File(Messages.getString("FileDialog.filenamePrefix") + formattedDate + ".mov"); outputFile = new File(Messages.getString("FileDialog.filenamePrefix") + formattedDate + ".mov");
fileChooser.setSelectedFile(outputFile); fileChooser.setSelectedFile(outputFile);
int returnVal = fileChooser.showDialog(null, "Save"); int returnVal = fileChooser.showDialog(null, "Save");
......
...@@ -120,7 +120,7 @@ class DataProcessingView extends JPanel implements IJsonView { ...@@ -120,7 +120,7 @@ class DataProcessingView extends JPanel implements IJsonView {
private JMenu processorsMenu = new JMenu(); private JMenu processorsMenu = new JMenu();
private TextView buildExpertView() { private TextView buildExpertView() {
TextView panel = new TextView("/" + IOUtils.OUTPUT_DIR, "default_directory_outputprocessors", AttributeType.OUTPUTPROCESSOR); TextView panel = new TextView("ProjectView.defaultDirectoryOutputProcessors", AttributeType.OUTPUTPROCESSOR);
JMenuBar processorsMenuBar = new JMenuBar(); JMenuBar processorsMenuBar = new JMenuBar();
processorsMenu = new JMenu(Messages.getString("Tab.Model.loadTemplateMenu.title")); processorsMenu = new JMenu(Messages.getString("Tab.Model.loadTemplateMenu.title"));
processorsMenu.setEnabled(isEditable); processorsMenu.setEnabled(isEditable);
......
...@@ -106,13 +106,13 @@ public class ScenarioPanel extends JPanel implements IProjectChangeListener, Pro ...@@ -106,13 +106,13 @@ public class ScenarioPanel extends JPanel implements IProjectChangeListener, Pro
//Tab //Tab
attributesSimulationView = attributesSimulationView =
new TextView("/attributes", "ProjectView.defaultDirectoryAttributes", AttributeType.SIMULATION); new TextView("ProjectView.defaultDirectoryAttributes", AttributeType.SIMULATION);
attributesSimulationView.setScenarioChecker(model); attributesSimulationView.setScenarioChecker(model);
tabbedPane.addTab(Messages.getString("Tab.Simulation.title"), attributesSimulationView); tabbedPane.addTab(Messages.getString("Tab.Simulation.title"), attributesSimulationView);
//Tab //Tab
attributesModelView = new TextView("/attributes", "ProjectView.defaultDirectoryAttributes", AttributeType.MODEL); attributesModelView = new TextView("ProjectView.defaultDirectoryAttributes", AttributeType.MODEL);
attributesModelView.setScenarioChecker(model); attributesModelView.setScenarioChecker(model);
JMenuBar presetMenuBar = new JMenuBar(); JMenuBar presetMenuBar = new JMenuBar();
...@@ -192,11 +192,11 @@ public class ScenarioPanel extends JPanel implements IProjectChangeListener, Pro ...@@ -192,11 +192,11 @@ public class ScenarioPanel extends JPanel implements IProjectChangeListener, Pro
attributesModelView.getPanelTop().add(presetMenuBar, 0); // the 0 puts it at the leftmost position instead of the rightmost attributesModelView.getPanelTop().add(presetMenuBar, 0); // the 0 puts it at the leftmost position instead of the rightmost
tabbedPane.addTab(Messages.getString("Tab.Model.title"), attributesModelView); tabbedPane.addTab(Messages.getString("Tab.Model.title"), attributesModelView);
topographyFileView = new TextView("/scenarios", "ProjectView.defaultDirectoryScenarios", AttributeType.TOPOGRAPHY); topographyFileView = new TextView("ProjectView.defaultDirectoryScenarios", AttributeType.TOPOGRAPHY);
topographyFileView.setScenarioChecker(model); topographyFileView.setScenarioChecker(model);
tabbedPane.addTab(Messages.getString("Tab.Topography.title"), topographyFileView); tabbedPane.addTab(Messages.getString("Tab.Topography.title"), topographyFileView);
eventFileView = new TextView("/attributes", "ProjectView.defaultDirectoryAttributes", AttributeType.EVENT); eventFileView = new TextView( "ProjectView.defaultDirectoryAttributes", AttributeType.EVENT);
eventFileView.isEditable(true); eventFileView.isEditable(true);
tabbedPane.addTab(Messages.getString("Tab.Event.title"), eventFileView); tabbedPane.addTab(Messages.getString("Tab.Event.title"), eventFileView);
......
...@@ -2,9 +2,11 @@ package org.vadere.gui.projectview.view; ...@@ -2,9 +2,11 @@ package org.vadere.gui.projectview.view;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.configuration2.Configuration;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rsyntaxtextarea.Theme; import org.fife.ui.rsyntaxtextarea.Theme;
import org.jetbrains.annotations.NotNull;
import org.vadere.gui.components.utils.Messages; import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.components.utils.Resources; import org.vadere.gui.components.utils.Resources;
import org.vadere.gui.projectview.VadereApplication; import org.vadere.gui.projectview.VadereApplication;
...@@ -17,12 +19,14 @@ import org.vadere.state.events.json.EventInfoStore; ...@@ -17,12 +19,14 @@ import org.vadere.state.events.json.EventInfoStore;
import org.vadere.state.events.presettings.EventPresettings; import org.vadere.state.events.presettings.EventPresettings;
import org.vadere.state.scenario.Topography; import org.vadere.state.scenario.Topography;
import org.vadere.state.util.StateJsonConverter; import org.vadere.state.util.StateJsonConverter;
import org.vadere.util.config.VadereConfig;
import org.vadere.util.io.IOUtils; import org.vadere.util.io.IOUtils;
import org.vadere.util.logging.Logger; import org.vadere.util.logging.Logger;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
...@@ -41,11 +45,12 @@ import javax.swing.filechooser.FileNameExtensionFilter; ...@@ -41,11 +45,12 @@ import javax.swing.filechooser.FileNameExtensionFilter;
public class TextView extends JPanel implements IJsonView { public class TextView extends JPanel implements IJsonView {
private static Logger logger = Logger.getLogger(TextView.class); private static Logger logger = Logger.getLogger(TextView.class);
private static final Configuration CONFIG = VadereConfig.getConfig();
private AttributeType attributeType; private AttributeType attributeType;
private String default_folder;
private String default_resource; private String default_resource;
private JPanel panelTop = new JPanel(); private JPanel panelTop = new JPanel();
private static final long serialVersionUID = 3975758744810301970L; private static final long serialVersionUID = 3975758744810301970L;
...@@ -64,14 +69,15 @@ public class TextView extends JPanel implements IJsonView { ...@@ -64,14 +69,15 @@ public class TextView extends JPanel implements IJsonView {
private ActionListener saveToFileActionListener = new ActionListener() { private ActionListener saveToFileActionListener = new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String path = IOUtils.chooseJSONFileSave(Messages.getString("TextFileView.btnSaveToFile.text"), String path = IOUtils.chooseJSONFileSave(Messages.getString("TextFileView.btnSaveToFile.text"), CONFIG.getString(default_resource));
Preferences.userNodeForPackage(VadereApplication.class).get(default_resource, default_folder));
if (path == null) if (path == null)
return; return;
try { try {
IOUtils.writeTextFile(path.endsWith(".json") ? path : path + ".json", txtrTextfiletextarea.getText()); IOUtils.writeTextFile(path.endsWith(".json") ? path : path + ".json", txtrTextfiletextarea.getText());
File file = new File(path);
VadereConfig.getConfig().setProperty(default_resource, file.getParentFile().getAbsolutePath());
} catch (IOException e1) { } catch (IOException e1) {
IOUtils.errorBox(e1.getLocalizedMessage(), Messages.getString("SaveFileErrorMessage.title")); IOUtils.errorBox(e1.getLocalizedMessage(), Messages.getString("SaveFileErrorMessage.title"));
logger.error(e1); logger.error(e1);
...@@ -83,15 +89,15 @@ public class TextView extends JPanel implements IJsonView { ...@@ -83,15 +89,15 @@ public class TextView extends JPanel implements IJsonView {
@Override @Override
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
FileFilter filter = new FileNameExtensionFilter("JSON file", "json"); FileFilter filter = new FileNameExtensionFilter("JSON file", "json");
String path = IOUtils.chooseFile("Choose file...", String path = IOUtils.chooseFile(Messages.getString("ChooseFile.text"), CONFIG.getString(default_resource), filter);
Preferences.userNodeForPackage(VadereApplication.class).get(default_resource, default_folder),
filter);
if (path == null) if (path == null)
return; return;
try { try {
String content = IOUtils.readTextFile(path); String content = IOUtils.readTextFile(path);
File file = new File(path);
VadereConfig.getConfig().setProperty(default_resource, file.getParentFile().getAbsolutePath());
txtrTextfiletextarea.setText(content); txtrTextfiletextarea.setText(content);
} catch (IOException e) { } catch (IOException e) {
logger.error("could not load from file: " + e.getMessage()); logger.error("could not load from file: " + e.getMessage());
...@@ -102,8 +108,7 @@ public class TextView extends JPanel implements IJsonView { ...@@ -102,8 +108,7 @@ public class TextView extends JPanel implements IJsonView {
/** /**
* Create the panel. * Create the panel.
*/ */
public TextView(String default_folder, String default_resource, final AttributeType attributeType) { public TextView(@NotNull final String default_resource, final AttributeType attributeType) {
this.default_folder = default_folder;
this.default_resource = default_resource; this.default_resource = default_resource;
this.attributeType = attributeType; this.attributeType = attributeType;
setLayout(new BorderLayout(0, 0)); setLayout(new BorderLayout(0, 0));
......
package org.vadere.gui.projectview.view; package org.vadere.gui.projectview.view;
import org.apache.commons.configuration2.Configuration;
import org.vadere.gui.components.utils.Messages; import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.projectview.VadereApplication; import org.vadere.gui.projectview.VadereApplication;
import org.vadere.util.config.VadereConfig;
import org.vadere.util.io.IOUtils; import org.vadere.util.io.IOUtils;
import org.vadere.util.logging.Logger; import org.vadere.util.logging.Logger;
...@@ -14,6 +16,7 @@ import java.util.prefs.Preferences; ...@@ -14,6 +16,7 @@ import java.util.prefs.Preferences;
public class VDialogManager { public class VDialogManager {
private static final Configuration CONFIG = VadereConfig.getConfig();
private static Logger logger = Logger.getLogger(VDialogManager.class); private static Logger logger = Logger.getLogger(VDialogManager.class);
private static final FileFilter PROJECT_FILTER = new FileNameExtensionFilter("Vadere Project", "project"); private static final FileFilter PROJECT_FILTER = new FileNameExtensionFilter("Vadere Project", "project");
...@@ -34,12 +37,11 @@ public class VDialogManager { ...@@ -34,12 +37,11 @@ public class VDialogManager {
} }
public static String loadProjectDialog() { public static String loadProjectDialog() {
return IOUtils.chooseFile(Messages.getString("LoadProjectText"), return IOUtils.chooseFile(Messages.getString("LoadProjectText"), getDefaultDirectory(), PROJECT_FILTER);
getDefaultDirectory(), PROJECT_FILTER);
} }
private static String getDefaultDirectory() { private static String getDefaultDirectory() {
return Preferences.userNodeForPackage(VadereApplication.class).get("ProjectView.defaultDirectory", "/projects"); return CONFIG.getString("ProjectView.defaultDirectory");
} }
public static int showConfirmDialogWithBodyAndTextArea(String title, String body, String textAreaContent, public static int showConfirmDialogWithBodyAndTextArea(String title, String body, String textAreaContent,
......
# nVertices dimension nAttributes boundaryMarker # nVertices dimension nAttributes boundaryMarker
21 2 0 0 19 2 0 0
# vertexId x y # vertexId x y
1 0.500000 0.500000 1 10.068317 15.240938
2 0.326351 11.349890 2 0.500000 12.473684
3 50.295924 42.506680 3 49.500000 49.500000
4 10.068317 15.240938 4 49.500000 0.500000
5 50.129121 5.936819 5 7.711478 10.030659
6 49.500000 49.500000 6 0.500000 45.907735
7 49.500000 0.500000 7 0.500000 42.907735
8 7.711478 10.030659 8 32.129121 5.936819
9 0.463889 45.907735 9 0.500000 49.500000
10 0.500000 49.500000 10 3.888684 20.251412
11 32.129121 5.936819 11 1.463889 42.907735
12 29.943119 0.478289 12 1.821300 11.082842
13 3.888684 20.251412 13 23.463889 45.907735
14 0.463889 42.907735 14 49.500000 5.936819
15 1.463889 42.907735 15 15.459378 12.808810
16 23.463889 45.907735 16 20.931872 10.544835
17 0.326351 -0.650110 17 29.892589 0.500000
18 15.459378 12.808810 18 49.500000 42.506680
19 20.931872 10.544835 19 31.295924 42.506680
20 29.943119 -1.521711
21 31.295924 42.506680
# #
# nSegments boundaryMarker # nSegments boundaryMarker
21 0 19 0
# lineId vertexId1 vertexId2 # lineId vertexId1 vertexId2
1 7 6 1 4 14
2 6 10 2 14 8
3 10 1 3 8 16
4 1 7 4 16 19
5 3 21 5 19 18
6 21 19 6 18 3
7 19 11 7 3 9
8 11 5 8 9 6
9 5 3 9 6 13
10 20 12 10 13 15
11 12 8 11 15 1
12 8 2 12 1 10
13 2 17 13 10 11
14 17 20 14 11 7
15 13 4 15 7 2
16 4 18 16 2 12
17 18 16 17 12 5
18 16 9 18 5 17
19 9 14 19 17 4
20 14 15
21 15 13
# #
# nHoles # nHoles
3 0
# vertexId x y (of a vertex which lies inside the hole) # vertexId x y (of a vertex which lies inside the hole)
1 37.999061 23.296979 \ No newline at end of file
2 11.703993 3.490417
3 11.505979 32.412715
\ No newline at end of file
...@@ -25,9 +25,22 @@ import java.util.stream.Collectors; ...@@ -25,9 +25,22 @@ import java.util.stream.Collectors;
/** /**
* The Weiler-Atherton-Algorithm (https://en.wikipedia.org/wiki/Weiler%E2%80%93Atherton_clipping_algorithm) * The Weiler-Atherton-Algorithm (https://en.wikipedia.org/wiki/Weiler%E2%80%93Atherton_clipping_algorithm)
* merges a set of polygons. Note this merging does not support holes that is if there is a hole it will be * enables boolean operations on polygons, i.e.:
* filled by the merging algorithm. Two polygons will be merged if they overlap. Co-linear and duplicated points, * <ul>
* i.e. useless points, will be removed. If polygon A contains polygon B, the result will be equals to polygon A. * <li>
* INTERSECTION of polygon A (subject) and B (clipper).
* </li>
* <li>
* UNION of polygon A (subject) and B (clipper).
* </li>
* <li>
* SUBTRACTION of polygon B (subject) from polygon A (clipper).
* </li>
* </ul>
* Note that holes are not supported, i.e. if UNION produces a polygon with holes this will be filled.