diff --git a/src/main/java/Model/Arrangement.java b/src/main/java/Model/Arrangement.java index 2741119..2e3ce7b 100644 --- a/src/main/java/Model/Arrangement.java +++ b/src/main/java/Model/Arrangement.java @@ -11,31 +11,31 @@ import java.util.LinkedList; */ public class Arrangement { - private LinkedList nodes; - private LinkedList lines; + private LinkedList nodes; + private LinkedList lines; public Arrangement() { nodes = new LinkedList<>(); lines = new LinkedList<>(); } - public void addNode(Coordinates node) { + public void addNode(Point node) { this.nodes.add(node); } - public void addLine(Coordinates line) { + public void addLine(Line line) { this.lines.add(line); } - public LinkedList getNodes() { + public LinkedList getNodes() { return nodes; } - public LinkedList getLines() { + public LinkedList getLines() { return lines; } - public void setLines(LinkedList lines) { + public void setLines(LinkedList lines) { this.lines = lines; } diff --git a/src/main/java/Model/DoublyConnectedEdgeList.java b/src/main/java/Model/DCEL/DoublyConnectedEdgeList.java similarity index 96% rename from src/main/java/Model/DoublyConnectedEdgeList.java rename to src/main/java/Model/DCEL/DoublyConnectedEdgeList.java index 6a034f7..33770d0 100644 --- a/src/main/java/Model/DoublyConnectedEdgeList.java +++ b/src/main/java/Model/DCEL/DoublyConnectedEdgeList.java @@ -1,6 +1,8 @@ -package Model; +package Model.DCEL; +import Model.Point; + import java.util.LinkedList; /** @@ -22,10 +24,10 @@ public class DoublyConnectedEdgeList { this.faces = new LinkedList<>(); } - public Node createNode(Coordinates point, String id) { + public Node createNode(Point point, String id) { Node node = new Node(); - node.setCoordinates(point); + node.setPoint(point); node.setID(id); return node; diff --git a/src/main/java/Model/Edge.java b/src/main/java/Model/DCEL/Edge.java similarity index 99% rename from src/main/java/Model/Edge.java rename to src/main/java/Model/DCEL/Edge.java index 2a8edd2..2bdff3e 100644 --- a/src/main/java/Model/Edge.java +++ b/src/main/java/Model/DCEL/Edge.java @@ -1,4 +1,4 @@ -package Model; +package Model.DCEL; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. diff --git a/src/main/java/Model/Face.java b/src/main/java/Model/DCEL/Face.java similarity index 99% rename from src/main/java/Model/Face.java rename to src/main/java/Model/DCEL/Face.java index 363bd6f..a7035b9 100644 --- a/src/main/java/Model/Face.java +++ b/src/main/java/Model/DCEL/Face.java @@ -1,4 +1,4 @@ -package Model; +package Model.DCEL; import java.util.LinkedList; diff --git a/src/main/java/Model/Node.java b/src/main/java/Model/DCEL/Node.java similarity index 67% rename from src/main/java/Model/Node.java rename to src/main/java/Model/DCEL/Node.java index a4fbaf7..b2c0efb 100644 --- a/src/main/java/Model/Node.java +++ b/src/main/java/Model/DCEL/Node.java @@ -1,4 +1,6 @@ -package Model; +package Model.DCEL; + +import Model.Point; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -9,7 +11,7 @@ package Model; */ public class Node { - private Coordinates coordinates; + private Point point; private Edge incidentEdge; private String id; @@ -17,17 +19,17 @@ public class Node { new Node(null, null); } - public Node(Coordinates coordinates, Edge incidentEdge) { - this.coordinates = coordinates; + public Node(Point point, Edge incidentEdge) { + this.point = point; this.incidentEdge = incidentEdge; } - public Coordinates getCoordinates() { - return coordinates; + public Point getPoint() { + return point; } - public void setCoordinates(Coordinates coordinates) { - this.coordinates = coordinates; + public void setPoint(Point point) { + this.point = point; } public Edge getIncidentEdge() { diff --git a/src/main/java/Model/Line.java b/src/main/java/Model/Line.java new file mode 100644 index 0000000..1819949 --- /dev/null +++ b/src/main/java/Model/Line.java @@ -0,0 +1,102 @@ +package Model; + +/** + * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. + * + * @Author: Armin Wolf + * @Email: a_wolf28@uni-muenster.de + * @Date: 12.06.2017. + */ +public class Line { + + private double m; + private double b; + + private double x1; + private double x2; + private double y1; + private double y2; + + private String id; + + public Line(double m, double b, String id) { + this.m = m; + this.b = b; + + this.x1 = Double.MIN_VALUE; + this.y1 = (Double.MIN_VALUE * m ) + b; + this.x2 = Double.MAX_VALUE * 0.5; + this.y2 = ((Double.MAX_VALUE * 0.5) * m ) + b; + this.id = id; + } + + + public Line(double m, double b) { + this.m = m; + this.b = b; + + this.x1 = Double.MIN_VALUE; + this.y1 = (Double.MIN_VALUE * m ) + b; + this.x2 = Double.MAX_VALUE * 0.5; + this.y2 = ((Double.MAX_VALUE * 0.5) * m ) + b; + } + + public Line(double x1, double x2, double y1, double y2) { + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; + + this.m = (y2 -y1)/(x2-x1); + this.b = y2 - (x2 * m); + } + + public double getM() { + return m; + } + + public void setM(double m) { + this.m = m; + } + + public double getB() { + return b; + } + + public void setB(double b) { + this.b = b; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public double getX1() { + return x1; + } + + public double getX2() { + return x2; + } + + public double getY1() { + return y1; + } + + public double getY2() { + return y2; + } + + public void setEndPoints(double x1, double y1, double x2, double y2){ + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; + } + + +} diff --git a/src/main/java/Model/Model.java b/src/main/java/Model/Model.java deleted file mode 100644 index 1ab1b9a..0000000 --- a/src/main/java/Model/Model.java +++ /dev/null @@ -1,11 +0,0 @@ -package Model; - -/** - * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. - * - * @Author: Armin Wolf - * @Email: a_wolf28@uni-muenster.de - * @Date: 28.05.2017. - */ -public interface Model { -} diff --git a/src/main/java/Model/Coordinates.java b/src/main/java/Model/Point.java similarity index 84% rename from src/main/java/Model/Coordinates.java rename to src/main/java/Model/Point.java index dd47482..f762caa 100644 --- a/src/main/java/Model/Coordinates.java +++ b/src/main/java/Model/Point.java @@ -7,12 +7,12 @@ package Model; * @Email: a_wolf28@uni-muenster.de * @Date: 28.05.2017. */ -public class Coordinates implements Comparable { +public class Point implements Comparable { private Double x; private Double y; - public Coordinates(Double x, Double y) { + public Point(Double x, Double y) { this.x = x; this.y = y; } @@ -34,7 +34,7 @@ public class Coordinates implements Comparable { } @Override - public int compareTo(Coordinates o) { + public int compareTo(Point o) { if (this.getX() == o.getX()) { if (this.getY() <= o.getY()) { return -1; diff --git a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java index 850e1a8..5b6a787 100644 --- a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java +++ b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java @@ -1,6 +1,7 @@ package Presenter.Algorithms; -import Model.Coordinates; +import Model.Line; +import Model.Point; import java.util.*; @@ -14,30 +15,311 @@ import java.util.*; public class LeastMedianOfSquaresEstimator extends Algorithm { - private LinkedList set = new LinkedList<>(); - private LinkedList intersections = new LinkedList<>(); - + private LinkedList set = new LinkedList<>(); + private LinkedList intersections = new LinkedList<>(); private int n; - private final double quantile = 0.5; - private final double error = 0.01; private double quantileError; - private double qPlus; - private double qMinus; private double kPlus; private double kMinus; - private Set slab; - private Slab activeSlab; + private ArrayDeque slabs; private Slab subSlabU1; private Slab subSlabU2; - private ArrayList sortedLineSequence = new ArrayList<>(); + private Line sigmaMin; private double heightsigmaMin; - private Coordinates sigmaMinStart; - private Coordinates sigmaMinEnd; - private int numberOfIntersections; - private final int constant = 1; - private Coordinates kMinusBracelet; private double intersectionsPoint; + public LeastMedianOfSquaresEstimator(LinkedList set, LinkedList intersections) { + this.set = set; + this.intersections = intersections; + } + + public void printResult(){ + System.out.println("RESULT: "+sigmaMin.getM()+"x +"+sigmaMin.getB()); + } + + /** + * + */ + public void approximateLMS() { + //(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);.... + n = set.size(); + double quantile = 0.5; + double qPlus = quantile; + double qMinus = qPlus * (1 - quantileError); + kMinus = Math.ceil(n * qMinus); + kPlus = Math.ceil(n * qPlus); + + //(2.) Let U <- (-inf, inf) be the initial active slabs... + slabs = new ArrayDeque<>(); + slabs.add(new Slab(-100000, 100000)); + heightsigmaMin = Double.MAX_VALUE; + + //(3.) Apply the following steps as long as the exists active slabs + while (!slabs.isEmpty()) { + Slab slab = slabs.getFirst(); + //(a.) Select any active Slab and calc. the inversions + int numberOfIntersections = countInversions(slab); + + //(b.) apply plane sweep + int constant = 1; + if (numberOfIntersections < (constant * n)) { + sigmaMin = planeSweep(slab); + } else {//(c.) otherwise.... + //get random intersections point... + splitActiveSlab(intersectionsPoint, slab); + } + //(d.) this may update sigma min + upperBound(intersectionsPoint); + //(e.) for i={1,2}, call lower bound(Ui) + lowerBound(subSlabU1); + lowerBound(subSlabU2); + } + +// printResult(); + } + + /** + * @param slab + * @return + */ + public int countInversions(Slab slab) { + + int numberOfInversions = 0; + + ArrayList umin = new ArrayList<>(); + ArrayList umax = new ArrayList<>(); + ArrayList randomIntersection = new ArrayList<>(); + + for (Line p : set) { + umin.add((slab.getLower() * p.getM()) + p.getB()); + umax.add((slab.getUpper() * p.getM()) + p.getB()); + } + + numberOfInversions = mergeSort(umin, 0, umin.size() - 1, umax); + + for (Point point : intersections) { + if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) { + randomIntersection.add(point.getX()); + } + } + + Collections.shuffle(randomIntersection); + intersectionsPoint = randomIntersection.get(0); + + return numberOfInversions; + } + + //Parameter anpassen + + /** + * + * @param a + * @param start + * @param end + * @param aux + * @return + */ + public int mergeSort(List a, int start, int end, List aux) { + if (start >= end) { + return 0; + } + int invCount = 0; + int mid = start + (end - start) / 2; + int invCountLeft = mergeSort(a, start, mid, aux); // divide and conquer + int invCountRight = mergeSort(a, mid + 1, end, aux); // divide and conquer + invCount += (invCountLeft + invCountRight); + for (int i = start; i <= end; i++) { + aux.set(i, a.get(i)); + } + int left = start; + int right = mid + 1; + int index = start; + while (left <= mid && right <= end) { + if (aux.get(left) < aux.get(right)) { + a.set(index++, aux.get(left++)); + } else { + a.set(index++, aux.get(right++)); + invCount += mid - left + 1; // number of inversions for aux[right] + } + } + while (left <= mid) { + a.set(index++, aux.get(left++)); + } + // no need to copy over remaining aux[right++] because they are already inside a + return invCount; + } + + /** + * @param slab + * @return + */ + public Line planeSweep(Slab slab) { + + //initialisiere die x-Queue mit den 2D Punkten und sortiere nach x-Lexikographischer Ordnung + ArrayList xQueue = new ArrayList<>(); + for (Point point : intersections) { + if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) { + xQueue.add(point); + } + } + Collections.sort(xQueue); + + + Line bracelet = sigmaMin; + double heightOfBracelet = heightsigmaMin; + + for (Point current : xQueue){ + double[] currentBracelet = calcKMinusBracelet(current); + + if (currentBracelet == null){ + continue; + } else if (currentBracelet[0] < heightOfBracelet){ + heightOfBracelet = currentBracelet[0]; + bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]); + System.out.println("R: "+bracelet.getM()+"x +"+bracelet.getB()); + } + } + + + return bracelet; + } + + /** + * @param point + */ + public void splitActiveSlab(double point, Slab active) { + + subSlabU1 = new Slab(active.getLower(), point); + subSlabU2 = new Slab(point, active.getUpper()); + this.slabs.removeFirst(); + } + + /** + * @param point + */ + public void upperBound(double point) { + + double height; + + ArrayList sortedLineSequence = getEjValues(point); + + for (int i = 1; i < (n - (kMinus + 1)); i++) { + height = sortedLineSequence.get(i + (((int) kMinus) - 1)) - sortedLineSequence.get(i); + + if (height < heightsigmaMin) { + sigmaMin.setEndPoints(point, sortedLineSequence.get(i + (((int) kMinus) - 1)) + ,point, sortedLineSequence.get(i)); + } + } + + } + + /** + * @param slab + * @return + */ + public void lowerBound(Slab slab) { + + int[] alpha = new int[n]; + int[] beta = new int[n]; + alpha[0] = 0; + beta[0] = 0; + int strictlyGreater = 0; + + //Teil I. + ArrayList umaxList; + ArrayList uminList; + + //y koordinaten der Schnittpunkte + ArrayList lines = new ArrayList<>(); + System.out.println("Anzahl der Slabs: "+this.slabs.size()); + for (Line p : set) { + lines.add(new Point(((slab.getLower() * p.getM()) + p.getB()), ((slab.getUpper() * p.getM()) + p.getB()))); + } + + + umaxList = getEjValues(slab.getUpper()); + uminList = getEjValues(slab.getLower()); + + for (int i = 1; i < n; i++) { + Point level = new Point(uminList.get(i), umaxList.get(i)); + for (Point point : lines) { + if ((point.getX() < level.getX()) && (point.getY() < level.getY())) { + alpha[i]++; + } + + if ((point.getX() > level.getX()) && (point.getY() > level.getY())) { + strictlyGreater++; + } + } + beta[i] = n - (alpha[i] + strictlyGreater); + } + + //Teil II. + int i = 1; + double h = Double.MAX_VALUE; + for (int j = 1; j < n; j++) { + while (((i < n) && (Math.abs(beta[i] - alpha[j]) < kPlus))){ + System.out.println("i: "+i+"\t "+Math.abs(beta[i] - alpha[j])+"\t kPlus: "+kPlus); + i++; + } + + if (i >= n) { + break; + } else { + h = Math.min((uminList.get(j) - uminList.get(i)), (umaxList.get(j) - umaxList.get(i))); + } + } + double error = 0.01; + System.out.println("h: "+h); + if (((1 + error) * h) < heightsigmaMin) { + this.slabs.addLast(slab); + } + } + + /** + * Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte als e_j Werte + * bekannt. + * + * @param u vertikale Gerade + * @return Liste der Schnittpunkte (da u bekannt werden nur die y Werte zurück gegeben) + */ + public ArrayList getEjValues(double u) { + + ArrayList ret = new ArrayList<>(); + + for (Line p : set) { + ret.add((p.getM() * u) + p.getB()); + } + + Collections.sort(ret); + + return ret; + } + + /** + * + * @param x + * @return + */ + public double[] calcKMinusBracelet(Point x) { + + //y Koordinaten für das kMinus brecalet + LinkedList intersections = new LinkedList<>(); + for (Line line : set) { + intersections.add((x.getX() * line.getM())+line.getB()); + } + if (intersections.size() < kMinus){ + return null; + } else { + Collections.sort(intersections); + double height = Math.abs(intersections.getFirst() - intersections.getLast()); + double[] ret = {height, intersections.getFirst(), intersections.getLast()}; + return ret; + } + + } + /** * Hilfsklasse um die Slabs zu verteilen, private Klasse da sonst nicht verwendett wird und somit eine * äußere Klasse überflüssig ist... @@ -77,259 +359,4 @@ public class LeastMedianOfSquaresEstimator extends Algorithm { } } - - - public void approximateLMS() { - //(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);.... - n = set.size(); - qPlus = quantile; - qMinus = qPlus * (1 - quantileError); - kMinus = Math.ceil(n * qMinus); - kPlus = Math.ceil(n * qPlus); - - //(2.) Let U <- (-inf, inf) be the initial active slab... - slab = new TreeSet<>(); - slab.add(new Slab(Double.MAX_VALUE, Double.MIN_VALUE)); - heightsigmaMin = Double.MAX_VALUE; - - //(3.) Apply the following steps as long as the exists active slabs - for (Iterator it = slab.iterator(); it.hasNext(); ) { - //(a.) Select any active Slab and calc. the inversions - activeSlab = it.next(); - numberOfIntersections = countInversions(activeSlab); - - //(b.) apply plane sweep - if (numberOfIntersections < (constant * n)) { - kMinusBracelet = planeSweep(activeSlab); - } else {//(c.) otherwise.... - //get random intersections point... - splitActiveSlab(intersectionsPoint); - } - //(d.) this may update sigma min - upperBound(intersectionsPoint); - - //(e.) for i={1,2}, call lower bound(Ui) - lowerBound(subSlabU1); - lowerBound(subSlabU2); - } - } - - //Parameter anpassen - - /** - * @param slab - * @return - */ - public int countInversions(Slab slab) { - - int numberOfInversions = 0; - - ArrayList umin = new ArrayList<>(); - ArrayList umax = new ArrayList<>(); - - for (Coordinates p : set) { - umin.add((slab.getLower() * p.getX()) + p.getY()); - umax.add((slab.getUpper() * p.getX()) + p.getY()); - } - - numberOfInversions = mergeSort(umin, 0, umin.size() - 1, umax); - - for (Coordinates point : intersections) { - if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) { - intersectionsPoint = point.getX(); - break; - } - } - - - return numberOfInversions; - } - - public int mergeSort(List a, int start, int end, List aux) { - if (start >= end) { - return 0; - } - int invCount = 0; - int mid = start + (end - start) / 2; - int invCountLeft = mergeSort(a, start, mid, aux); // divide and conquer - int invCountRight = mergeSort(a, mid + 1, end, aux); // divide and conquer - invCount += (invCountLeft + invCountRight); - for (int i = start; i <= end; i++) { - aux.set(i, a.get(i)); - } - int left = start; - int right = mid + 1; - int index = start; - while (left <= mid && right <= end) { - if (aux.get(left) < aux.get(right)) { - a.set(index++, aux.get(left++)); - } else { - a.set(index++, aux.get(right++)); - invCount += mid - left + 1; // number of inversions for aux[right] - } - } - while (left <= mid) { - a.set(index++, aux.get(left++)); - } - // no need to copy over remaining aux[right++] because they are already inside a - return invCount; - } - - /** - * @param slab - * @return - */ - public Coordinates planeSweep(Slab slab) { - Comparator queueComparator = (o1, o2) -> { - if (o1.getX() == o2.getX()) { - if (o1.getY() <= o2.getY()) { - return -1; - } else { - return 1; - } - } else if (o1.getX() < o2.getX()) { - return -1; - } else { - return 1; - } - }; - PriorityQueue xQueue = new PriorityQueue<>(queueComparator); - Comparator treeComparator = (o1, o2) -> { - if (o1.getY() == o2.getY()) { - if (o1.getX() <= o2.getX()) { - return -1; - } else { - return 1; - } - } else if (o1.getY() < o2.getY()) { - return -1; - } else { - return 1; - } - }; - TreeMap yStruct = new TreeMap(treeComparator); - - for (Coordinates point : intersections) { - if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) { - xQueue.add(point); - } - } - - - - return new Coordinates(.0, .0); - } - - /** - * @param point - */ - public void splitActiveSlab(double point) { - - subSlabU1 = new Slab(activeSlab.getLower(), point); - subSlabU2 = new Slab(point, activeSlab.getUpper()); - } - - /** - * @param point - */ - public void upperBound(double point) { - - ArrayList min = new ArrayList<>(); - double height; - - sortedLineSequence = getEjValues(point); - - for (int i = 1; i < (n - (kMinus + 1)); i++) { - height = sortedLineSequence.get(i + (((int) kMinus) - 1)) - sortedLineSequence.get(i); - - if (height < heightsigmaMin) { - sigmaMinStart = new Coordinates(point, sortedLineSequence.get(i + (((int) kMinus) - 1))); - sigmaMinEnd = new Coordinates(point, sortedLineSequence.get(i)); - } - } - - } - - /** - * @param slab - * @return - */ - public Slab lowerBound(Slab slab) { - - boolean active = false; - int[] alpha = new int[n]; - int[] beta = new int[n]; - alpha[0] = 0; - beta[0] = 0; - int strictlyGreater = 0; - - //Teil I. - ArrayList umaxList; - ArrayList uminList; - - //y koordinaten der Schnittpunkte - ArrayList lines = new ArrayList<>(); - for (Coordinates p : set) { - lines.add(new Coordinates(((slab.getLower() * p.getX()) + p.getY()), ((slab.getUpper() * p.getX()) + p.getY()))); - } - - - umaxList = getEjValues(slab.getUpper()); - uminList = getEjValues(slab.getLower()); - - for (int i = 1; i < n; i++) { - Coordinates level = new Coordinates(uminList.get(i), umaxList.get(i)); - for (Coordinates point : lines) { - if ((point.getX() < level.getX()) && (point.getY() < level.getY())) { - alpha[i]++; - } - - if ((point.getX() > level.getX()) && (point.getY() > level.getY())) { - strictlyGreater++; - } - } - beta[i] = n - (alpha[i] + strictlyGreater); - } - - //Teil II. - int i = 1; - double h = Double.MAX_VALUE; - active = false; - for (int j = 0; j < n; j++) { - do { - i++; - } while ((i < n) && (beta[i] - alpha[j] < kPlus)); - - if (i > n) { - slab.setActivity(false); - break; - } - - h = Math.min((uminList.get(j) - uminList.get(i)), (umaxList.get(j) - umaxList.get(i))); - } - if (((1 + error) * h) < heightsigmaMin) { - slab.setActivity(true); - } - return slab; - } - - /** - * Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte als e_j Werte - * bekannt. - * - * @param u vertikale Gerade - * @return Liste der Schnittpunkte (da u bekannt werden nur die y Werte zurück gegeben) - */ - public ArrayList getEjValues(double u) { - - ArrayList ret = new ArrayList<>(); - - for (Coordinates p : set) { - ret.add((p.getX() * u) + p.getY()); - } - - Collections.sort(ret); - - return ret; - } } diff --git a/src/main/java/Presenter/Presenter.java b/src/main/java/Presenter/Presenter.java index 860c3aa..ea31563 100644 --- a/src/main/java/Presenter/Presenter.java +++ b/src/main/java/Presenter/Presenter.java @@ -1,7 +1,9 @@ package Presenter; import Model.Arrangement; -import Model.Coordinates; +import Model.Line; +import Model.Point; +import Presenter.Algorithms.LeastMedianOfSquaresEstimator; import View.MainFrame; import java.util.Collections; @@ -28,16 +30,16 @@ public class Presenter { public Presenter(Arrangement model, MainFrame view) { this.model = model; this.view = view; - Double[] x = {1d, 2d, 3d, 4d, 10d, 12d, 18d}; - Double[] y = {9d, 15d, 19d, 20d, 45d, 55d, 78d}; -// Float[] x = {18f,24f,30f,34f,38f}; -// Float[] y = {18f,26f,30f,40f,70f}; +// Double[] x = {1d, 2d, 3d, 4d, 10d, 12d, 18d}; +// Double[] y = {9d, 15d, 19d, 20d, 45d, 55d, 78d}; + Double[] x = {18d,24d,30d,34d,38d}; + Double[] y = {18d,26d,30d,40d,70d}; // Double[] x = {1d,3d,4d,5d,8d}; // Double[] y = {4d,2d,1d,0d,0d}; view.logHeading("Dualen Geraden"); - for (int j = 0; j < 7; j++) { - Coordinates p = new Coordinates(x[j], y[j]); - view.log("f(x) = " + p.getX() + "x + " + p.getY()); + for (int j = 0; j < 5; j++) { + Line p = new Line(x[j], y[j]); + view.log("f(x) = " + p.getM() + "x + " + p.getB()); this.model.addLine(p); } @@ -47,7 +49,7 @@ public class Presenter { List> rows = new LinkedList<>(); heading.add("X - Koordinate"); heading.add("Y - Koordinate"); - for (Coordinates p : model.getNodes()) { + for (Point p : model.getNodes()) { LinkedList rowEntry = new LinkedList<>(); rowEntry.add(p.getX().toString()); rowEntry.add(p.getY().toString()); @@ -56,6 +58,12 @@ public class Presenter { view.logHeading("Koordinaten der Punkte"); view.createTable(heading, rows); view.logSuccess("Berechnung wurde Erfolgreich durchgeführt"); + + Thread thread = new Thread(() -> { + LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(model.getLines(), model.getNodes()); + lms.approximateLMS(); + }); + thread.start(); } public void startArrangementVisualization() { @@ -72,7 +80,7 @@ public class Presenter { LinkedList xCoordinates = new LinkedList<>(); LinkedList yCoordinates = new LinkedList<>(); - for (Coordinates point : model.getNodes()) { + for (Point point : model.getNodes()) { xCoordinates.add(point.getX()); yCoordinates.add(point.getY()); } @@ -89,7 +97,7 @@ public class Presenter { ymax = yCoordinates.getLast(); -// for (Coordinates p : model.getNodes()) { +// for (Point p : model.getNodes()) { // p.setX(scale(p.getX(), xmin, xmax, 0, 700)); // p.setY(scale(p.getY(), ymin, ymax, 0, 700)); // } @@ -103,30 +111,23 @@ public class Presenter { return ret; } - public Coordinates calcIntersection(Coordinates a, Coordinates b) { - Coordinates p1; - Coordinates p2; + public Point calcIntersection(Line a, Line b) { + Line p1 = a; + Line p2 = b; - if (a.compareTo(b) > 0) { - p1 = a; - p2 = b; - } else { - p1 = b; - p2 = a; - } + Double x = (p1.getB() - p2.getB()) / (p2.getM() - p1.getM()); + Double y = ((p1.getM() * p2.getB()) - (p2.getM() * p1.getB())) / (p1.getM() - p2.getM()); - Double x = (p1.getY() - p2.getY()) / (p2.getX() - p1.getX()); - Double y = ((p1.getX() * p2.getY()) - (p2.getX() * p1.getY())) / (p1.getX() - p2.getX()); - - return new Coordinates(x, y); + return new Point(x, y); } public void calcArrangementNodes() { Thread thread = new Thread(() -> { for (int i = 0; i < getLines().size(); i++) { for (int j = i; j < getLines().size(); j++) { - if (i != j) + if (i != j){ model.addNode(calcIntersection(getLines().get(j), getLines().get(i))); + } } } convertCoordinates(); @@ -140,18 +141,18 @@ public class Presenter { } - public LinkedList> calcArrangementLines(){ - LinkedList> lineCoordinates = new LinkedList<>(); + public LinkedList> calcArrangementLines(){ + LinkedList> lineCoordinates = new LinkedList<>(); double x1 = -1000; double x2 = 1000; - for (Coordinates point : model.getLines()) { + for (Line point : model.getLines()) { LinkedList line = new LinkedList(); - double y1 = (point.getX() * x1 + point.getY()); - double y2 = (point.getX() * x2 + point.getY()); - line.add(new Coordinates(x1,y1)); - line.add(new Coordinates(x2,y2)); + double y1 = (point.getM() * x1 + point.getB()); + double y2 = (point.getM() * x2 + point.getB()); + line.add(new Point(x1,y1)); + line.add(new Point(x2,y2)); lineCoordinates.add(line); } @@ -178,11 +179,11 @@ public class Presenter { this.view = view; } - public LinkedList getLines() { + public LinkedList getLines() { return this.model.getLines(); } - public void setLines(LinkedList lines) { + public void setLines(LinkedList lines) { this.model.setLines(lines); } diff --git a/src/main/java/View/ArrangementDialog.java b/src/main/java/View/ArrangementDialog.java index fe802d8..43b5784 100644 --- a/src/main/java/View/ArrangementDialog.java +++ b/src/main/java/View/ArrangementDialog.java @@ -1,6 +1,6 @@ package View; -import Model.Coordinates; +import Model.Point; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; @@ -24,8 +24,8 @@ import java.util.LinkedList; */ public class ArrangementDialog extends JPanel { - private LinkedList lines; - private LinkedList points; + private LinkedList lines; + private LinkedList points; private double max; private double min; private JFreeChart chart; @@ -39,7 +39,7 @@ public class ArrangementDialog extends JPanel { this.setMinimumSize(new Dimension(800, 500)); } - public void setPrameters(Double pmax, Double pmin, LinkedList lines, LinkedList points) { + public void setPrameters(Double pmax, Double pmin, LinkedList lines, LinkedList points) { this.max = pmax; this.min = pmin; this.lines = lines; @@ -53,7 +53,7 @@ public class ArrangementDialog extends JPanel { public void createArrangement() { XYSeriesCollection dataset = new XYSeriesCollection(); - for (Coordinates p : lines) { + for (Point p : lines) { XYSeries series = new XYSeries(p.getX() + p.getY()); series.add((-1 * this.max), (((-1 * this.max) * p.getX()) + p.getY())); series.add(this.max, ((this.max * p.getX()) + p.getY())); @@ -61,7 +61,7 @@ public class ArrangementDialog extends JPanel { } XYSeries intersections = new XYSeries("intersections"); - for (Coordinates p : points) { + for (Point p : points) { domainMax = domainMax < p.getX() ? p.getX() : domainMax; domainMin = domainMin > p.getX() ? p.getX() : domainMin; rangeMax = rangeMax < p.getY() ? p.getY() : rangeMax; diff --git a/src/main/java/View/ArrangementDialog2.java b/src/main/java/View/ArrangementDialog2.java index 09f3d9d..42003ef 100644 --- a/src/main/java/View/ArrangementDialog2.java +++ b/src/main/java/View/ArrangementDialog2.java @@ -1,16 +1,10 @@ package View; -import Model.Coordinates; -import sun.awt.image.ImageWatched; -import sun.plugin.dom.core.CoreConstants; +import Model.Point; import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.geom.Line2D; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; import java.util.LinkedList; /** @@ -30,8 +24,8 @@ public class ArrangementDialog2 extends JPanel { private Dimension dimension; - private LinkedList> lines; - private LinkedList points; + private LinkedList> lines; + private LinkedList points; private LinkedList line2Ds; @@ -43,7 +37,7 @@ public class ArrangementDialog2 extends JPanel { } - public void setPrameters(LinkedList> lines, LinkedList points) { + public void setPrameters(LinkedList> lines, LinkedList points) { this.lines = lines; this.points = points; this.repaint(); @@ -78,7 +72,7 @@ public class ArrangementDialog2 extends JPanel { //draw the lines g2.setColor(Color.BLACK); g2.setStroke(new BasicStroke(5f / (float) scale)); - for (LinkedList line : lines){ + for (LinkedList line : lines){ line2Ds.add(new Line2D.Double(zero +line.getFirst().getX().intValue(), zero +line.getFirst().getY().intValue(), zero +line.getLast().getX().intValue(), zero +line.getLast().getY().intValue())); } for (Line2D.Double line : line2Ds) { @@ -87,7 +81,7 @@ public class ArrangementDialog2 extends JPanel { //draw intersections of the lines g2.setColor(Color.RED); - for (Coordinates point : points) { + for (Point point : points) { g2.fillOval(zero +point.getX().intValue(),zero +point.getY().intValue(), pointThicknes, pointThicknes); } } diff --git a/src/main/java/View/PlotDialog.java b/src/main/java/View/PlotDialog.java index 427652b..80cae06 100644 --- a/src/main/java/View/PlotDialog.java +++ b/src/main/java/View/PlotDialog.java @@ -1,6 +1,7 @@ package View; -import Model.Coordinates; +import Model.Line; +import Model.Point; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; @@ -35,7 +36,7 @@ public class PlotDialog extends JPanel { this.setMinimumSize(new Dimension(800, 500)); } - public void createPlot(LinkedList points) { + public void createPlot(LinkedList points) { Thread thread = new Thread(() -> convertData(points)); thread.start(); @@ -71,12 +72,12 @@ public class PlotDialog extends JPanel { //TODO Line Estimator } - private void convertData(LinkedList points) { + private void convertData(LinkedList points) { datapoints = new XYSeriesCollection(); series = new XYSeries(""); - for (Coordinates p : points) { - series.add(p.getX(), p.getY()); + for (Line p : points) { + series.add(p.getM(), p.getB()); } datapoints.addSeries(series); diff --git a/src/test/java/Model/DoublyConnectedEdgeListTest.java b/src/test/java/Model/DoublyConnectedEdgeListTest.java index 46c393d..459af80 100644 --- a/src/test/java/Model/DoublyConnectedEdgeListTest.java +++ b/src/test/java/Model/DoublyConnectedEdgeListTest.java @@ -1,5 +1,9 @@ package Model; +import Model.DCEL.DoublyConnectedEdgeList; +import Model.DCEL.Edge; +import Model.DCEL.Face; +import Model.DCEL.Node; import org.junit.Before; import org.junit.Test; @@ -27,11 +31,11 @@ public class DoublyConnectedEdgeListTest { dcel = new DoublyConnectedEdgeList(); //initialisiere die TestKnoten im Graphen - v1 = dcel.createNode(new Coordinates(2.5, 7.5), "v1"); - v2 = dcel.createNode(new Coordinates(2.5, 4.0), "v2"); - v3 = dcel.createNode(new Coordinates(6.5, 3.5), "v3"); - v4 = dcel.createNode(new Coordinates(8.5, 6.5), "v4"); - v5 = dcel.createNode(new Coordinates(6.0, 8.0), "v5"); + v1 = dcel.createNode(new Point(2.5, 7.5), "v1"); + v2 = dcel.createNode(new Point(2.5, 4.0), "v2"); + v3 = dcel.createNode(new Point(6.5, 3.5), "v3"); + v4 = dcel.createNode(new Point(8.5, 6.5), "v4"); + v5 = dcel.createNode(new Point(6.0, 8.0), "v5"); //initialisere Kanten im Graph e1 = dcel.createEdge(v1, v5, "e1"); diff --git a/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java b/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java index 58bcc78..dea4976 100644 --- a/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java +++ b/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java @@ -1,9 +1,14 @@ package Presenter.Algorithms; + +import Model.Line; +import Model.Point; import org.junit.Before; import org.junit.Test; + import java.util.ArrayList; +import java.util.LinkedList; import static org.junit.Assert.*; @@ -20,11 +25,18 @@ public class LeastMedianOfSquaresEstimatorTest { @Before public void setUp() throws Exception { - lms = new LeastMedianOfSquaresEstimator(); + + LinkedList line = new LinkedList<>(); + LinkedList intersections = new LinkedList<>(); + + + + lms = new LeastMedianOfSquaresEstimator(line, intersections); } @Test public void approximateLMS() throws Exception { + } @@ -50,24 +62,4 @@ public class LeastMedianOfSquaresEstimatorTest { } - @Test - public void planeSweep() throws Exception { - } - - @Test - public void splitActiveSlab() throws Exception { - } - - @Test - public void upperBound() throws Exception { - } - - @Test - public void lowerBound() throws Exception { - } - - @Test - public void getEjValues() throws Exception { - } - } \ No newline at end of file