2020-03-21 00:37:09 +00:00
|
|
|
package de.wwwu.awolf.presenter.util;
|
2017-09-18 21:16:18 +00:00
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import com.google.common.collect.Sets;
|
2020-03-21 00:37:09 +00:00
|
|
|
import de.wwwu.awolf.model.Line;
|
|
|
|
import de.wwwu.awolf.model.Point;
|
2020-03-23 06:58:40 +00:00
|
|
|
import org.jfree.util.Log;
|
2017-09-18 21:16:18 +00:00
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
import java.util.*;
|
|
|
|
import java.util.concurrent.ForkJoinPool;
|
|
|
|
import java.util.concurrent.ForkJoinTask;
|
|
|
|
import java.util.concurrent.RecursiveTask;
|
|
|
|
import java.util.stream.Collectors;
|
2017-09-18 21:16:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
|
|
|
*
|
|
|
|
* @Author: Armin Wolf
|
|
|
|
* @Email: a_wolf28@uni-muenster.de
|
|
|
|
* @Date: 18.09.2017.
|
|
|
|
*/
|
|
|
|
public class IntersectionComputer {
|
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
private static IntersectionComputer instance;
|
2017-09-18 21:16:18 +00:00
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
|
|
|
* Konstruktor
|
|
|
|
*/
|
2020-03-23 06:58:40 +00:00
|
|
|
private IntersectionComputer() {
|
2017-09-18 21:16:18 +00:00
|
|
|
}
|
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
private class RecursiveComputationTask extends RecursiveTask<Collection<Point>> {
|
2017-09-18 21:16:18 +00:00
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
private static final int THRESHOLD = 20;
|
2017-09-18 21:16:18 +00:00
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
private final List<Line> lines;
|
|
|
|
private final List<Line> fullList;
|
|
|
|
private final double lower;
|
|
|
|
private final double upper;
|
2017-09-18 21:16:18 +00:00
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
public RecursiveComputationTask(final List<Line> fullList, final List<Line> lines, final double lower, final double upper) {
|
|
|
|
this.lines = lines;
|
|
|
|
this.fullList = fullList;
|
|
|
|
this.lower = lower;
|
|
|
|
this.upper = upper;
|
2017-09-18 21:16:18 +00:00
|
|
|
}
|
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
@Override
|
|
|
|
protected Collection<Point> compute() {
|
|
|
|
if (this.lines.isEmpty()){
|
|
|
|
return Collections.emptyList();
|
|
|
|
} else if (this.lines.size() > THRESHOLD) {
|
2020-03-23 20:58:39 +00:00
|
|
|
Logging.logDebug("Bigger than threshold, split into subtask.");
|
2020-03-23 06:58:40 +00:00
|
|
|
return ForkJoinTask.invokeAll(createSubTask()).stream().map(ForkJoinTask::join).flatMap(Collection::stream).collect(Collectors.toList());
|
|
|
|
} else {
|
|
|
|
return work(this.lines, this.lines, this.lower, this.upper);
|
2017-09-18 21:16:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
private Collection<RecursiveComputationTask> createSubTask() {
|
|
|
|
List<RecursiveComputationTask> dividedTasks = new ArrayList<>();
|
|
|
|
dividedTasks.add(new RecursiveComputationTask(this.fullList, this.lines.subList(0, this.lines.size() / 2), this.lower, this.upper));
|
|
|
|
dividedTasks.add(new RecursiveComputationTask(this.fullList, this.lines.subList(this.lines.size() / 2, this.lines.size()), this.lower, this.upper));
|
|
|
|
return dividedTasks;
|
|
|
|
}
|
2017-09-18 21:16:18 +00:00
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
private Collection<Point> work(List<Line> fullList, List<Line> lines, double lower, double higher) {
|
|
|
|
Set<Point> points = new HashSet<>();
|
|
|
|
List<List<Line>> lists = Lists.cartesianProduct(new ArrayList<>(fullList), new ArrayList<>(lines));
|
|
|
|
lists.forEach(entry -> {
|
|
|
|
if (entry.get(0).doIntersect(entry.get(1), lower, upper)) {
|
|
|
|
Point intersect = entry.get(0).intersect(entry.get(1));
|
|
|
|
if (intersect.getX() > lower && intersect.getX() <= higher) {
|
|
|
|
points.add(intersect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return new HashSet<>(points);
|
|
|
|
}
|
2017-09-18 21:16:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
2020-03-23 06:58:40 +00:00
|
|
|
* Berechnet zu einer gegebenen Menge von dualen Geraden die Schnittpunkte. Dafür wird ein modifizierter Merge-Sort
|
|
|
|
* Algorithmus verwendett. Um die Performance zu steigern wird die Berechnung ab einer passenden Größe auf vier
|
|
|
|
* Threads ausgelagert.
|
2020-03-20 17:08:18 +00:00
|
|
|
*
|
2020-03-23 06:58:40 +00:00
|
|
|
* @param lower untere Schranke
|
|
|
|
* @param higher obere Schranke
|
|
|
|
* @return Liste der Schnittpunkte
|
2017-10-15 10:45:47 +00:00
|
|
|
*/
|
2020-03-23 06:58:40 +00:00
|
|
|
public Collection<Point> compute(final List<Line> lines, final double lower, final double higher) {
|
2020-03-23 20:58:39 +00:00
|
|
|
Logging.logInfo("Open ForkJoinPool: lines: " + lines.size() + " I(" + lower +", " +higher + "]");
|
2020-03-23 06:58:40 +00:00
|
|
|
ForkJoinPool pool = ForkJoinPool.commonPool();
|
|
|
|
RecursiveComputationTask recursiveComputationTask = new RecursiveComputationTask(lines, lines, lower, higher);
|
|
|
|
pool.execute(recursiveComputationTask);
|
|
|
|
return recursiveComputationTask.join();
|
2017-09-18 21:16:18 +00:00
|
|
|
}
|
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
public static IntersectionComputer getInstance() {
|
|
|
|
if (instance == null) {
|
|
|
|
instance = new IntersectionComputer();
|
|
|
|
Logging.logInfo("Created instance of IntersectionComputer");
|
|
|
|
}
|
2017-09-18 21:16:18 +00:00
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
return instance;
|
2017-09-18 21:16:18 +00:00
|
|
|
}
|
2020-03-23 06:58:40 +00:00
|
|
|
|
2017-09-18 21:16:18 +00:00
|
|
|
}
|