WIP: RM Estimator

This commit is contained in:
Armin Wolf 2017-06-20 16:59:24 +02:00
parent 04bcaa0f24
commit 6b99966b5e
29 changed files with 2399 additions and 2170 deletions

64
pom.xml
View File

@ -1,39 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>wwu</groupId> <groupId>wwu</groupId>
<artifactId>masterarbeit</artifactId> <artifactId>masterarbeit</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<source>1.8</source> <source>1.8</source>
<target>1.8</target> <target>1.8</target>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<!-- https://mvnrepository.com/artifact/org.jfree/jfreechart --> <!-- https://mvnrepository.com/artifact/org.jfree/jfreechart -->
<dependency> <dependency>
<groupId>org.jfree</groupId> <groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId> <artifactId>jfreechart</artifactId>
<version>1.0.14</version> <version>1.0.14</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/junit/junit --> <!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.12</version> <version>4.12</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,8 +1,7 @@
import Model.Arrangement; import Model.Arrangement;
import Presenter.Presenter; import Presenter.Presenter;
import View.MainFrame; import View.MainFrame;
import javax.swing.SwingUtilities;
import javax.swing.*;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -14,13 +13,13 @@ import javax.swing.*;
public class App { public class App {
public static void main(String[] args) { public static void main(String[] args) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
MainFrame view = new MainFrame(); MainFrame view = new MainFrame();
view.setPresenter(new Presenter(new Arrangement(), view)); view.setPresenter(new Presenter(new Arrangement(), view));
}); });
} }
} }

View File

@ -11,33 +11,33 @@ import java.util.LinkedList;
*/ */
public class Arrangement { public class Arrangement {
private LinkedList<Point> nodes; private LinkedList<Point> nodes;
private LinkedList<Line> lines; private LinkedList<Line> lines;
public Arrangement() { public Arrangement() {
nodes = new LinkedList<>(); nodes = new LinkedList<>();
lines = new LinkedList<>(); lines = new LinkedList<>();
} }
public void addNode(Point node) { public void addNode(Point node) {
this.nodes.add(node); this.nodes.add(node);
} }
public void addLine(Line line) { public void addLine(Line line) {
this.lines.add(line); this.lines.add(line);
} }
public LinkedList<Point> getNodes() { public LinkedList<Point> getNodes() {
return nodes; return nodes;
} }
public LinkedList<Line> getLines() { public LinkedList<Line> getLines() {
return lines; return lines;
} }
public void setLines(LinkedList<Line> lines) { public void setLines(LinkedList<Line> lines) {
this.lines = lines; this.lines = lines;
} }
} }

View File

@ -2,7 +2,6 @@ package Model.DCEL;
import Model.Point; import Model.Point;
import java.util.LinkedList; import java.util.LinkedList;
/** /**
@ -14,141 +13,141 @@ import java.util.LinkedList;
*/ */
public class DoublyConnectedEdgeList { public class DoublyConnectedEdgeList {
private LinkedList<Node> nodes; private LinkedList<Node> nodes;
private LinkedList<Edge> edges; private LinkedList<Edge> edges;
private LinkedList<Face> faces; private LinkedList<Face> faces;
public DoublyConnectedEdgeList() { public DoublyConnectedEdgeList() {
this.nodes = new LinkedList<>(); this.nodes = new LinkedList<>();
this.edges = new LinkedList<>(); this.edges = new LinkedList<>();
this.faces = new LinkedList<>(); this.faces = new LinkedList<>();
}
public Node createNode(Point point, String id) {
Node node = new Node();
node.setPoint(point);
node.setID(id);
return node;
}
public Edge createEdge(Node source, Node destination, String id) {
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(source);
edge.setID(id);
edge.setTwin(twin);
twin.setOrigin(destination);
twin.setID("#" + id);
twin.setTwin(edge);
source.setIncidentEdge(edge);
destination.setIncidentEdge(twin);
return edge;
}
public Face createFace(Edge outerComponent, Edge innerComponent, String id) {
Face face = new Face(outerComponent, null);
face.setID(id);
Edge tempEdge;
if (outerComponent != null) {
tempEdge = outerComponent;
do {
tempEdge.setIncidentFace(face);
tempEdge = tempEdge.getNext();
} while (!tempEdge.equals(outerComponent));
} }
public Node createNode(Point point, String id) { if (innerComponent != null) {
LinkedList<Edge> componentlist;
Node node = new Node(); componentlist = face.getInnerComponents();
node.setPoint(point); componentlist.add(innerComponent);
node.setID(id); tempEdge = innerComponent;
do {
return node; tempEdge.setIncidentFace(face);
tempEdge = tempEdge.getNext();
} while (!tempEdge.equals(innerComponent));
} }
public Edge createEdge(Node source, Node destination, String id) { return face;
}
Edge edge = new Edge(); public void createConnection(Edge edge, Edge succ) {
Edge twin = new Edge(); edge.setNext(succ);
succ.setPrev(edge);
edge.setOrigin(source); edge.getTwin().setPrev(succ.getTwin());
edge.setID(id); succ.getTwin().setNext(edge.getTwin());
edge.setTwin(twin); }
twin.setOrigin(destination);
twin.setID("#" + id);
twin.setTwin(edge);
source.setIncidentEdge(edge); public LinkedList<Edge> getEdgesOfInnerComponents(Face face) {
destination.setIncidentEdge(twin);
return edge; LinkedList<Edge> list = new LinkedList();
LinkedList<Edge> innerComponents = face.getInnerComponents();
Edge it;
for (Edge e : innerComponents) {
it = e;
do {
list.add(it);
//System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID());
it = it.getNext();
} while (it != e);
} }
public Face createFace(Edge outerComponent, Edge innerComponent, String id) { return list;
}
Face face = new Face(outerComponent, null); public LinkedList<Edge> getEdgesOfOuterComponents(Face face) {
face.setID(id);
Edge tempEdge;
if (outerComponent != null) { LinkedList<Edge> list = new LinkedList();
tempEdge = outerComponent; Edge it = face.getOuterComponent();
do { do {
tempEdge.setIncidentFace(face); list.add(it);
tempEdge = tempEdge.getNext(); //System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID());
} while (!tempEdge.equals(outerComponent)); it = it.getNext();
} } while (it != face.getOuterComponent());
if (innerComponent != null) { return list;
LinkedList<Edge> componentlist; }
componentlist = face.getInnerComponents();
componentlist.add(innerComponent);
tempEdge = innerComponent;
do {
tempEdge.setIncidentFace(face);
tempEdge = tempEdge.getNext();
} while (!tempEdge.equals(innerComponent));
}
return face;
}
public void createConnection(Edge edge, Edge succ) {
edge.setNext(succ);
succ.setPrev(edge);
edge.getTwin().setPrev(succ.getTwin());
succ.getTwin().setNext(edge.getTwin());
}
public LinkedList<Edge> getEdgesOfInnerComponents(Face face) {
LinkedList<Edge> list = new LinkedList();
LinkedList<Edge> innerComponents = face.getInnerComponents();
Edge it;
for (Edge e : innerComponents) {
it = e;
do {
list.add(it);
//System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID());
it = it.getNext();
} while (it != e);
}
return list;
}
public LinkedList<Edge> getEdgesOfOuterComponents(Face face) {
LinkedList<Edge> list = new LinkedList();
Edge it = face.getOuterComponent();
do {
list.add(it);
//System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID());
it = it.getNext();
} while (it != face.getOuterComponent());
return list;
}
public LinkedList<Edge> getConnectedEdges(Node node) { public LinkedList<Edge> getConnectedEdges(Node node) {
Edge edge = node.getIncidentEdge(); Edge edge = node.getIncidentEdge();
LinkedList list = new LinkedList(); LinkedList list = new LinkedList();
do { do {
list.add(edge); list.add(edge);
edge = edge.getNext(); edge = edge.getNext();
} while (node != edge.getOrigin()); } while (node != edge.getOrigin());
return list; return list;
} }
public LinkedList<Node> getNodes() { public LinkedList<Node> getNodes() {
return nodes; return nodes;
} }
public void setNodes(LinkedList<Node> nodes) { public void setNodes(LinkedList<Node> nodes) {
this.nodes = nodes; this.nodes = nodes;
} }
public LinkedList<Edge> getEdges() { public LinkedList<Edge> getEdges() {
return edges; return edges;
} }
public void setEdges(LinkedList<Edge> edges) { public void setEdges(LinkedList<Edge> edges) {
this.edges = edges; this.edges = edges;
} }
public LinkedList<Face> getFaces() { public LinkedList<Face> getFaces() {
return faces; return faces;
} }
public void setFaces(LinkedList<Face> faces) { public void setFaces(LinkedList<Face> faces) {
this.faces = faces; this.faces = faces;
} }
} }

View File

@ -9,109 +9,109 @@ package Model.DCEL;
*/ */
public class Edge { public class Edge {
private Node origin; private Node origin;
private Edge twin; private Edge twin;
private Face incidentFace; private Face incidentFace;
private Edge next; private Edge next;
private Edge prev; private Edge prev;
private String id; private String id;
public Edge() { public Edge() {
new Edge(null, null, null, null, null); new Edge(null, null, null, null, null);
}
public Edge(Node origin, Edge twin, Edge next, Edge prev, Face incidentFace) {
this.origin = origin;
this.twin = twin;
this.next = next;
this.prev = prev;
this.incidentFace = incidentFace;
}
public Node getOrigin() {
return origin;
}
public void setOrigin(Node origin) {
this.origin = origin;
}
public Edge getTwin() {
return twin;
}
public void setTwin(Edge twin) {
this.twin = twin;
}
public Face getIncidentFace() {
return incidentFace;
}
public void setIncidentFace(Face incidentFace) {
this.incidentFace = incidentFace;
}
public Edge getNext() {
return next;
}
public void setNext(Edge next) {
this.next = next;
}
public Edge getPrev() {
return prev;
}
public void setPrev(Edge prev) {
this.prev = prev;
}
public boolean hasNext() {
if (getNext() == null) {
return false;
} else {
return true;
} }
public Edge(Node origin, Edge twin, Edge next, Edge prev, Face incidentFace) { }
this.origin = origin;
this.twin = twin;
this.next = next;
this.prev = prev;
this.incidentFace = incidentFace;
}
public Node getOrigin() { public Edge insertNode(Node node) {
return origin;
}
public void setOrigin(Node origin) { Edge edge = new Edge();
this.origin = origin; Edge twin = new Edge();
}
public Edge getTwin() { edge.setOrigin(node);
return twin; edge.setNext(this.getNext());
} edge.setPrev(this);
edge.setTwin(twin);
edge.setIncidentFace(this.getIncidentFace());
public void setTwin(Edge twin) { twin.setOrigin(this.getTwin().getOrigin());
this.twin = twin; twin.setPrev(this.getTwin().getPrev());
} twin.setNext(this.getTwin());
twin.setTwin(edge);
twin.setIncidentFace(this.getTwin().getIncidentFace());
public Face getIncidentFace() { Node twinOrigin = this.getTwin().getOrigin();
return incidentFace; twinOrigin.setIncidentEdge(twin);
} node.setIncidentEdge(edge);
public void setIncidentFace(Face incidentFace) { this.getTwin().setOrigin(node);
this.incidentFace = incidentFace; this.getTwin().getPrev().setNext(twin);
} this.getNext().setPrev(edge);
this.setNext(edge);
this.getTwin().setPrev(twin);
public Edge getNext() { return edge;
return next; }
}
public void setNext(Edge next) { public String getID() {
this.next = next; return this.id;
} }
public Edge getPrev() { public void setID(String id) {
return prev; this.id = id;
} }
public void setPrev(Edge prev) {
this.prev = prev;
}
public boolean hasNext() {
if (getNext() == null) {
return false;
} else {
return true;
}
}
public Edge insertNode(Node node) {
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(node);
edge.setNext(this.getNext());
edge.setPrev(this);
edge.setTwin(twin);
edge.setIncidentFace(this.getIncidentFace());
twin.setOrigin(this.getTwin().getOrigin());
twin.setPrev(this.getTwin().getPrev());
twin.setNext(this.getTwin());
twin.setTwin(edge);
twin.setIncidentFace(this.getTwin().getIncidentFace());
Node twinOrigin = this.getTwin().getOrigin();
twinOrigin.setIncidentEdge(twin);
node.setIncidentEdge(edge);
this.getTwin().setOrigin(node);
this.getTwin().getPrev().setNext(twin);
this.getNext().setPrev(edge);
this.setNext(edge);
this.getTwin().setPrev(twin);
return edge;
}
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
} }

View File

@ -11,113 +11,115 @@ import java.util.LinkedList;
*/ */
public class Face { public class Face {
private LinkedList<Edge> innerComponents; private LinkedList<Edge> innerComponents;
private Edge outerComponent; private Edge outerComponent;
private String id; private String id;
public Face() {
this.outerComponent = null;
this.innerComponents = new LinkedList<>();
}
public Face(Edge outerComponent, LinkedList<Edge> innerComponents) {
this.outerComponent = outerComponent;
if (innerComponents != null) {
this.innerComponents = innerComponents;
} else {
this.innerComponents = new LinkedList<>();
public Face() {
this.outerComponent = null;
this.innerComponents = new LinkedList<>();
} }
public Face(Edge outerComponent, LinkedList<Edge> innerComponents) { }
this.outerComponent = outerComponent;
if (innerComponents != null) {
this.innerComponents = innerComponents;
} else {
this.innerComponents = new LinkedList<>();
public LinkedList<Edge> getInnerComponents() {
return innerComponents;
}
public void setInnerComponents(LinkedList<Edge> innerComponents) {
this.innerComponents = innerComponents;
}
public Edge getOuterComponent() {
return outerComponent;
}
public void setOuterComponent(Edge outerComponent) {
this.outerComponent = outerComponent;
}
public Face insertEdge(Edge edgeWithSameDestination, Edge edgeToMySource) {
if (edgeWithSameDestination.getIncidentFace().equals(this) || edgeToMySource.getIncidentFace()
.equals(this)) {
LinkedList<Edge> components = new LinkedList<Edge>();
for (Edge e : innerComponents) {
components.add(e);
}
Face face = new Face(getOuterComponent(), components);
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(edgeWithSameDestination.getOrigin());
edge.setTwin(twin);
edge.setNext(edgeToMySource);
edge.setPrev(edgeWithSameDestination.getPrev());
twin.setOrigin(edgeToMySource.getOrigin());
twin.setTwin(edge);
twin.setNext(edgeWithSameDestination);
twin.setPrev(edgeToMySource.getPrev());
Edge tempEdge = edge.getNext();
Edge tempTwin = twin.getNext();
//kreis umlaufen um festzustellen welche fläche kleiner ist
while ((tempEdge.equals(edge) == false) && (tempTwin.equals(twin) == false)) {
tempEdge = tempEdge.getNext();
tempTwin = tempTwin.getNext();
}
if (tempEdge.equals(edge)) {
setOuterComponent(twin);
twin.setIncidentFace(this);
face.setOuterComponent(edge);
} else {
setOuterComponent(edge);
edge.setIncidentFace(this);
face.setOuterComponent(twin);
}
LinkedList<Edge> bla = new LinkedList<Edge>();
Edge iterEdge = face.getOuterComponent();
bla.add(face.getOuterComponent());
while (iterEdge.hasNext()) {
bla.add(iterEdge.getNext());
iterEdge = iterEdge.getNext();
}
for (Edge e : face.getInnerComponents()) {
iterEdge = e;
while (iterEdge.hasNext()) {
bla.add(iterEdge.getNext());
iterEdge = iterEdge.getNext();
} }
}
for (Edge e : bla) {
e.setIncidentFace(face);
}
return face;
} else {
throw new IllegalArgumentException(
"Die angegebenen Kanten haben keinen zusammenhang mit der Fläche!");
} }
public LinkedList<Edge> getInnerComponents() { }
return innerComponents;
}
public void setInnerComponents(LinkedList<Edge> innerComponents) { public String getID() {
this.innerComponents = innerComponents; return this.id;
} }
public Edge getOuterComponent() { public void setID(String id) {
return outerComponent; this.id = id;
} }
public void setOuterComponent(Edge outerComponent) {
this.outerComponent = outerComponent;
}
public Face insertEdge(Edge edgeWithSameDestination, Edge edgeToMySource) {
if (edgeWithSameDestination.getIncidentFace().equals(this) || edgeToMySource.getIncidentFace().equals(this)) {
LinkedList<Edge> components = new LinkedList<Edge>();
for (Edge e : innerComponents) {
components.add(e);
}
Face face = new Face(getOuterComponent(), components);
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(edgeWithSameDestination.getOrigin());
edge.setTwin(twin);
edge.setNext(edgeToMySource);
edge.setPrev(edgeWithSameDestination.getPrev());
twin.setOrigin(edgeToMySource.getOrigin());
twin.setTwin(edge);
twin.setNext(edgeWithSameDestination);
twin.setPrev(edgeToMySource.getPrev());
Edge tempEdge = edge.getNext();
Edge tempTwin = twin.getNext();
//kreis umlaufen um festzustellen welche fläche kleiner ist
while ((tempEdge.equals(edge) == false) && (tempTwin.equals(twin) == false)) {
tempEdge = tempEdge.getNext();
tempTwin = tempTwin.getNext();
}
if (tempEdge.equals(edge)) {
setOuterComponent(twin);
twin.setIncidentFace(this);
face.setOuterComponent(edge);
} else {
setOuterComponent(edge);
edge.setIncidentFace(this);
face.setOuterComponent(twin);
}
LinkedList<Edge> bla = new LinkedList<Edge>();
Edge iterEdge = face.getOuterComponent();
bla.add(face.getOuterComponent());
while (iterEdge.hasNext()) {
bla.add(iterEdge.getNext());
iterEdge = iterEdge.getNext();
}
for (Edge e : face.getInnerComponents()) {
iterEdge = e;
while (iterEdge.hasNext()) {
bla.add(iterEdge.getNext());
iterEdge = iterEdge.getNext();
}
}
for (Edge e : bla) {
e.setIncidentFace(face);
}
return face;
} else {
throw new IllegalArgumentException("Die angegebenen Kanten haben keinen zusammenhang mit der Fläche!");
}
}
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
} }

View File

@ -11,40 +11,40 @@ import Model.Point;
*/ */
public class Node { public class Node {
private Point point; private Point point;
private Edge incidentEdge; private Edge incidentEdge;
private String id; private String id;
public Node() { public Node() {
new Node(null, null); new Node(null, null);
} }
public Node(Point point, Edge incidentEdge) { public Node(Point point, Edge incidentEdge) {
this.point = point; this.point = point;
this.incidentEdge = incidentEdge; this.incidentEdge = incidentEdge;
} }
public Point getPoint() { public Point getPoint() {
return point; return point;
} }
public void setPoint(Point point) { public void setPoint(Point point) {
this.point = point; this.point = point;
} }
public Edge getIncidentEdge() { public Edge getIncidentEdge() {
return incidentEdge; return incidentEdge;
} }
public void setIncidentEdge(Edge incidentEdge) { public void setIncidentEdge(Edge incidentEdge) {
this.incidentEdge = incidentEdge; this.incidentEdge = incidentEdge;
} }
public String getID() { public String getID() {
return this.id; return this.id;
} }
public void setID(String id) { public void setID(String id) {
this.id = id; this.id = id;
} }
} }

View File

@ -9,95 +9,95 @@ package Model;
*/ */
public class Line { public class Line {
private double m; private double m;
private double b; private double b;
private double x1; private double x1;
private double x2; private double x2;
private double y1; private double y1;
private double y2; private double y2;
private String id; private String id;
public Line(double m, double b, String id) { public Line(double m, double b, String id) {
this.m = m; this.m = m;
this.b = b; this.b = b;
this.x1 = Double.MIN_VALUE; this.x1 = Double.MIN_VALUE;
this.y1 = (Double.MIN_VALUE * m ) + b; this.y1 = (Double.MIN_VALUE * m) + b;
this.x2 = Double.MAX_VALUE * 0.5; this.x2 = Double.MAX_VALUE * 0.5;
this.y2 = ((Double.MAX_VALUE * 0.5) * m ) + b; this.y2 = ((Double.MAX_VALUE * 0.5) * m) + b;
this.id = id; this.id = id;
} }
public Line(double m, double b) { public Line(double m, double b) {
this.m = m; this.m = m;
this.b = b; this.b = b;
this.x1 = Double.MIN_VALUE; this.x1 = Double.MIN_VALUE;
this.y1 = (Double.MIN_VALUE * m ) + b; this.y1 = (Double.MIN_VALUE * m) + b;
this.x2 = Double.MAX_VALUE * 0.5; this.x2 = Double.MAX_VALUE * 0.5;
this.y2 = ((Double.MAX_VALUE * 0.5) * m ) + b; this.y2 = ((Double.MAX_VALUE * 0.5) * m) + b;
} }
public Line(double x1, double x2, double y1, double y2) { public Line(double x1, double x2, double y1, double y2) {
this.x1 = x1; this.x1 = x1;
this.x2 = x2; this.x2 = x2;
this.y1 = y1; this.y1 = y1;
this.y2 = y2; this.y2 = y2;
this.m = (y2 -y1)/(x2-x1); this.m = (y2 - y1) / (x2 - x1);
this.b = y2 - (x2 * m); this.b = y2 - (x2 * m);
} }
public double getM() { public double getM() {
return m; return m;
} }
public void setM(double m) { public void setM(double m) {
this.m = m; this.m = m;
} }
public double getB() { public double getB() {
return b; return b;
} }
public void setB(double b) { public void setB(double b) {
this.b = b; this.b = b;
} }
public String getId() { public String getId() {
return id; return id;
} }
public void setId(String id) { public void setId(String id) {
this.id = id; this.id = id;
} }
public double getX1() { public double getX1() {
return x1; return x1;
} }
public double getX2() { public double getX2() {
return x2; return x2;
} }
public double getY1() { public double getY1() {
return y1; return y1;
} }
public double getY2() { public double getY2() {
return y2; return y2;
} }
public void setEndPoints(double x1, double y1, double x2, double y2){ public void setEndPoints(double x1, double y1, double x2, double y2) {
this.x1 = x1; this.x1 = x1;
this.x2 = x2; this.x2 = x2;
this.y1 = y1; this.y1 = y1;
this.y2 = y2; this.y2 = y2;
} }
} }

View File

@ -8,26 +8,28 @@ package Model;
* @Date: 19.06.2017. * @Date: 19.06.2017.
*/ */
public class Pair { public class Pair {
private Integer p1;
private Integer p2;
public Pair(Integer p1, Integer p2) {
this.p1 = p1;
this.p2 = p2;
}
public Integer getP1() { private Integer p1;
return p1; private Integer p2;
}
public void setP1(Integer p1) { public Pair(Integer p1, Integer p2) {
this.p1 = p1; this.p1 = p1;
} this.p2 = p2;
}
public Integer getP2() { public Integer getP1() {
return p2; return p1;
} }
public void setP2(Integer p2) { public void setP1(Integer p1) {
this.p2 = p2; this.p1 = p1;
} }
public Integer getP2() {
return p2;
}
public void setP2(Integer p2) {
this.p2 = p2;
}
} }

View File

@ -9,57 +9,57 @@ package Model;
*/ */
public class Point implements Comparable<Point> { public class Point implements Comparable<Point> {
private Double x; private Double x;
private Double y; private Double y;
private String id; private String id;
public Point(Double x, Double y) { public Point(Double x, Double y) {
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
public Point(Double x, Double y, String id) { public Point(Double x, Double y, String id) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.id = id; this.id = id;
} }
public Double getX() { public Double getX() {
return x; return x;
} }
public void setX(Double x) { public void setX(Double x) {
this.x = x; this.x = x;
} }
public Double getY() { public Double getY() {
return y; return y;
} }
public void setY(Double y) { public void setY(Double y) {
this.y = y; this.y = y;
} }
@Override @Override
public int compareTo(Point o) { public int compareTo(Point o) {
if (this.getX() == o.getX()) { if (this.getX() == o.getX()) {
if (this.getY() <= o.getY()) { if (this.getY() <= o.getY()) {
return -1; return -1;
} else { } else {
return 1; return 1;
} }
} else if (this.getX() < o.getX()) { } else if (this.getX() < o.getX()) {
return -1; return -1;
} else { } else {
return 1; return 1;
}
} }
}
public String getId() { public String getId() {
return id; return id;
} }
public void setId(String id) { public void setId(String id) {
this.id = id; this.id = id;
} }
} }

View File

@ -8,43 +8,44 @@ package Model;
* @Date: 16.06.2017. * @Date: 16.06.2017.
*/ */
public class Slab { public class Slab {
private double upper;
private double lower;
private Boolean activity;
public Slab(double lower, double upper) { private double upper;
this.upper = upper; private double lower;
this.lower = lower; private Boolean activity;
this.activity = true;
}
public Boolean getActivity() { public Slab(double lower, double upper) {
return activity; this.upper = upper;
} this.lower = lower;
this.activity = true;
}
public void setActivity(Boolean isActive) { public Boolean getActivity() {
this.activity = isActive; return activity;
} }
public double getUpper() { public void setActivity(Boolean isActive) {
return upper; this.activity = isActive;
} }
public void setUpper(double upper) { public double getUpper() {
this.upper = upper; return upper;
} }
public double getLower() { public void setUpper(double upper) {
return lower; this.upper = upper;
} }
public void setLower(double lower) { public double getLower() {
this.lower = lower; return lower;
} }
public Double getDistance(){ public void setLower(double lower) {
this.lower = lower;
}
return Math.abs(this.upper - this.lower); public Double getDistance() {
}
return Math.abs(this.upper - this.lower);
}
} }

View File

@ -1,7 +1,5 @@
package Presenter.Algorithms; package Presenter.Algorithms;
import java.util.Observable;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *

View File

@ -1,165 +0,0 @@
package Presenter.Algorithms;
import Model.Line;
import Model.Pair;
import Model.Point;
import Model.Slab;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 18.06.2017.
*/
public class InversionCounter {
private HashMap<Integer, Integer> dictionaryTO;
private HashMap<Integer, Integer> dictionaryBACK;
private ArrayList<Integer> substituted;
private ArrayList<Pair> inversions;
//indexieren der Punkte damit die schnittpunkte berechnet werden können
private HashMap<Integer, Integer> secondaryIndex;
private ArrayList<Point> umin;
private ArrayList<Point> umax;
public int run(List<Integer> a, List<Integer> b){
dictionaryTO = new HashMap<>();
dictionaryBACK = new HashMap<>();
substituted = new ArrayList<>();
inversions = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
temp.addAll(a);
for (int i=0;i<a.size();i++){
dictionaryTO.put(a.get(i), i+1 );
dictionaryBACK.put(i+1 , a.get(i));
}
for (int j=0;j<b.size();j++){
substituted.add(dictionaryTO.get(b.get(j)));
}
int ret = countInversions(substituted, 0, substituted.size()-1, temp);
dictionaryTO = null;
substituted = null;
inversions = null;
return ret;
}
public int run(List<Line> set, Slab slab){
ArrayList<Integer> listA = new ArrayList<>();
ArrayList<Integer> listB = new ArrayList<>();
prepareData(set, slab, listA, listB);
return run(listA, listB);
}
private void prepareData(List<Line> set, Slab slab, ArrayList<Integer> listA, ArrayList<Integer> listB){
secondaryIndex = new HashMap<>();
umin = new ArrayList<>();
umax = new ArrayList<>();
int counter = 0;
for (Line p : set) {
//vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet
umin.add(new Point(slab.getLower() * p.getM() + p.getB(),p.getM(), counter+""));
umax.add(new Point(slab.getUpper() * p.getM() + p.getB(),p.getM() ,counter+""));
counter++;
}
for (int i=0; i<umin.size();i++){
int id = Integer.parseInt(umin.get(i).getId());
secondaryIndex.put(id, i);
}
Collections.sort(umin);
Collections.sort(umax);
for (Point p : umax){
int x = Integer.parseInt(p.getId());
listB.add(secondaryIndex.get(x));
}
for (Point q : umin){
int x = Integer.parseInt(q.getId());
listA.add(secondaryIndex.get(x));
}
}
/**
* Angepasster Merge-Sort Algorithmus.
* Die Funktion bekommt neben den standard Parametern zusätzlich eine Liste mit Elementen
* die als Groundtruth dienen.
* @param a Eingabefeld mit den Elementen die überprüft werden sollen.
* @param start Startpunkt des Eingabefeldes.
* @param end Endpunkt des Eingabefeldes.
* @param aux Groundtruth Ordnung um die Anzahl der Inversionen zu bestimmen.
* @return Anzahl der inversionen zwischen a und aux.
*/
public int countInversions(List<Integer> a, int start, int end, List<Integer> aux) {
if (start >= end) {
return 0;
}
int invCount = 0;
int mid = start + (end - start) / 2;
int invCountLeft = countInversions(a, start, mid, aux); // divide and conquer
int invCountRight = countInversions(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 {
for (int i=left; i<=mid;i++){
// System.out.println(aux.get(i)+" -- "+ aux.get(right));
inversions.add(new Pair(aux.get(i), aux.get(right)));
}
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;
}
public ArrayList<Pair> getInversionPairs(){
ArrayList<Pair> result = new ArrayList<>();
for (int i=0;i<inversions.size();i++){
result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()), dictionaryBACK.get(inversions.get(i).getP2())));
}
//for (Pair p : result){
// System.out.println(p.getP1() + " <==> " + p.getP2());
//}
return result;
}
}

View File

@ -3,10 +3,15 @@ package Presenter.Algorithms;
import Model.Line; import Model.Line;
import Model.Point; import Model.Point;
import Model.Slab; import Model.Slab;
import Presenter.InversionCounter;
import Presenter.Presenter; import Presenter.Presenter;
import java.util.ArrayList;
import java.util.*; import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Observable; import java.util.Observable;
import java.util.PriorityQueue;
import java.util.Random;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -18,432 +23,440 @@ import java.util.Observable;
public class LeastMedianOfSquaresEstimator extends Observable implements Algorithm { public class LeastMedianOfSquaresEstimator extends Observable implements Algorithm {
private Presenter presenter; private Presenter presenter;
private LinkedList<Line> set = new LinkedList<>(); private LinkedList<Line> set = new LinkedList<>();
private LinkedList<Point> intersections = new LinkedList<>(); private LinkedList<Point> intersections = new LinkedList<>();
private InversionCounter invCounter = new InversionCounter(); private InversionCounter invCounter = new InversionCounter();
private int n; private int n;
private double quantileError; private double quantileError;
private int kPlus; private int kPlus;
private int kMinus; private int kMinus;
private PriorityQueue<Slab> slabs; private PriorityQueue<Slab> slabs;
private Slab subSlabU1; private Slab subSlabU1;
private Slab subSlabU2; private Slab subSlabU2;
private Line sigmaMin; private Line sigmaMin;
private double heightsigmaMin; private double heightsigmaMin;
private Double intersectionsPoint; private Double intersectionsPoint;
private Double constant; private Double constant;
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections, Presenter presenter) { public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections,
this.set = set; Presenter presenter) {
this.intersections = intersections; this.set = set;
this.intersections = intersections;
//(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);.... //(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);....
n = set.size(); n = set.size();
double quantile = 0.5; double quantile = 0.5;
double qPlus = quantile; double qPlus = quantile;
quantileError = 0.1; quantileError = 0.1;
double qMinus = qPlus * (1 - quantileError); double qMinus = qPlus * (1 - quantileError);
kMinus = (int) Math.ceil(n * qMinus); kMinus = (int) Math.ceil(n * qMinus);
kPlus = (int) Math.ceil(n * qPlus); kPlus = (int) Math.ceil(n * qPlus);
this.presenter = presenter; this.presenter = presenter;
} }
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections) { public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections) {
this(set, intersections, null); this(set, intersections, null);
} }
/** /**
* *
*/ */
public void run() { public void run() {
//(2.) Let U <- (-inf, inf) be the initial active slabs...
//(2.) Let U <- (-inf, inf) be the initial active slabs... Comparator<Slab> comparator = new Comparator<Slab>() {
Comparator<Slab> comparator = new Comparator<Slab>() { @Override
@Override public int compare(Slab o1, Slab o2) {
public int compare(Slab o1, Slab o2) { if (o1.getDistance() < o2.getDistance()) {
if (o1.getDistance() < o2.getDistance()) return -1;
return -1;
if (o1.getDistance() > o2.getDistance())
return 1;
else
return 0;
}
};
slabs = new PriorityQueue<>(comparator);
slabs.add(new Slab(-100000, 100000));
heightsigmaMin = Double.MAX_VALUE;
LinkedList<Point> tmpIntersections = intersections;
//(3.) Apply the following steps as long as the exists active slabs
boolean active = true;
Slab slab;
while (!this.slabs.isEmpty()) {
slab = this.slabs.peek();
if (slab.getActivity()){
//(a.) Select any active Slab and calc. the inversions
int numberOfIntersections = countInversions(slab);
//(b.) apply plane sweep
if ((constant * n) >= numberOfIntersections) {
sigmaMin = planeSweep(slab);
} else {
//(c.) otherwise....
// get random intersections point...
Collections.shuffle(tmpIntersections, new Random());
for (int i=0;i<tmpIntersections.size();i++) {
if (tmpIntersections.get(i).getX() > slab.getLower() && tmpIntersections.get(i).getX() < slab.getUpper()) {
intersectionsPoint = tmpIntersections.get(i).getX();
break;
} else {
intersectionsPoint = null;
}
}
if (intersectionsPoint != null){
splitActiveSlab(intersectionsPoint, slab);
//(d.) this may update sigma min
upperBound(intersectionsPoint);
//(e.) for i={1,2}, call lower bound(Ui)
lowerBound(subSlabU1);
lowerBound(subSlabU2);
if (subSlabU1.getActivity()){
this.slabs.add(subSlabU1);
}
if (subSlabU2.getActivity()){
this.slabs.add(subSlabU2);
}
} else {
this.slabs.poll();
}
}
} else {
this.slabs.remove(slab);
}
} }
if (presenter != null){ if (o1.getDistance() > o2.getDistance()) {
setChanged(); return 1;
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * -0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * 0.5;
notifyObservers(new Line(m,b));
}
}
/**
* @param slab
* @return
*/
public int countInversions(Slab slab) {
int numberOfInversions = 0;
// debug
//for (int i=0;i<listA.size();i++){
// System.out.println(listA.get(i)+", "+listB.get(i));
//}
numberOfInversions = invCounter.run(set,slab);
return numberOfInversions;
}
/**
* @param slab
* @return
*/
public Line planeSweep(Slab slab) {
//initialisiere die x-Queue mit den 2D Punkten und sortiere nach x-Lexikographischer Ordnung
ArrayList<Point> 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, kMinus);
if (currentBracelet == null){
continue;
} else if (currentBracelet[0] < heightOfBracelet){
heightOfBracelet = currentBracelet[0];
bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]);
}
}
slab.setActivity(false);
return bracelet;
}
/**
* Diese Methode spaltet den aktiven Slab an der x Koordinate point. Es werden zwei neue Slabs erzeugt.
* @param point x Koordinate an der, der Split geschieht.
*/
public void splitActiveSlab(double point, Slab active) {
subSlabU1 = new Slab(active.getLower()+0.01, point);
subSlabU2 = new Slab(point, active.getUpper());
this.slabs.remove(active);
}
/**
*
* @param point
*/
public void upperBound(double point) {
double height = heightsigmaMin;
double tmpHeight;
ArrayList<Double> sortedLineSequence = getEjValues(point);
int itnbr = ((n - kMinus) + 1);
for (int i = 0; i < itnbr; i++) {
tmpHeight = sortedLineSequence.get((i + kMinus) - 1) - sortedLineSequence.get(i);
if (tmpHeight < height){
height = tmpHeight;
}
if (height < heightsigmaMin) {
heightsigmaMin = height;
if (sigmaMin != null){
sigmaMin.setEndPoints(point, sortedLineSequence.get(i)
,point, sortedLineSequence.get((i + kMinus) - 1));
} else {
sigmaMin = new Line(point, point, sortedLineSequence.get(i), sortedLineSequence.get((i + kMinus) - 1));
}
}
}
}
/**
* @param pslab
* @return
*/
public void lowerBound(Slab pslab) {
int[] alpha = new int[n];
int[] beta = new int[n];
int strictlyGreater = 0;
//Teil I.
ArrayList<Double> umaxList;
ArrayList<Double> uminList;
//y koordinaten der Schnittpunkte
ArrayList<Line> lines = new ArrayList<>();
for (Line p : set) {
lines.add(new Line(pslab.getLower(), pslab.getUpper(),((pslab.getLower() * p.getM()) + p.getB()), ((pslab.getUpper() * p.getM()) + p.getB())));
}
umaxList = getEjValues(pslab.getUpper());
uminList = getEjValues(pslab.getLower());
for (int i = 0; i < n; i++) {
Line level = new Line(pslab.getLower(),pslab.getUpper(),uminList.get(i), umaxList.get(i));
for (Line line : lines) {
if ((line.getY1() < level.getY1()) && (line.getY2() < level.getY2())) {
alpha[i]++;
}
if ((line.getY1() > level.getY1()) && (line.getY2() > level.getY2())) {
strictlyGreater++;
}
}
beta[i] = n - (alpha[i] + strictlyGreater);
strictlyGreater = 0;
}
//TEST der Alpha und Beta werte, siehe JUnit Test
//for (int i=0;i<alpha.length;i++){
// System.out.println("Alpha["+i+"]: "+alpha[i]+"\t Beta["+i+"]: "+beta[i]);
//}
//Test
//Teil II.
int i = 0;
double h;
pslab.setActivity(false);
for (int j = 0; j < n; j++) {
while ((i < n && (Math.abs(beta[i] - alpha[j]) < kPlus))){
i++;
}
//test
//if (i < n)
// System.out.println("i: "+i+", j:"+j+"\t "+Math.abs(beta[i] - alpha[j])+"\t kPlus: "+kPlus);
if (i >= n) {
//System.out.println("i: "+i+", j:"+j+". ungültig");
pslab.setActivity(false);
break;
} else {
h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)), Math.abs(umaxList.get(j) - umaxList.get(i)));
double error = 0.01;
if (((1 + error) * h) < heightsigmaMin) {
//System.out.println("h: "+ h +" ist kleiner als height(sigmaMin): "+heightsigmaMin);
pslab.setActivity(true);
return;
}
}
i = 0;
}
}
/**
* 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<Double> getEjValues(double u) {
ArrayList<Double> ret = new ArrayList<>();
for (Line p : set) {
ret.add((p.getM() * u) + p.getB());
}
Collections.sort(ret);
return ret;
}
/**
* Die Funktion berechnet anhand einer vertikalen Gerade x = px das sogenannte kleinste kMinus Bracelet.
* Mit anderen Worten es wird eine vertikale Teilgerade berechnet die mindestens kMinus Geraden schneidet
* und dabei minimal ist.
* @param px Koordinate um die "vertikale Gerade" zu simulieren.
* @return Das Array enthält höhe des Bracelet, e_j und e_(j + kMinus - 1)
*/
public Double[] calcKMinusBracelet(Point px, int kMinusValue) {
//y Koordinaten für das kMinus brecalet
LinkedList<Double> intersections = new LinkedList<>();
for (Line line : set) {
intersections.add((px.getX() * line.getM())+line.getB());
}
if (intersections.size() >= kMinusValue){
Collections.sort(intersections);
double height = Math.abs(intersections.get(0) - intersections.get(0 + kMinusValue - 1));
Double[] ret = {height, intersections.get(0), intersections.get(0 + kMinusValue - 1)};
return ret;
} else { } else {
return null; return 0;
}
}
};
slabs = new PriorityQueue<>(comparator);
slabs.add(new Slab(-100000, 100000));
heightsigmaMin = Double.MAX_VALUE;
LinkedList<Point> tmpIntersections = intersections;
//(3.) Apply the following steps as long as the exists active slabs
boolean active = true;
Slab slab;
while (!this.slabs.isEmpty()) {
slab = this.slabs.peek();
if (slab.getActivity()) {
//(a.) Select any active Slab and calc. the inversions
int numberOfIntersections = countInversions(slab);
//(b.) apply plane sweep
if ((constant * n) >= numberOfIntersections) {
sigmaMin = planeSweep(slab);
} else {
//(c.) otherwise....
// get random intersections point...
Collections.shuffle(tmpIntersections, new Random());
for (int i = 0; i < tmpIntersections.size(); i++) {
if (tmpIntersections.get(i).getX() > slab.getLower()
&& tmpIntersections.get(i).getX() < slab.getUpper()) {
intersectionsPoint = tmpIntersections.get(i).getX();
break;
} else {
intersectionsPoint = null;
}
}
if (intersectionsPoint != null) {
splitActiveSlab(intersectionsPoint, slab);
//(d.) this may update sigma min
upperBound(intersectionsPoint);
//(e.) for i={1,2}, call lower bound(Ui)
lowerBound(subSlabU1);
lowerBound(subSlabU2);
if (subSlabU1.getActivity()) {
this.slabs.add(subSlabU1);
}
if (subSlabU2.getActivity()) {
this.slabs.add(subSlabU2);
}
} else {
this.slabs.poll();
}
} }
} else {
this.slabs.remove(slab);
}
}
if (presenter != null) {
setChanged();
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * -0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * 0.5;
notifyObservers(new Line(m, b));
}
}
/**
* @param slab
* @return
*/
public int countInversions(Slab slab) {
int numberOfInversions = 0;
// debug
//for (int i=0;i<listA.size();i++){
// System.out.println(listA.get(i)+", "+listB.get(i));
//}
numberOfInversions = invCounter.run(set, slab);
return numberOfInversions;
}
/**
* @param slab
* @return
*/
public Line planeSweep(Slab slab) {
//initialisiere die x-Queue mit den 2D Punkten und sortiere nach x-Lexikographischer Ordnung
ArrayList<Point> 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, kMinus);
if (currentBracelet == null) {
continue;
} else if (currentBracelet[0] < heightOfBracelet) {
heightOfBracelet = currentBracelet[0];
bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]);
}
} }
/** slab.setActivity(false);
* Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den JUnit Testfällen. return bracelet;
*/ }
public LinkedList<Line> getSet() { /**
return set; * Diese Methode spaltet den aktiven Slab an der x Koordinate point. Es werden zwei neue Slabs
* erzeugt.
*
* @param point x Koordinate an der, der Split geschieht.
*/
public void splitActiveSlab(double point, Slab active) {
subSlabU1 = new Slab(active.getLower() + 0.01, point);
subSlabU2 = new Slab(point, active.getUpper());
this.slabs.remove(active);
}
/**
*
* @param point
*/
public void upperBound(double point) {
double height = heightsigmaMin;
double tmpHeight;
ArrayList<Double> sortedLineSequence = getEjValues(point);
int itnbr = ((n - kMinus) + 1);
for (int i = 0; i < itnbr; i++) {
tmpHeight = sortedLineSequence.get((i + kMinus) - 1) - sortedLineSequence.get(i);
if (tmpHeight < height) {
height = tmpHeight;
}
if (height < heightsigmaMin) {
heightsigmaMin = height;
if (sigmaMin != null) {
sigmaMin.setEndPoints(point, sortedLineSequence.get(i)
, point, sortedLineSequence.get((i + kMinus) - 1));
} else {
sigmaMin = new Line(point, point, sortedLineSequence.get(i),
sortedLineSequence.get((i + kMinus) - 1));
}
}
} }
public void setSet(LinkedList<Line> set) { }
this.set = set;
/**
* @param pslab
* @return
*/
public void lowerBound(Slab pslab) {
int[] alpha = new int[n];
int[] beta = new int[n];
int strictlyGreater = 0;
//Teil I.
ArrayList<Double> umaxList;
ArrayList<Double> uminList;
//y koordinaten der Schnittpunkte
ArrayList<Line> lines = new ArrayList<>();
for (Line p : set) {
lines.add(
new Line(pslab.getLower(), pslab.getUpper(), ((pslab.getLower() * p.getM()) + p.getB()),
((pslab.getUpper() * p.getM()) + p.getB())));
} }
public LinkedList<Point> getIntersections() { umaxList = getEjValues(pslab.getUpper());
return intersections; uminList = getEjValues(pslab.getLower());
for (int i = 0; i < n; i++) {
Line level = new Line(pslab.getLower(), pslab.getUpper(), uminList.get(i), umaxList.get(i));
for (Line line : lines) {
if ((line.getY1() < level.getY1()) && (line.getY2() < level.getY2())) {
alpha[i]++;
}
if ((line.getY1() > level.getY1()) && (line.getY2() > level.getY2())) {
strictlyGreater++;
}
}
beta[i] = n - (alpha[i] + strictlyGreater);
strictlyGreater = 0;
}
//TEST der Alpha und Beta werte, siehe JUnit Test
//for (int i=0;i<alpha.length;i++){
// System.out.println("Alpha["+i+"]: "+alpha[i]+"\t Beta["+i+"]: "+beta[i]);
//}
//Test
//Teil II.
int i = 0;
double h;
pslab.setActivity(false);
for (int j = 0; j < n; j++) {
while ((i < n && (Math.abs(beta[i] - alpha[j]) < kPlus))) {
i++;
}
//test
//if (i < n)
// System.out.println("i: "+i+", j:"+j+"\t "+Math.abs(beta[i] - alpha[j])+"\t kPlus: "+kPlus);
if (i >= n) {
//System.out.println("i: "+i+", j:"+j+". ungültig");
pslab.setActivity(false);
break;
} else {
h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)),
Math.abs(umaxList.get(j) - umaxList.get(i)));
double error = 0.01;
if (((1 + error) * h) < heightsigmaMin) {
//System.out.println("h: "+ h +" ist kleiner als height(sigmaMin): "+heightsigmaMin);
pslab.setActivity(true);
return;
}
}
i = 0;
} }
public void setIntersections(LinkedList<Point> intersections) { }
this.intersections = intersections;
/**
* 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<Double> getEjValues(double u) {
ArrayList<Double> ret = new ArrayList<>();
for (Line p : set) {
ret.add((p.getM() * u) + p.getB());
} }
public int getN() { Collections.sort(ret);
return n;
return ret;
}
/**
* Die Funktion berechnet anhand einer vertikalen Gerade x = px das sogenannte kleinste kMinus
* Bracelet. Mit anderen Worten es wird eine vertikale Teilgerade berechnet die mindestens kMinus
* Geraden schneidet und dabei minimal ist.
*
* @param px Koordinate um die "vertikale Gerade" zu simulieren.
* @return Das Array enthält höhe des Bracelet, e_j und e_(j + kMinus - 1)
*/
public Double[] calcKMinusBracelet(Point px, int kMinusValue) {
//y Koordinaten für das kMinus brecalet
LinkedList<Double> intersections = new LinkedList<>();
for (Line line : set) {
intersections.add((px.getX() * line.getM()) + line.getB());
}
if (intersections.size() >= kMinusValue) {
Collections.sort(intersections);
double height = Math.abs(intersections.get(0) - intersections.get(0 + kMinusValue - 1));
Double[] ret = {height, intersections.get(0), intersections.get(0 + kMinusValue - 1)};
return ret;
} else {
return null;
} }
public void setN(int n) { }
this.n = n;
}
public double getQuantileError() { /**
return quantileError; * Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den
} * JUnit Testfällen.
*/
public void setQuantileError(double quantileError) { public LinkedList<Line> getSet() {
this.quantileError = quantileError; return set;
} }
public int getkPlus() { public void setSet(LinkedList<Line> set) {
return kPlus; this.set = set;
} }
public void setkPlus(int kPlus) { public LinkedList<Point> getIntersections() {
this.kPlus = kPlus; return intersections;
} }
public int getkMinus() { public void setIntersections(LinkedList<Point> intersections) {
return kMinus; this.intersections = intersections;
} }
public void setkMinus(int kMinus) { public int getN() {
this.kMinus = kMinus; return n;
} }
public Slab getSubSlabU1() { public void setN(int n) {
return subSlabU1; this.n = n;
} }
public void setSubSlabU1(Slab subSlabU1) { public double getQuantileError() {
this.subSlabU1 = subSlabU1; return quantileError;
} }
public Slab getSubSlabU2() { public void setQuantileError(double quantileError) {
return subSlabU2; this.quantileError = quantileError;
} }
public void setSubSlabU2(Slab subSlabU2) { public int getkPlus() {
this.subSlabU2 = subSlabU2; return kPlus;
} }
public Line getSigmaMin() { public void setkPlus(int kPlus) {
return sigmaMin; this.kPlus = kPlus;
} }
public void setSigmaMin(Line sigmaMin) { public int getkMinus() {
this.sigmaMin = sigmaMin; return kMinus;
} }
public double getHeightsigmaMin() { public void setkMinus(int kMinus) {
return heightsigmaMin; this.kMinus = kMinus;
} }
public void setHeightsigmaMin(double heightsigmaMin) { public Slab getSubSlabU1() {
this.heightsigmaMin = heightsigmaMin; return subSlabU1;
} }
public double getIntersectionsPoint() { public void setSubSlabU1(Slab subSlabU1) {
return intersectionsPoint; this.subSlabU1 = subSlabU1;
} }
public void setIntersectionsPoint(double intersectionsPoint) { public Slab getSubSlabU2() {
this.intersectionsPoint = intersectionsPoint; return subSlabU2;
} }
public Double getConstant() { public void setSubSlabU2(Slab subSlabU2) {
return constant; this.subSlabU2 = subSlabU2;
} }
public void setConstant(Double constant) { public Line getSigmaMin() {
this.constant = constant; return sigmaMin;
} }
public void setSigmaMin(Line sigmaMin) {
this.sigmaMin = sigmaMin;
}
public double getHeightsigmaMin() {
return heightsigmaMin;
}
public void setHeightsigmaMin(double heightsigmaMin) {
this.heightsigmaMin = heightsigmaMin;
}
public double getIntersectionsPoint() {
return intersectionsPoint;
}
public void setIntersectionsPoint(double intersectionsPoint) {
this.intersectionsPoint = intersectionsPoint;
}
public Double getConstant() {
return constant;
}
public void setConstant(Double constant) {
this.constant = constant;
}
} }

View File

@ -1,13 +1,14 @@
package Presenter.Algorithms; package Presenter.Algorithms;
import Model.Line; import Model.Line;
import Model.Pair;
import Model.Slab; import Model.Slab;
import Presenter.InversionCounter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -18,127 +19,225 @@ import java.util.Random;
*/ */
public class RepeatedMedianEstimator implements Algorithm { public class RepeatedMedianEstimator implements Algorithm {
private LinkedList<Line> set; private LinkedList<Line> set;
private Slab interval; private HashMap<Line, ArrayList<Line>> linePairs;
private InversionCounter invCounter = new InversionCounter(); private Slab interval;
//in der Literatur als L_i, C_i, und R_i bekannt //in der Literatur als L_i, C_i, und R_i bekannt
private Integer countLeftSlab; private ArrayList<Integer> countLeftSlab;
private Integer countCenterSlab; private ArrayList<Integer> countCenterSlab;
private Integer countRightSlab; private ArrayList<Integer> countRightSlab;
//die Mengen L,C und R //die Mengen L,C und R
private ArrayList<Line> linesInLeftSlab; private ArrayList<Line> linesInLeftSlab;
private ArrayList<Line> linesInCenterSlab; private ArrayList<Line> linesInCenterSlab;
private ArrayList<Line> linesInRightSlab; private ArrayList<Line> linesInRightSlab;
private Double r; private Double r;
private Integer n; private Integer n;
private Double k; private Double k;
private Double kLow; private Double kLow;
private Double kHigh; private Double kHigh;
private Double beta; private Double beta;
private Line thetaLow; private Double thetaLow;
private Line thetaHigh; private Double thetaHigh;
public RepeatedMedianEstimator(LinkedList<Line> set) {
this.set = set;
interval = new Slab(-10000, 10000);
n = set.size();
beta = 0.5;
countLeftSlab = new ArrayList<>();
countCenterSlab = new ArrayList<>();
countRightSlab = new ArrayList<>();
public RepeatedMedianEstimator(LinkedList<Line> set) { for (int i = 0; i < n; i++) {
this.set = set; countLeftSlab.add(0);
interval = new Slab(-10000,10000); countRightSlab.add(0);
n = set.size(); countCenterSlab.add(n - 1);
beta = 1.0;
countLeftSlab = 0;
countCenterSlab = n - 1;
countRightSlab = 0;
linesInLeftSlab = new ArrayList<>();
linesInCenterSlab = new ArrayList<>(set);
linesInRightSlab = new ArrayList<>();
} }
linesInLeftSlab = new ArrayList<>();
public void run(){ linesInCenterSlab = new ArrayList<>(set);
while (linesInCenterSlab.size() != 1){ linesInRightSlab = new ArrayList<>();
r = Math.floor(Math.pow(n, beta)); linePairs = new HashMap<>();
ArrayList<Line> lines = sampleLines(linesInCenterSlab, r); }
//TODO: hier kommt der neue Ansatz vom zweiten Algorithmus hin
estimateMedianIntersectionAbscissas(lines);
k = (Math.floor(n * 0.5) - linesInLeftSlab.size());
computeSlabBorders();
thetaLow = randomizedSelect(linesInCenterSlab,0,linesInCenterSlab.size()-1,kLow);
thetaHigh = randomizedSelect(linesInCenterSlab,0,linesInCenterSlab.size()-1,kHigh);
countNumberOfIntersectionsAbscissas();
}
}
public void run() {
while (linesInCenterSlab.size() != 1) {
r = Math.floor(Math.pow(n, beta));
ArrayList<Line> lines = sampleLines(linesInCenterSlab, r);
public void computeSlabBorders(){ InversionCounter invCounter = new InversionCounter();
kLow = Math.max(1, Math.ceil(((r * k)/(linesInCenterSlab.size()))-((3 * Math.sqrt(r))/(2)))); invCounter.run(lines, interval);
kHigh = Math.min(1, Math.ceil(((r * k)/(linesInCenterSlab.size()))+((3 * Math.sqrt(r))/(2))));
}
public ArrayList<Line> sampleLines(ArrayList<Line> set, Double r){ HashMap<Line, ArrayList<Line>> tmpMap;
tmpMap = invCounter.getIntersectionAbscissas();
ArrayList<Line> sampledLines = new ArrayList<>(); linePairs.putAll(tmpMap);
if (tmpMap.size() > 0){
Random random = new Random(n); ArrayList<Double> medianIntersections = new ArrayList<>();
for (int i=0; i<n; i++){ for (Line l : lines) {
sampledLines.add(set.get(random.nextInt())); medianIntersections.add(estimateMedianIntersectionAbscissas(l));
} }
return sampledLines; k = (Math.floor(n * 0.5) - linesInLeftSlab.size());
} computeSlabBorders();
thetaLow = randomizedSelect(medianIntersections, 0, medianIntersections.size() - 1, kLow);
thetaHigh = randomizedSelect(medianIntersections, 0, medianIntersections.size() - 1, kHigh);
public Line randomizedSelect(ArrayList<Line> a, int start, int end, double i){ for (Line l : linesInCenterSlab) {
if (start == end) countNumberOfIntersectionsAbscissas(l);
return a.get(start);
int q = randomizedPartition(a, start, end);
int tmpPivot = q - start + 1;
if ( i == tmpPivot ){
return a.get(q);
} else if ( i < tmpPivot ) {
return randomizedSelect(a, start, q-1, i);
} else {
return randomizedSelect(a, q+1, end, i-tmpPivot);
} }
contractIntervals();
}
} }
public int randomizedPartition(ArrayList<Line> a, int start, int end){ System.out.println(
int delta = Math.abs(end - start); "Ergebnis: " + linesInCenterSlab.get(0).getM() + " * x + " + linesInCenterSlab.get(0)
Random random = new Random(delta); .getB());
int i = start + random.nextInt(); }
Collections.swap(a, end, i);
return partition(a, start, end);
public void computeSlabBorders() {
kLow = Math
.max(1, Math.ceil(((r * k) / (linesInCenterSlab.size())) - ((3 * Math.sqrt(r)) / (2))));
kHigh = Math
.min(r, Math.ceil(((r * k) / (linesInCenterSlab.size())) + ((3 * Math.sqrt(r)) / (2))));
}
public ArrayList<Line> sampleLines(ArrayList<Line> set, Double r) {
ArrayList<Line> sampledLines = new ArrayList<>();
for (int i = 0; i < r; i++) {
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, n)));
} }
public int partition(ArrayList<Line> a, int start, int end){ return sampledLines;
Line x = a.get(end); }
int i = start - 1;
for (int j=start; j<end; j++){
if (a.get(j).getM() <= x.getM()){ public Double randomizedSelect(ArrayList<Double> a, int start, int end, double i) {
i++; if (start == end) {
Collections.swap(a, i, j); return a.get(start);
} }
int q = randomizedPartition(a, start, end);
int tmpPivot = q - start + 1;
if (i == tmpPivot) {
return a.get(q);
} else if (i < tmpPivot) {
return randomizedSelect(a, start, q - 1, i);
} else {
return randomizedSelect(a, q + 1, end, i - tmpPivot);
}
}
public int randomizedPartition(ArrayList<Double> a, int start, int end) {
int delta = Math.abs(end - start);
int i = start + ThreadLocalRandom.current().nextInt(0, delta);
Collections.swap(a, end, i);
return partition(a, start, end);
}
public int partition(ArrayList<Double> a, int start, int end) {
Double x = a.get(end);
int i = start - 1;
for (int j = start; j < end; j++) {
if (a.get(j) <= x) {
i++;
Collections.swap(a, i, j);
}
}
Collections.swap(a, i + 1, end);
return i + 1;
}
public void countNumberOfIntersectionsAbscissas(Line sampledLine) {
if (linePairs.get(sampledLine) != null){
double intersection;
Integer index = Integer.parseInt(sampledLine.getId());
for (Line line : linePairs.get(sampledLine)) {
intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
int tmpVal;
if (intersection <= thetaLow) {
tmpVal = countLeftSlab.get(index) + 1;
countLeftSlab.set(index, tmpVal);
tmpVal = countCenterSlab.get(index) - 1;
countCenterSlab.set(index, tmpVal);
} else if (intersection > thetaHigh) {
tmpVal = countRightSlab.get(index) + 1;
countRightSlab.set(index, tmpVal);
tmpVal = countCenterSlab.get(index) - 1;
countCenterSlab.set(index, tmpVal);
} }
Collections.swap(a, i+1, end);
return i+1;
}
public void countNumberOfIntersectionsAbscissas(){ countCenterSlab
.set(index, Math.abs((n - 1) - (countLeftSlab.get(index) + countRightSlab.get(index))));
}
}
}
public Double estimateMedianIntersectionAbscissas(Line sampledLine) {
Integer index = Integer.parseInt(sampledLine.getId());
ArrayList<Double> intersections = new ArrayList<>();
double intersection;
for (Line line : linePairs.get(sampledLine)) {
if (line != sampledLine){
intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
intersections.add(intersection);
}
}
Collections.sort(intersections);
double ki = Math.floor((n - 1) / 2) - countLeftSlab.get(index);
int accessIndex = ((int) Math.floor((Math.sqrt(n) * ki) / countCenterSlab.get(index)))-1;
System.out.println(accessIndex);
return intersections.get(accessIndex);
}
public void contractIntervals() {
if (linesInLeftSlab.size() < Math.floor(n / 2) && Math.floor(n / 2) <= (linesInLeftSlab.size()
+ linesInCenterSlab.size())) {
for (int i = 0; i < linesInCenterSlab.size(); i++) {
int maxVal = Math
.max(countLeftSlab.get(i), Math.max(countCenterSlab.get(i), countRightSlab.get(i)));
if (countLeftSlab.get(i) == maxVal) {
linesInLeftSlab.add(linesInCenterSlab.get(i));
linesInCenterSlab.remove(i);
}
if (countRightSlab.get(i) == maxVal) {
linesInRightSlab.add(linesInCenterSlab.get(i));
linesInCenterSlab.remove(i);
}
}
for (int i = 0; i < n; i++) {
countLeftSlab.set(i,0);
countRightSlab.set(i,0);
countCenterSlab.set(i,n - 1);
}
interval.setLower(thetaLow - 0.01);
interval.setUpper(thetaHigh);
} }
}
public void estimateMedianIntersectionAbscissas(ArrayList<Line> sampledLines){
int inversions = invCounter.run(sampledLines, interval);
}
} }

View File

@ -8,4 +8,5 @@ package Presenter.Algorithms;
* @Date: 28.05.2017. * @Date: 28.05.2017.
*/ */
public class TheilSenEstimator implements Algorithm { public class TheilSenEstimator implements Algorithm {
} }

View File

@ -0,0 +1,29 @@
package Presenter.Comparators;
import Model.Line;
import java.util.Comparator;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 19.06.2017.
*/
public class YOrderLineComparatorBegin implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
if (o1.getY1() == o2.getY1()) {
if (o1.getX1() <= o2.getX1()) {
return -1;
} else {
return 1;
}
} else if (o1.getY1() < o2.getY1()) {
return -1;
} else {
return 1;
}
}
}

View File

@ -0,0 +1,29 @@
package Presenter.Comparators;
import Model.Line;
import java.util.Comparator;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 19.06.2017.
*/
public class YOrderLineComparatorEnd implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
if (o1.getY2() == o2.getY2()) {
if (o1.getX2() <= o2.getX2()) {
return -1;
} else {
return 1;
}
} else if (o1.getY2() < o2.getY2()) {
return -1;
} else {
return 1;
}
}
}

View File

@ -0,0 +1,195 @@
package Presenter;
import Model.Line;
import Model.Pair;
import Model.Slab;
import Presenter.Comparators.YOrderLineComparatorBegin;
import Presenter.Comparators.YOrderLineComparatorEnd;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 18.06.2017.
*/
public class InversionCounter {
private HashMap<Integer, Integer> dictionaryTO;
private HashMap<Integer, Integer> dictionaryBACK;
private ArrayList<Integer> substituted;
private ArrayList<Pair> inversions;
private List<Line> set;
//indexieren der Punkte damit die schnittpunkte berechnet werden können
private HashMap<Line, Integer> secondaryDictionaryTO;
private HashMap<Integer, Line> secondaryDictionaryBACK;
private ArrayList<Line> umin;
public int run(List<Integer> a, List<Integer> b) {
dictionaryTO = new HashMap<>();
dictionaryBACK = new HashMap<>();
substituted = new ArrayList<>();
inversions = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
temp.addAll(a);
for (int i = 0; i < a.size(); i++) {
dictionaryTO.put(a.get(i), i + 1);
dictionaryBACK.put(i + 1, a.get(i));
}
for (int j = 0; j < b.size(); j++) {
substituted.add(dictionaryTO.get(b.get(j)));
}
int ret = countInversions(substituted, 0, substituted.size() - 1, temp);
getIntersectionAbscissas();
return ret;
}
public int run(List<Line> set, Slab slab) {
ArrayList<Integer> listA = new ArrayList<>();
ArrayList<Integer> listB = new ArrayList<>();
prepareData(set, slab, listA, listB);
return run(listA, listB);
}
private void prepareData(List<Line> set, Slab slab, ArrayList<Integer> listA,
ArrayList<Integer> listB) {
secondaryDictionaryTO = new HashMap<>();
secondaryDictionaryBACK = new HashMap<>();
this.set = set;
umin = new ArrayList<>();
Line tmpLine;
for (Line p : set) {
//vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet
tmpLine = new Line(p.getM(), p.getM(), slab.getLower() * p.getM() + p.getB(),
slab.getUpper() * p.getM() + p.getB());
//wird benötigt um späer die Schnittpunkte ermitteln zu können
tmpLine.setB(p.getB());
tmpLine.setM(p.getM());
umin.add(tmpLine);
}
for (int i = 0; i < umin.size(); i++) {
secondaryDictionaryTO.put(umin.get(i), i);
secondaryDictionaryBACK.put(i, this.set.get(i));
}
Collections.sort(umin, new YOrderLineComparatorBegin());
for (Line q : umin) {
listA.add(secondaryDictionaryTO.get(q));
}
Collections.sort(umin, new YOrderLineComparatorEnd());
for (Line q : umin) {
listB.add(secondaryDictionaryTO.get(q));
}
}
/**
* Angepasster Merge-Sort Algorithmus.
* Die Funktion bekommt neben den standard Parametern zusätzlich eine Liste mit Elementen
* die als Groundtruth dienen.
*
* @param a Eingabefeld mit den Elementen die überprüft werden sollen.
* @param start Startpunkt des Eingabefeldes.
* @param end Endpunkt des Eingabefeldes.
* @param aux Groundtruth Ordnung um die Anzahl der Inversionen zu bestimmen.
* @return Anzahl der inversionen zwischen a und aux.
*/
public int countInversions(List<Integer> a, int start, int end, List<Integer> aux) {
if (start >= end) {
return 0;
}
int invCount = 0;
int mid = start + (end - start) / 2;
int invCountLeft = countInversions(a, start, mid, aux); // divide and conquer
int invCountRight = countInversions(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 {
for (int i = left; i <= mid; i++) {
// System.out.println(aux.get(i)+" -- "+ aux.get(right));
inversions.add(new Pair(aux.get(i), aux.get(right)));
}
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;
}
public HashMap<Line, ArrayList<Line>> getIntersectionAbscissas() {
ArrayList<Pair> result = new ArrayList<>();
HashMap<Line, ArrayList<Line>> ret = new HashMap<>();
for (int i = 0; i < inversions.size(); i++) {
result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()),
dictionaryBACK.get(inversions.get(i).getP2())));
}
ArrayList<Line> linePairs;
for (Pair p : result) {
Line l1 = secondaryDictionaryBACK.get(p.getP1());
Line l2 = secondaryDictionaryBACK.get(p.getP2());
if (ret.get(l2) == null){
linePairs = new ArrayList<>();
} else {
linePairs = ret.get(l2);
}
linePairs.add(l1);
ret.put(l2, linePairs);
//Symetrie
if (ret.get(l1) == null){
linePairs = new ArrayList<>();
} else {
linePairs = ret.get(l1);
}
linePairs.add(l2);
ret.put(l1, linePairs);
}
// System.out.println("----------------------------------------------------------");
// for (Line outerLine : ret.keySet()){
// System.out.println("Linie: "+outerLine);
// for (Line innerLine : ret.get(outerLine)){
// System.out.println("\t\t -> "+innerLine);
// }
// }
// System.out.println("----------------------------------------------------------");
return ret;
}
}

View File

@ -4,13 +4,13 @@ import Model.Arrangement;
import Model.Line; import Model.Line;
import Model.Point; import Model.Point;
import Presenter.Algorithms.LeastMedianOfSquaresEstimator; import Presenter.Algorithms.LeastMedianOfSquaresEstimator;
import Presenter.Algorithms.RepeatedMedianEstimator;
import View.MainFrame; import View.MainFrame;
import javax.swing.*;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import javax.swing.SwingUtilities;
/** /**
@ -22,166 +22,172 @@ import java.util.Observer;
*/ */
public class Presenter implements Observer { public class Presenter implements Observer {
private Arrangement model; private Arrangement model;
private MainFrame view; private MainFrame view;
private LeastMedianOfSquaresEstimator lms; private LeastMedianOfSquaresEstimator lms;
private Double max; private Double max;
private Double min; private Double min;
public Presenter(Arrangement model, MainFrame view) { public Presenter(Arrangement model, MainFrame view) {
this.model = model; this.model = model;
this.view = view; this.view = view;
// Double[] x = {1d, 2d, 3d, 4d, 10d, 12d, 18d}; // Double[] x = {1d, 2d, 3d, 4d, 10d, 12d, 18d};
// Double[] y = {9d, 15d, 19d, 20d, 45d, 55d, 78d}; // Double[] y = {9d, 15d, 19d, 20d, 45d, 55d, 78d};
Double[] x = {18d,24d,30d,34d,38d}; Double[] x = {18d, 24d, 30d, 34d, 38d};
Double[] y = {18d,26d,30d,40d,70d}; Double[] y = {18d, 26d, 30d, 40d, 70d};
// Double[] x = {1d,3d,4d,5d,8d}; // Double[] x = {1d,3d,4d,5d,8d};
// Double[] y = {4d,2d,1d,0d,0d}; // Double[] y = {4d,2d,1d,0d,0d};
view.logHeading("Duale Darstellung der Punkte als Geraden:"); view.logHeading("Duale Darstellung der Punkte als Geraden:");
for (int j = 0; j < x.length; j++) { for (int j = 0; j < x.length; j++) {
Line p = new Line(x[j], y[j]); Line p = new Line(x[j], y[j]);
view.log("f(x) = " + p.getM() + "x + " + p.getB()); p.setId(j+"");
this.model.addLine(p); view.log("f(x) = " + p.getM() + "x + " + p.getB());
this.model.addLine(p);
}
calcArrangementNodes();
//print
List<String> heading = new LinkedList<>();
List<List<String>> rows = new LinkedList<>();
heading.add("X - Koordinate");
heading.add("Y - Koordinate");
for (Point p : model.getNodes()) {
LinkedList<String> rowEntry = new LinkedList<>();
rowEntry.add(p.getX().toString());
rowEntry.add(p.getY().toString());
rows.add(rowEntry);
}
view.logHeading("Schnittpunkte der Dualen Geraden:");
view.createTable(heading, rows);
Thread t = new Thread(() -> {
RepeatedMedianEstimator rm = new RepeatedMedianEstimator(this.getLines());
rm.run();
});
t.start();
}
@Override
public void update(Observable o, Object arg) {
Line result = ((Line) arg);
SwingUtilities.invokeLater(() -> {
getView().createPlot(result.getM(), result.getB());
getView().setLmsIsComplete(true);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt");
getView().log("m: " + result.getM() + "\t b: " + result.getB());
});
}
public void startArrangementVisualization() {
view.createArrangement();
}
public void startScatterPlotVisualization(String[] input) {
Double constant = Double.parseDouble(input[0]);
Double error = Double.parseDouble(input[1]);
lms = new LeastMedianOfSquaresEstimator(model.getLines(), model.getNodes(), this);
lms.setConstant(constant);
lms.setQuantileError(error);
lms.addObserver(this);
lms.run();
}
public Point calcIntersection(Line a, Line b) {
Line p1 = a;
Line p2 = b;
Double x = (p1.getB() - p2.getB()) / (p2.getM() - p1.getM());
Double y = ((p1.getM() * p2.getB()) - (p2.getM() * p1.getB())) / (p1.getM() - p2.getM());
return new Point(x, y);
}
public void calcArrangementNodes() {
try {
Thread thread = new Thread(() -> {
for (int i = 0; i < getLines().size(); i++) {
for (int j = i; j < getLines().size(); j++) {
if (i != j) {
model.addNode(calcIntersection(getLines().get(j), getLines().get(i)));
}
}
} }
});
calcArrangementNodes(); thread.start();
//print thread.join();
List<String> heading = new LinkedList<>(); } catch (InterruptedException e) {
List<List<String>> rows = new LinkedList<>(); e.printStackTrace();
heading.add("X - Koordinate");
heading.add("Y - Koordinate");
for (Point p : model.getNodes()) {
LinkedList<String> rowEntry = new LinkedList<>();
rowEntry.add(p.getX().toString());
rowEntry.add(p.getY().toString());
rows.add(rowEntry);
}
view.logHeading("Schnittpunkte der Dualen Geraden:");
view.createTable(heading, rows);
} }
}
@Override public LinkedList<LinkedList<Point>> calcArrangementLines() {
public void update(Observable o, Object arg) { LinkedList<LinkedList<Point>> lineCoordinates = new LinkedList<>();
Line result = ((Line) arg); double x1 = -1000;
SwingUtilities.invokeLater(()->{ double x2 = 1000;
getView().createPlot(result.getM(), result.getB());
getView().setLmsIsComplete(true);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt");
getView().log("m: "+result.getM()+"\t b: "+result.getB());
});
for (Line point : model.getLines()) {
LinkedList line = new LinkedList();
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);
} }
return lineCoordinates;
}
public void startArrangementVisualization() { /***************************************************************************************************************************
view.createArrangement(); * Getter und Setter Methoden
} ***************************************************************************************************************************/
public void startScatterPlotVisualization(String[] input) {
Double constant = Double.parseDouble(input[0]);
Double error = Double.parseDouble(input[1]);
lms = new LeastMedianOfSquaresEstimator(model.getLines(), model.getNodes(), this);
lms.setConstant(constant);
lms.setQuantileError(error);
lms.addObserver(this);
lms.run();
}
public Point calcIntersection(Line a, Line b) { public Arrangement getModel() {
Line p1 = a; return model;
Line p2 = b; }
Double x = (p1.getB() - p2.getB()) / (p2.getM() - p1.getM()); public void setModel(Arrangement model) {
Double y = ((p1.getM() * p2.getB()) - (p2.getM() * p1.getB())) / (p1.getM() - p2.getM()); this.model = model;
}
return new Point(x, y); public MainFrame getView() {
} return view;
}
public void calcArrangementNodes() { public void setView(MainFrame view) {
try { this.view = view;
Thread thread = new Thread(() -> { }
for (int i = 0; i < getLines().size(); i++) {
for (int j = i; j < getLines().size(); j++) {
if (i != j){
model.addNode(calcIntersection(getLines().get(j), getLines().get(i)));
}
}
}
});
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} public LinkedList<Line> getLines() {
return this.model.getLines();
}
public LinkedList<LinkedList<Point>> calcArrangementLines(){ public void setLines(LinkedList<Line> lines) {
LinkedList<LinkedList<Point>> lineCoordinates = new LinkedList<>(); this.model.setLines(lines);
double x1 = -1000; }
double x2 = 1000;
public Double getMax() {
return max;
}
for (Line point : model.getLines()) { public void setMax(Double max) {
LinkedList line = new LinkedList(); this.max = max;
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);
}
return lineCoordinates; public Double getMin() {
} return min;
/*************************************************************************************************************************** }
* Getter und Setter Methoden
***************************************************************************************************************************/
public void setMin(Double min) {
public Arrangement getModel() { this.min = min;
return model; }
}
public void setModel(Arrangement model) {
this.model = model;
}
public MainFrame getView() {
return view;
}
public void setView(MainFrame view) {
this.view = view;
}
public LinkedList<Line> getLines() {
return this.model.getLines();
}
public void setLines(LinkedList<Line> lines) {
this.model.setLines(lines);
}
public Double getMax() {
return max;
}
public void setMax(Double max) {
this.max = max;
}
public Double getMin() {
return min;
}
public void setMin(Double min) {
this.min = min;
}
} }

View File

@ -1,7 +1,15 @@
package View; package View;
import Model.Line;
import Model.Point; import Model.Point;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.util.LinkedList;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel; import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart; import org.jfree.chart.JFreeChart;
@ -13,12 +21,6 @@ import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection; import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities; import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.LinkedList;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -28,123 +30,122 @@ import java.util.LinkedList;
*/ */
public class ArrangementDialog extends JPanel { public class ArrangementDialog extends JPanel {
private LinkedList<LinkedList<Point>> lines; private LinkedList<LinkedList<Point>> lines;
private LinkedList<Point> points; private LinkedList<Point> points;
private double max; private double max;
private double min; private double min;
private JFreeChart chart; private JFreeChart chart;
private ChartPanel panel; private ChartPanel panel;
private JSlider hslider; private JSlider hslider;
private JSlider vslider; private JSlider vslider;
private double domainMin, domainMax; private double domainMin, domainMax;
private double rangeMin, rangeMax; private double rangeMin, rangeMax;
private ValueAxis domain; private ValueAxis domain;
private ValueAxis range; private ValueAxis range;
public ArrangementDialog() { public ArrangementDialog() {
super(); super();
this.setPreferredSize(new Dimension(800, 800)); this.setPreferredSize(new Dimension(800, 800));
this.setMinimumSize(new Dimension(800, 800)); this.setMinimumSize(new Dimension(800, 800));
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
this.vslider = new JSlider(SwingConstants.VERTICAL,1,100,50); this.vslider = new JSlider(SwingConstants.VERTICAL, 1, 100, 50);
this.hslider = new JSlider(SwingConstants.HORIZONTAL,10,1000,500); this.hslider = new JSlider(SwingConstants.HORIZONTAL, 10, 1000, 500);
}
public void setPrameters(LinkedList<LinkedList<Point>> lines, LinkedList<Point> points) {
this.lines = lines;
this.points = points;
this.domainMin = Double.MAX_VALUE;
this.domainMax = Double.MIN_VALUE;
this.rangeMin = Double.MAX_VALUE;
this.rangeMax = Double.MIN_VALUE;
}
public void createArrangement() {
XYSeriesCollection dataset = new XYSeriesCollection();
for (LinkedList<Point> p : lines) {
XYSeries series = new XYSeries(p.get(0).getX() + p.get(0).getY());
series.add(p.get(0).getX(), p.get(0).getY());
series.add(p.get(1).getX(), p.get(1).getY());
dataset.addSeries(series);
} }
public void setPrameters(LinkedList<LinkedList<Point>> lines, LinkedList<Point> points) { XYSeries intersections = new XYSeries("intersections");
this.lines = lines; for (Point p : points) {
this.points = points; domainMax = domainMax < p.getX() ? p.getX() : domainMax;
this.domainMin = Double.MAX_VALUE; domainMin = domainMin > p.getX() ? p.getX() : domainMin;
this.domainMax = Double.MIN_VALUE; rangeMax = rangeMax < p.getY() ? p.getY() : rangeMax;
this.rangeMin = Double.MAX_VALUE; rangeMin = rangeMin > p.getY() ? p.getY() : rangeMin;
this.rangeMax = Double.MIN_VALUE; intersections.add(p.getX(), p.getY());
}
dataset.addSeries(intersections);
chart = ChartFactory.createXYLineChart(
null, null, null, dataset,
PlotOrientation.HORIZONTAL, false, false, false);
chart.setRenderingHints(
new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
chart.setAntiAlias(true);
final XYPlot plot = chart.getXYPlot();
domain = plot.getDomainAxis();
range = plot.getRangeAxis();
domain.setRange(domainMin - 1, domainMax + 1);
range.setRange(rangeMin - 1, rangeMax + 1);
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false);
plot.setRenderer(renderer);
for (int i = 0; i < lines.size(); i++) {
// Setze die Shapes für die Schnittpunkte
renderer.setSeriesPaint(i, Color.BLUE);
renderer.setBaseSeriesVisible(true);
} }
public void createArrangement() { Shape shape = ShapeUtilities.createDiagonalCross(4, 1);
XYSeriesCollection dataset = new XYSeriesCollection(); renderer.setSeriesPaint(lines.size(), Color.BLACK);
renderer.setSeriesShape(lines.size(), shape);
for (LinkedList<Point> p : lines) { panel = new ChartPanel(chart);
XYSeries series = new XYSeries(p.get(0).getX() + p.get(0).getY()); panel.setPreferredSize(new Dimension(800, 800));
series.add(p.get(0).getX(), p.get(0).getY());
series.add(p.get(1).getX(), p.get(1).getY());
dataset.addSeries(series);
}
XYSeries intersections = new XYSeries("intersections"); addListener();
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;
rangeMin = rangeMin > p.getY() ? p.getY() : rangeMin;
intersections.add(p.getX(), p.getY());
}
dataset.addSeries(intersections);
chart = ChartFactory.createXYLineChart( this.add(panel, BorderLayout.CENTER);
null, null, null, dataset, this.add(hslider, BorderLayout.SOUTH);
PlotOrientation.HORIZONTAL, false, false, false); this.add(vslider, BorderLayout.EAST);
chart.setRenderingHints( new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ) ); }
chart.setAntiAlias(true);
final XYPlot plot = chart.getXYPlot(); private void addListener() {
this.vslider.addChangeListener(e -> {
JSlider slider = (JSlider) e.getSource();
double delta = Math.abs(slider.getValue() - 50) * 0.1;
if (slider.getValue() < 50) {
domain.setRange(domainMin - delta, domainMax - delta);
} else {
domain.setRange(domainMin + delta, domainMax + delta);
}
});
domain = plot.getDomainAxis(); this.hslider.addChangeListener(e -> {
range = plot.getRangeAxis(); JSlider slider = (JSlider) e.getSource();
double delta = Math.abs(slider.getValue() - 500);
domain.setRange(domainMin - 1, domainMax + 1); if (slider.getValue() < 500) {
range.setRange(rangeMin - 1, rangeMax + 1); range.setRange(rangeMin - delta, rangeMax - delta);
plot.setBackgroundPaint(Color.WHITE); } else {
plot.setDomainGridlinePaint(Color.white); range.setRange(rangeMin + delta, rangeMax + delta);
plot.setRangeGridlinePaint(Color.white); }
});
}
final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false);
plot.setRenderer(renderer);
for (int i=0;i<lines.size();i++){
// Setze die Shapes für die Schnittpunkte
renderer.setSeriesPaint(i, Color.BLUE);
renderer.setBaseSeriesVisible(true);
}
Shape shape = ShapeUtilities.createDiagonalCross(4,1);
renderer.setSeriesPaint(lines.size(), Color.BLACK);
renderer.setSeriesShape(lines.size(), shape);
panel = new ChartPanel(chart);
panel.setPreferredSize(new Dimension(800, 800));
addListener();
this.add(panel, BorderLayout.CENTER);
this.add(hslider, BorderLayout.SOUTH);
this.add(vslider, BorderLayout.EAST);
}
private void addListener(){
this.vslider.addChangeListener(e -> {
JSlider slider = (JSlider) e.getSource();
double delta = Math.abs(slider.getValue() - 50) * 0.1;
if (slider.getValue() < 50){
domain.setRange(domainMin - delta, domainMax - delta);
} else {
domain.setRange(domainMin + delta, domainMax + delta);
}
});
this.hslider.addChangeListener(e -> {
JSlider slider = (JSlider) e.getSource();
double delta = Math.abs(slider.getValue() - 500);
if (slider.getValue() < 500){
range.setRange(rangeMin - delta, rangeMax - delta);
} else {
range.setRange(rangeMin + delta, rangeMax + delta);
}
});
}
} }

View File

@ -1,11 +1,16 @@
package View; package View;
import Model.Point; import Model.Point;
import java.awt.BasicStroke;
import javax.swing.*; import java.awt.BorderLayout;
import java.awt.*; import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Line2D; import java.awt.geom.Line2D;
import java.util.LinkedList; import java.util.LinkedList;
import javax.swing.JPanel;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -16,73 +21,76 @@ import java.util.LinkedList;
*/ */
public class ArrangementDialog2 extends JPanel { public class ArrangementDialog2 extends JPanel {
private int min = 0; private int min = 0;
private int max = 800; private int max = 800;
private int zero = max/2; private int zero = max / 2;
private double scale = 1.0; private double scale = 1.0;
private int pointThicknes = 5; private int pointThicknes = 5;
private Dimension dimension; private Dimension dimension;
private LinkedList<LinkedList<Point>> lines; private LinkedList<LinkedList<Point>> lines;
private LinkedList<Point> points; private LinkedList<Point> points;
private LinkedList<Line2D.Double> line2Ds; private LinkedList<Line2D.Double> line2Ds;
public ArrangementDialog2(){ public ArrangementDialog2() {
super(); super();
this.dimension = new Dimension(max,max); this.dimension = new Dimension(max, max);
this.setPreferredSize(dimension); this.setPreferredSize(dimension);
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
}
public void setPrameters(LinkedList<LinkedList<Point>> lines, LinkedList<Point> points) {
this.lines = lines;
this.points = points;
this.repaint();
}
public double getScale() {
return scale;
}
public void setScale(double scale) {
this.scale = scale;
}
public int getPointThicknes() {
return pointThicknes;
}
public void setPointThicknes(int pointThicknes) {
this.pointThicknes = pointThicknes;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
line2Ds = new LinkedList<>();
g2.translate(zero, zero);
g2.scale(scale, scale);
g2.translate(-1 * zero, -1 * zero);
//draw the lines
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(5f / (float) scale));
for (LinkedList<Point> 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) {
g2.draw(line);
} }
public void setPrameters(LinkedList<LinkedList<Point>> lines, LinkedList<Point> points) { //draw intersections of the lines
this.lines = lines; g2.setColor(Color.RED);
this.points = points; for (Point point : points) {
this.repaint(); g2.fillOval(zero + point.getX().intValue(), zero + point.getY().intValue(), pointThicknes,
} pointThicknes);
public double getScale() {
return scale;
}
public void setScale(double scale) {
this.scale = scale;
}
public int getPointThicknes() {
return pointThicknes;
}
public void setPointThicknes(int pointThicknes) {
this.pointThicknes = pointThicknes;
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
line2Ds = new LinkedList<>();
g2.translate(zero, zero);
g2.scale(scale, scale);
g2.translate(-1 * zero, -1 *zero);
//draw the lines
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(5f / (float) scale));
for (LinkedList<Point> 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) {
g2.draw(line);
}
//draw intersections of the lines
g2.setColor(Color.RED);
for (Point point : points) {
g2.fillOval(zero +point.getX().intValue(),zero +point.getY().intValue(), pointThicknes, pointThicknes);
}
} }
}
} }

View File

@ -1,21 +1,20 @@
package View; package View;
import Model.Line;
import Presenter.Algorithms.LeastMedianOfSquaresEstimator;
import Presenter.Presenter; import Presenter.Presenter;
import com.sun.org.apache.xpath.internal.operations.Bool; import java.awt.BorderLayout;
import jdk.nashorn.internal.scripts.JO; import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List; import java.util.List;
import java.util.Observable; import javax.swing.JButton;
import java.util.Observer; import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -24,291 +23,293 @@ import java.util.Observer;
* @Email: a_wolf28@uni-muenster.de * @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017. * @Date: 28.05.2017.
*/ */
public class MainFrame extends JFrame{ public class MainFrame extends JFrame {
private Presenter presenter; private Presenter presenter;
private Boolean lmsIsComplete = false; private Boolean lmsIsComplete = false;
private Boolean rmIsComplete = false; private Boolean rmIsComplete = false;
private Boolean tsIsComplete = false; private Boolean tsIsComplete = false;
//TODO refactoring //TODO refactoring
private JButton arrangementButton; private JButton arrangementButton;
private JButton button3; private JButton button3;
private OutputPanel output; private OutputPanel output;
private MenuPanel menupanel; private MenuPanel menupanel;
private SidePanel sidepanel; private SidePanel sidepanel;
private JPanel pane; private JPanel pane;
private ArrangementDialog arrangement; private ArrangementDialog arrangement;
private JDialog arrangementDialog; private JDialog arrangementDialog;
private PlotDialog plot; private PlotDialog plot;
private JSplitPane splitpane; private JSplitPane splitpane;
private JScrollPane scrollPane; private JScrollPane scrollPane;
private JTabbedPane tabbedPane; private JTabbedPane tabbedPane;
public MainFrame() { public MainFrame() {
initializeComponents(); initializeComponents();
setDimensions(); setDimensions();
setLayouts(); setLayouts();
setTitles(); setTitles();
addComponents(); addComponents();
setCloseOperations(); setCloseOperations();
setActionListeners(); setActionListeners();
this.setVisible(true); this.setVisible(true);
}
/*******************************************************************************************************************
* visualisierungs methoden
******************************************************************************************************************/
public void createArrangement() {
if (arrangement == null) {
arrangement = new ArrangementDialog();
arrangement.setPrameters(getPresenter().calcArrangementLines(),
getPresenter().getModel().getNodes());
arrangement.createArrangement();
SwingUtilities.invokeLater(() -> {
arrangementDialog.add(arrangement, BorderLayout.CENTER);
arrangementDialog.setVisible(true);
});
} else {
arrangementDialog.setVisible(true);
} }
}
public void createPlot(double m, double b) {
plot = new PlotDialog();
SwingUtilities.invokeLater(() -> {
plot.createPlot(getPresenter().getLines());
plot.addLineToPlot(m, b);
sidepanel.setPlotDialog(plot);
});
}
/******************************************************************************************************************* /*******************************************************************************************************************
* visualisierungs methoden * init GUI
******************************************************************************************************************/ ******************************************************************************************************************/
private void setTitles() {
this.setTitle("MainFrame");
arrangementDialog.setTitle("Dual Representation - Dialog");
button3.setText("Import");
arrangementButton.setText("Dualraum");
}
public void createArrangement() { private void setupTabbedPane() {
if (arrangement == null) { tabbedPane.add("Least Median of Squares", sidepanel);
arrangement = new ArrangementDialog(); tabbedPane.add("Repeated Median", new JPanel());
arrangement.setPrameters(getPresenter().calcArrangementLines(), getPresenter().getModel().getNodes()); tabbedPane.add("Theil-Sen", new JPanel());
arrangement.createArrangement(); }
SwingUtilities.invokeLater(() -> {
arrangementDialog.add(arrangement, BorderLayout.CENTER);
arrangementDialog.setVisible(true);
});
} else {
arrangementDialog.setVisible(true);
}
}
public void createPlot(double m, double b) { private void addComponents() {
pane.add(arrangementButton);
pane.add(button3);
plot = new PlotDialog(); setupSplitPane();
SwingUtilities.invokeLater(() -> { setupTabbedPane();
plot.createPlot(getPresenter().getLines());
plot.addLineToPlot(m, b); this.add(pane, BorderLayout.SOUTH);
sidepanel.setPlotDialog(plot); this.add(splitpane, BorderLayout.CENTER);
}); this.add(menupanel, BorderLayout.NORTH);
} }
private void setupSplitPane() {
splitpane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitpane.setResizeWeight(.5d);
splitpane.setContinuousLayout(true);
splitpane.setLeftComponent(output);
splitpane.setRightComponent(tabbedPane);
}
private void setCloseOperations() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
arrangementDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
}
private void setDimensions() {
this.setSize(1900, 1000);
sidepanel.setMinimumSize(new Dimension(400, 500));
arrangementDialog.setSize(new Dimension(800, 800));
output.setMinimumSize(new Dimension(400, 500));
}
private void setLayouts() {
this.setLayout(new BorderLayout());
pane.setLayout(new FlowLayout());
}
private void initializeComponents() {
//Panels
pane = new JPanel();
sidepanel = new SidePanel();
menupanel = new MenuPanel();
//Dialogs
arrangementDialog = new JDialog();
//Panes
tabbedPane = new JTabbedPane();
output = new OutputPanel();
splitpane = new JSplitPane();
//Buttons
arrangementButton = new JButton();
button3 = new JButton();
}
private void setActionListeners() {
arrangementButton.addActionListener((ActionEvent e) -> {
Thread t = new Thread(() -> getPresenter().startArrangementVisualization());
t.start();
});
sidepanel.getStartButton().addActionListener((ActionEvent e) -> {
Thread t = new Thread(
() -> this.getPresenter().startScatterPlotVisualization(sidepanel.getInput()));
t.start();
});
}
/*******************************************************************************************************************
* log Methode
******************************************************************************************************************/
public void log(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraph(s));
}
/******************************************************************************************************************* public void logError(String s) {
* init GUI SwingUtilities.invokeLater(() -> output.appendParagraphRed(s));
******************************************************************************************************************/ }
private void setTitles(){
this.setTitle("MainFrame");
arrangementDialog.setTitle("Dual Representation - Dialog");
button3.setText("Import");
arrangementButton.setText("Dualraum");
}
private void setupTabbedPane(){ public void logSuccess(String s) {
tabbedPane.add("LMS", sidepanel); SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s));
tabbedPane.add("RM", new JPanel()); }
tabbedPane.add("TS", new JPanel());
}
private void addComponents(){ public void logHeading(String s) {
pane.add(arrangementButton); SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s));
pane.add(button3); }
setupSplitPane(); public void createTable(List<String> heading, List<List<String>> rows) {
setupTabbedPane(); SwingUtilities.invokeLater(() -> output.logTable(heading, rows));
}
this.add(pane, BorderLayout.SOUTH); /*******************************************************************************************************************
this.add(splitpane, BorderLayout.CENTER); * Getter und Setter Methoden
this.add(menupanel, BorderLayout.NORTH); ******************************************************************************************************************/
}
private void setupSplitPane(){ public Boolean getLmsIsComplete() {
splitpane.setOrientation(JSplitPane.HORIZONTAL_SPLIT); return lmsIsComplete;
splitpane.setResizeWeight(.5d); }
splitpane.setContinuousLayout(true);
splitpane.setLeftComponent(output);
splitpane.setRightComponent(tabbedPane);
}
private void setCloseOperations(){ public void setLmsIsComplete(Boolean lmsIsComplete) {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.lmsIsComplete = lmsIsComplete;
arrangementDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); }
}
private void setDimensions(){ public Boolean getRmIsComplete() {
this.setSize(1900, 1000); return rmIsComplete;
sidepanel.setMinimumSize(new Dimension(400,500)); }
arrangementDialog.setSize(new Dimension(800, 800));
output.setMinimumSize(new Dimension(400,500));
}
private void setLayouts(){ public void setRmIsComplete(Boolean rmIsComplete) {
this.setLayout(new BorderLayout()); this.rmIsComplete = rmIsComplete;
pane.setLayout(new FlowLayout()); }
}
private void initializeComponents(){ public Boolean getTsIsComplete() {
//Panels return tsIsComplete;
pane = new JPanel(); }
sidepanel = new SidePanel();
menupanel = new MenuPanel();
//Dialogs public void setTsIsComplete(Boolean tsIsComplete) {
arrangementDialog = new JDialog(); this.tsIsComplete = tsIsComplete;
}
//Panes public JButton getArrangementButton() {
tabbedPane = new JTabbedPane(); return arrangementButton;
output = new OutputPanel(); }
splitpane = new JSplitPane();
//Buttons public void setArrangementButton(JButton arrangementButton) {
arrangementButton = new JButton(); this.arrangementButton = arrangementButton;
button3 = new JButton(); }
}
private void setActionListeners(){ public JButton getButton3() {
arrangementButton.addActionListener((ActionEvent e) -> { return button3;
Thread t = new Thread(() -> getPresenter().startArrangementVisualization()); }
t.start();
});
sidepanel.getStartButton().addActionListener((ActionEvent e) -> { public void setButton3(JButton button3) {
Thread t = new Thread(() -> this.getPresenter().startScatterPlotVisualization(sidepanel.getInput())); this.button3 = button3;
t.start(); }
});
} public JPanel getPane() {
return pane;
}
public void setPane(JPanel pane) {
this.pane = pane;
}
public JDialog getArrangementDialog() {
return arrangementDialog;
}
public void setArrangementDialog(JDialog arrangementDialog) {
this.arrangementDialog = arrangementDialog;
}
public OutputPanel getOutput() {
return output;
}
public void setOutput(OutputPanel output) {
this.output = output;
}
public JPanel getMenupanel() {
return menupanel;
}
public JPanel getSidepanel() {
return sidepanel;
}
public JSplitPane getSplitpane() {
return splitpane;
}
public void setSplitpane(JSplitPane splitpane) {
this.splitpane = splitpane;
}
public JScrollPane getScrollPane() {
return scrollPane;
}
public void setScrollPane(JScrollPane scrollPane) {
this.scrollPane = scrollPane;
}
/******************************************************************************************************************* public PlotDialog getPlot() {
* log Methode return plot;
******************************************************************************************************************/ }
public void log(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraph(s));
}
public void logError(String s){ public void setPlot(PlotDialog plot) {
SwingUtilities.invokeLater(() -> output.appendParagraphRed(s)); this.plot = plot;
} }
public void logSuccess(String s){ public Presenter getPresenter() {
SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s)); return presenter;
} }
public void logHeading(String s){ public void setPresenter(Presenter presenter) {
SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s)); this.presenter = presenter;
} }
public void createTable(List<String> heading, List<List<String>> rows){
SwingUtilities.invokeLater(() -> output.logTable(heading, rows));
}
/*******************************************************************************************************************
* Getter und Setter Methoden
******************************************************************************************************************/
public Boolean getLmsIsComplete() {
return lmsIsComplete;
}
public void setLmsIsComplete(Boolean lmsIsComplete) {
this.lmsIsComplete = lmsIsComplete;
}
public Boolean getRmIsComplete() {
return rmIsComplete;
}
public void setRmIsComplete(Boolean rmIsComplete) {
this.rmIsComplete = rmIsComplete;
}
public Boolean getTsIsComplete() {
return tsIsComplete;
}
public void setTsIsComplete(Boolean tsIsComplete) {
this.tsIsComplete = tsIsComplete;
}
public JButton getArrangementButton() {
return arrangementButton;
}
public void setArrangementButton(JButton arrangementButton) {
this.arrangementButton = arrangementButton;
}
public JButton getButton3() {
return button3;
}
public void setButton3(JButton button3) {
this.button3 = button3;
}
public JPanel getPane() {
return pane;
}
public void setPane(JPanel pane) {
this.pane = pane;
}
public JDialog getArrangementDialog() {
return arrangementDialog;
}
public void setArrangementDialog(JDialog arrangementDialog) {
this.arrangementDialog = arrangementDialog;
}
public OutputPanel getOutput() {
return output;
}
public void setOutput(OutputPanel output) {
this.output = output;
}
public JPanel getMenupanel() {
return menupanel;
}
public JPanel getSidepanel() {
return sidepanel;
}
public JSplitPane getSplitpane() {
return splitpane;
}
public void setSplitpane(JSplitPane splitpane) {
this.splitpane = splitpane;
}
public JScrollPane getScrollPane() {
return scrollPane;
}
public void setScrollPane(JScrollPane scrollPane) {
this.scrollPane = scrollPane;
}
public PlotDialog getPlot() {
return plot;
}
public void setPlot(PlotDialog plot) {
this.plot = plot;
}
public Presenter getPresenter() {
return presenter;
}
public void setPresenter(Presenter presenter) {
this.presenter = presenter;
}
} }

View File

@ -1,9 +1,12 @@
package View; package View;
import javax.swing.*; import java.awt.BorderLayout;
import java.awt.*; import javax.swing.JMenu;
import java.awt.event.ActionEvent; import javax.swing.JMenuBar;
import java.awt.event.ActionListener; import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -14,21 +17,23 @@ import java.awt.event.ActionListener;
*/ */
public class MenuPanel extends JPanel { public class MenuPanel extends JPanel {
private JMenuBar menuBar; private JMenuBar menuBar;
private JMenu menu; private JMenu menu;
private JMenuItem item; private JMenuItem item;
public MenuPanel() { public MenuPanel() {
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
this.menuBar = new JMenuBar(); this.menuBar = new JMenuBar();
this.menu = new JMenu("File"); this.menu = new JMenu("File");
this.item = new JMenuItem("Exit"); this.item = new JMenuItem("Exit");
this.item.addActionListener(e -> { System.exit(0);}); this.item.addActionListener(e -> {
System.exit(0);
});
menu.add(item); menu.add(item);
menuBar.add(menu); menuBar.add(menu);
this.add(menuBar, BorderLayout.WEST); this.add(menuBar, BorderLayout.WEST);
this.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.SOUTH); this.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.SOUTH);
} }
} }

View File

@ -1,9 +1,12 @@
package View; package View;
import javax.swing.*; import java.awt.BorderLayout;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.util.List; import java.util.List;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.border.TitledBorder;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -13,73 +16,73 @@ import java.util.List;
*/ */
public class OutputPanel extends JPanel { public class OutputPanel extends JPanel {
private JTextPane output; private JTextPane output;
private JScrollPane scrollPane; private JScrollPane scrollPane;
private StringBuilder content; private StringBuilder content;
public OutputPanel(){ public OutputPanel() {
this.setBorder(new TitledBorder("Ausgabekanal")); this.setBorder(new TitledBorder("Ausgabekanal"));
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
output = new JTextPane(); output = new JTextPane();
output.setEditable(false); output.setEditable(false);
output.setContentType("text/html"); output.setContentType("text/html");
content = new StringBuilder(); content = new StringBuilder();
scrollPane = new JScrollPane(output);
scrollPane.setWheelScrollingEnabled(true);
this.add(scrollPane, BorderLayout.CENTER);
}
scrollPane = new JScrollPane(output); public void appendParagraph(String p) {
scrollPane.setWheelScrollingEnabled(true);
this.add(scrollPane, BorderLayout.CENTER);
} content.append("<p>" + p + "</p></br>");
public void appendParagraph(String p) {
content.append("<p>" + p + "</p></br>");
output.setText(content.toString());
}
public void appendParagraphWithHeading(String h1){
content.append("<h1>"+ h1 + "</h1></br>");
output.setText(content.toString());
}
public void appendParagraphRed(String p) {
content.append("<p style=\" color:red \"><em><strong>" + p + "</strong></em></p></br>");
output.setText(content.toString());
}
public void appendParagraphGreen(String p) {
content.append("<p style=\" color:green \"><em><strong>" + p + "</strong></em></p></br>");
output.setText(content.toString());
}
public void logTable(List<String> heading, List<List<String>> rows){
content.append("<center>");
content.append("<table style=\" width:80%; border: 1px solid black; \">");
content.append("<tr>");
for (String str : heading) {
content.append("<th style=\" border: 1px solid black; \">" + str + "</th>");
}
content.append("</tr>");
for (List<String> row : rows) {
content.append("<tr>");
for (String entry : row) {
content.append("<td style=\" border: 1px solid black; \">"+entry+"</td>");
}
content.append("</tr>");
}
content.append("</table>");
content.append("</center>");
output.setText(content.toString()); output.setText(content.toString());
}
public void appendParagraphWithHeading(String h1) {
content.append("<h1>" + h1 + "</h1></br>");
output.setText(content.toString());
}
public void appendParagraphRed(String p) {
content.append("<p style=\" color:red \"><em><strong>" + p + "</strong></em></p></br>");
output.setText(content.toString());
}
public void appendParagraphGreen(String p) {
content.append("<p style=\" color:green \"><em><strong>" + p + "</strong></em></p></br>");
output.setText(content.toString());
}
public void logTable(List<String> heading, List<List<String>> rows) {
content.append("<center>");
content.append("<table style=\" width:80%; border: 1px solid black; \">");
content.append("<tr>");
for (String str : heading) {
content.append("<th style=\" border: 1px solid black; \">" + str + "</th>");
} }
content.append("</tr>");
for (List<String> row : rows) {
content.append("<tr>");
for (String entry : row) {
content.append("<td style=\" border: 1px solid black; \">" + entry + "</td>");
}
content.append("</tr>");
}
content.append("</table>");
content.append("</center>");
output.setText(content.toString());
}
} }

View File

@ -1,24 +1,25 @@
package View; package View;
import Model.Line; import Model.Line;
import Model.Point; import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Shape;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel; import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart; import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot; import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection; import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities; import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -28,92 +29,91 @@ import java.util.LinkedList;
*/ */
public class PlotDialog extends JPanel { public class PlotDialog extends JPanel {
private JFreeChart chart; private JFreeChart chart;
private ChartPanel panel; private ChartPanel panel;
private XYSeriesCollection datapoints; private XYSeriesCollection datapoints;
private XYSeries series; private XYSeries series;
private XYSeries linesA, linesB; private XYSeries linesA, linesB;
private Double min; private Double min;
private Double max; private Double max;
public PlotDialog() { public PlotDialog() {
super(); super();
this.setPreferredSize(new Dimension(800, 500)); this.setPreferredSize(new Dimension(800, 500));
this.setMinimumSize(new Dimension(800, 500)); this.setMinimumSize(new Dimension(800, 500));
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
}
public void createPlot(LinkedList<Line> points) {
try {
Thread thread = new Thread(() -> convertData(points));
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
} }
public void createPlot(LinkedList<Line> points) { //createScatterPlot
chart = ChartFactory.createXYLineChart("",
"X", "Y", datapoints, PlotOrientation.VERTICAL, false, true, false);
Shape diamond = ShapeUtilities.createDiamond(2f);
chart.setBorderVisible(false);
chart.setAntiAlias(true);
chart.getPlot().setBackgroundPaint(Color.WHITE);
try { XYPlot xyPlot = (XYPlot) chart.getPlot();
Thread thread = new Thread(() -> convertData(points)); xyPlot.setDomainCrosshairVisible(true);
thread.start(); xyPlot.setRangeCrosshairVisible(true);
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//createScatterPlot XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
chart = ChartFactory.createXYLineChart("", renderer.setSeriesLinesVisible(0, false);
"X", "Y", datapoints, PlotOrientation.VERTICAL, false, true, false); renderer.setSeriesShapesVisible(0, true);
Shape diamond = ShapeUtilities.createDiamond(2f); renderer.setSeriesLinesVisible(1, true);
chart.setBorderVisible(false); renderer.setSeriesLinesVisible(2, true);
chart.setAntiAlias(true);
chart.getPlot().setBackgroundPaint(Color.WHITE);
XYPlot xyPlot = (XYPlot) chart.getPlot(); renderer.setSeriesPaint(0, Color.blue);
xyPlot.setDomainCrosshairVisible(true); renderer.setSeriesShape(0, diamond);
xyPlot.setRangeCrosshairVisible(true);
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer(); renderer.setSeriesPaint(1, Color.red);
renderer.setSeriesLinesVisible(0,false); renderer.setSeriesShape(1, diamond);
renderer.setSeriesShapesVisible(0, true); renderer.setSeriesStroke(1, new BasicStroke(2.0f));
renderer.setSeriesLinesVisible(1,true); renderer.setBaseSeriesVisible(true);
renderer.setSeriesLinesVisible(2,true);
renderer.setSeriesPaint(0, Color.blue); renderer.setSeriesPaint(2, Color.GREEN);
renderer.setSeriesShape(0, diamond); renderer.setSeriesShape(2, diamond);
renderer.setSeriesStroke(2, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
renderer.setSeriesPaint(1, Color.red); panel = new ChartPanel(chart);
renderer.setSeriesShape(1, diamond); this.add(panel, BorderLayout.CENTER);
renderer.setSeriesStroke(1,new BasicStroke(2.0f)); }
renderer.setBaseSeriesVisible(true);
renderer.setSeriesPaint(2, Color.GREEN); public void addLineToPlot(double m, double b) {
renderer.setSeriesShape(2, diamond); linesA = new XYSeries("linesA");
renderer.setSeriesStroke(2,new BasicStroke(2.0f)); linesA.add(min.intValue(), min.intValue() * m + b);
renderer.setBaseSeriesVisible(true); linesA.add(max.intValue(), max.intValue() * m + b);
xyPlot.setDomainCrosshairVisible(true); datapoints.addSeries(linesA);
xyPlot.setRangeCrosshairVisible(true); }
private void convertData(LinkedList<Line> points) {
datapoints = new XYSeriesCollection();
ArrayList<Double> coordinates = new ArrayList<>();
series = new XYSeries("points");
for (Line p : points) {
series.add(p.getM(), p.getB());
coordinates.add(p.getM());
panel = new ChartPanel(chart);
this.add(panel, BorderLayout.CENTER);
}
public void addLineToPlot(double m, double b) {
linesA = new XYSeries("linesA");
linesA.add(min.intValue(), min.intValue() * m + b );
linesA.add(max.intValue(), max.intValue() * m + b );
datapoints.addSeries(linesA);
}
private void convertData(LinkedList<Line> points) {
datapoints = new XYSeriesCollection();
ArrayList<Double> coordinates = new ArrayList<>();
series = new XYSeries("points");
for (Line p : points) {
series.add(p.getM(), p.getB());
coordinates.add(p.getM());
}
this.max = Collections.max(coordinates) + 1;
this.min = Collections.min(coordinates) - 1;
datapoints.addSeries(series);
} }
this.max = Collections.max(coordinates) + 1;
this.min = Collections.min(coordinates) - 1;
datapoints.addSeries(series);
}
} }

View File

@ -1,8 +1,14 @@
package View; package View;
import javax.swing.*; import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import java.awt.*;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -14,99 +20,98 @@ import java.awt.*;
public class SidePanel extends JPanel { public class SidePanel extends JPanel {
private JLabel[] labels; private JLabel[] labels;
private JTextField[] input; private JTextField[] input;
private JButton startButton; private JButton startButton;
private JPanel continer; private JPanel continer;
private JPanel northPanel; private JPanel northPanel;
private JPanel centerPanel; private JPanel centerPanel;
private PlotDialog plotDialog; private PlotDialog plotDialog;
private GridBagConstraints gbc; private GridBagConstraints gbc;
public SidePanel() { public SidePanel() {
this.labels = new JLabel[10]; this.labels = new JLabel[10];
this.input = new JTextField[10]; this.input = new JTextField[10];
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
this.northPanel = new JPanel(new BorderLayout()); this.northPanel = new JPanel(new BorderLayout());
this.centerPanel = new JPanel(new BorderLayout()); this.centerPanel = new JPanel(new BorderLayout());
this.northPanel.setBorder(new TitledBorder("Konfiguration")); this.northPanel.setBorder(new TitledBorder("Konfiguration"));
this.centerPanel.setBorder(new TitledBorder("Visualisierung")); this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
this.continer = new JPanel();
this.continer.setLayout(new GridBagLayout());
this.gbc = new GridBagConstraints();
this.gbc.anchor = GridBagConstraints.NORTH;
this.gbc.fill = GridBagConstraints.HORIZONTAL;
addTextfieldAndInput(0, "Konstante", 0.5);
addTextfieldAndInput(1, "Fehler", 0.05);
this.startButton = new JButton("start");
addButton(2, startButton);
this.northPanel.add(continer, BorderLayout.CENTER);
this.add(northPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
}
this.continer = new JPanel(); private void addTextfieldAndInput(int row, String name, Double value) {
this.continer.setLayout(new GridBagLayout()); this.labels[row] = new JLabel(name);
this.input[row] = new JTextField();
this.input[row].setText("" + value);
this.gbc = new GridBagConstraints(); gbc.insets = new Insets(0, 5, 0, 0);
this.gbc.anchor = GridBagConstraints.NORTH; gbc.gridx = 0;
this.gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridy = row;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
continer.add(this.labels[row], gbc);
addTextfieldAndInput(0, "Konstante", 0.5); gbc.gridx = 1;
addTextfieldAndInput(1, "Fehler", 0.05); gbc.gridy = row;
gbc.weightx = 0.9;
gbc.weighty = 0.05;
gbc.insets = new Insets(0, 0, 0, 5);
continer.add(this.input[row], gbc);
}
this.startButton = new JButton("start"); private void addButton(int row, JButton button) {
addButton(2, startButton);
this.northPanel.add(continer, BorderLayout.CENTER); gbc.insets = new Insets(30, 5, 10, 0);
this.add(northPanel, BorderLayout.NORTH); gbc.gridx = 0;
this.add(centerPanel, BorderLayout.CENTER); gbc.gridy = row;
} gbc.weightx = 0.05;
gbc.weighty = 0.05;
continer.add(button, gbc);
}
private void addTextfieldAndInput(int row, String name, Double value) { public JButton getStartButton() {
this.labels[row] = new JLabel(name); return startButton;
this.input[row] = new JTextField(); }
this.input[row].setText("" + value);
gbc.insets = new Insets(0, 5, 0, 0); public String[] getInput() {
gbc.gridx = 0; String[] input = new String[3];
gbc.gridy = row; input[0] = this.input[0].getText();
gbc.weightx = 0.05; input[1] = this.input[1].getText();
gbc.weighty = 0.05; return input;
continer.add(this.labels[row], gbc); }
gbc.gridx = 1; public void setInput(JTextField[] input) {
gbc.gridy = row; this.input = input;
gbc.weightx = 0.9; }
gbc.weighty = 0.05;
gbc.insets = new Insets(0, 0, 0, 5);
continer.add(this.input[row], gbc);
}
private void addButton(int row, JButton button) { public PlotDialog getPlotDialog() {
return plotDialog;
}
gbc.insets = new Insets(30, 5, 10, 0); public void setPlotDialog(PlotDialog plotDialog) {
gbc.gridx = 0; this.plotDialog = plotDialog;
gbc.gridy = row; this.centerPanel.add(plotDialog, BorderLayout.CENTER);
gbc.weightx = 0.05; this.plotDialog.setVisible(true);
gbc.weighty = 0.05; this.repaint();
this.revalidate();
continer.add(button, gbc); }
}
public JButton getStartButton() {
return startButton;
}
public String[] getInput() {
String[] input = new String[3];
input[0] = this.input[0].getText();
input[1] = this.input[1].getText();
return input;
}
public void setInput(JTextField[] input) {
this.input = input;
}
public PlotDialog getPlotDialog() {
return plotDialog;
}
public void setPlotDialog(PlotDialog plotDialog) {
this.plotDialog = plotDialog;
this.centerPanel.add(plotDialog, BorderLayout.CENTER);
this.plotDialog.setVisible(true);
this.repaint();
this.revalidate();
}
} }

View File

@ -1,17 +1,16 @@
package Model; package Model;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import Model.DCEL.DoublyConnectedEdgeList; import Model.DCEL.DoublyConnectedEdgeList;
import Model.DCEL.Edge; import Model.DCEL.Edge;
import Model.DCEL.Face; import Model.DCEL.Face;
import Model.DCEL.Node; import Model.DCEL.Node;
import java.util.LinkedList;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.util.LinkedList;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -21,80 +20,80 @@ import static org.junit.Assert.assertEquals;
*/ */
public class DoublyConnectedEdgeListTest { public class DoublyConnectedEdgeListTest {
private static DoublyConnectedEdgeList dcel; private static DoublyConnectedEdgeList dcel;
private static Node v1, v2, v3, v4, v5; private static Node v1, v2, v3, v4, v5;
private static Edge e1, e2, e3, e4, e5; private static Edge e1, e2, e3, e4, e5;
private static Face f1, f2; private static Face f1, f2;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
dcel = new DoublyConnectedEdgeList(); dcel = new DoublyConnectedEdgeList();
//initialisiere die TestKnoten im Graphen //initialisiere die TestKnoten im Graphen
v1 = dcel.createNode(new Point(2.5, 7.5), "v1"); v1 = dcel.createNode(new Point(2.5, 7.5), "v1");
v2 = dcel.createNode(new Point(2.5, 4.0), "v2"); v2 = dcel.createNode(new Point(2.5, 4.0), "v2");
v3 = dcel.createNode(new Point(6.5, 3.5), "v3"); v3 = dcel.createNode(new Point(6.5, 3.5), "v3");
v4 = dcel.createNode(new Point(8.5, 6.5), "v4"); v4 = dcel.createNode(new Point(8.5, 6.5), "v4");
v5 = dcel.createNode(new Point(6.0, 8.0), "v5"); v5 = dcel.createNode(new Point(6.0, 8.0), "v5");
//initialisere Kanten im Graph //initialisere Kanten im Graph
e1 = dcel.createEdge(v1, v5, "e1"); e1 = dcel.createEdge(v1, v5, "e1");
e2 = dcel.createEdge(v5, v4, "e2"); e2 = dcel.createEdge(v5, v4, "e2");
e3 = dcel.createEdge(v4, v3, "e3"); e3 = dcel.createEdge(v4, v3, "e3");
e4 = dcel.createEdge(v3, v2, "e4"); e4 = dcel.createEdge(v3, v2, "e4");
e5 = dcel.createEdge(v2, v1, "e5"); e5 = dcel.createEdge(v2, v1, "e5");
dcel.createConnection(e1, e2); dcel.createConnection(e1, e2);
dcel.createConnection(e2, e3); dcel.createConnection(e2, e3);
dcel.createConnection(e3, e4); dcel.createConnection(e3, e4);
dcel.createConnection(e4, e5); dcel.createConnection(e4, e5);
dcel.createConnection(e5, e1); dcel.createConnection(e5, e1);
//intialisiere die Flaechen //intialisiere die Flaechen
f1 = dcel.createFace(null, e1, "f1"); f1 = dcel.createFace(null, e1, "f1");
f2 = dcel.createFace(e1.getTwin(), null, "f2"); f2 = dcel.createFace(e1.getTwin(), null, "f2");
}
@Test
public void testInnerComponentsAccess() {
System.out.println("Test: testInnerComponentAccess();");
Edge[] expected = {e1, e2, e3, e4, e5};
LinkedList<Edge> list = dcel.getEdgesOfInnerComponents(f1);
assertArrayEquals(expected, list.toArray());
}
@Test
public void testOuterComponentsAccess() {
System.out.println("Test: testOuterComponentAccess();");
String[] expected = {"#e1", "#e5", "#e4", "#e3", "#e2"};
LinkedList<Edge> list = dcel.getEdgesOfOuterComponents(f2);
for (int i = 0; i < list.size(); i++) {
assertEquals(expected[i], list.get(i).getID());
} }
}
@Test
public void testInnerComponentsAccess() {
System.out.println("Test: testInnerComponentAccess();");
Edge[] expected = {e1, e2, e3, e4, e5};
LinkedList<Edge> list = dcel.getEdgesOfInnerComponents(f1);
assertArrayEquals(expected, list.toArray());
}
@Test
public void testOuterComponentsAccess() {
System.out.println("Test: testOuterComponentAccess();");
String[] expected = {"#e1", "#e5", "#e4", "#e3", "#e2"};
LinkedList<Edge> list = dcel.getEdgesOfOuterComponents(f2);
for (int i = 0; i < list.size(); i++) {
assertEquals(expected[i], list.get(i).getID());
}
}
@Test @Test
public void testNodeEdgeAccess() { public void testNodeEdgeAccess() {
System.out.println("Test: testNodeEdgeAccess();"); System.out.println("Test: testNodeEdgeAccess();");
assertEquals(5, dcel.getConnectedEdges(v4).size()); assertEquals(5, dcel.getConnectedEdges(v4).size());
} }
@Test @Test
public void testDCELAccess() { public void testDCELAccess() {
System.out.println("Test: testDCELAccess();"); System.out.println("Test: testDCELAccess();");
assertEquals(e1, e1.getTwin().getTwin()); assertEquals(e1, e1.getTwin().getTwin());
assertEquals(e1, e1.getPrev().getNext()); assertEquals(e1, e1.getPrev().getNext());
assertEquals(e2.getID(), e1.getTwin().getPrev().getTwin().getID()); assertEquals(e2.getID(), e1.getTwin().getPrev().getTwin().getID());
assertEquals(e1, e1.getNext().getNext().getNext().getNext().getNext()); assertEquals(e1, e1.getNext().getNext().getNext().getNext().getNext());
assertEquals(e1.getTwin(), e1.getTwin().getNext().getNext().getNext().getNext().getNext()); assertEquals(e1.getTwin(), e1.getTwin().getNext().getNext().getNext().getNext().getNext());
} }
} }

View File

@ -1,16 +1,18 @@
package Presenter.Algorithms; package Presenter.Algorithms;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import Model.Line; import Model.Line;
import Model.Point; import Model.Point;
import Model.Slab; import Model.Slab;
import org.junit.Before; import Presenter.InversionCounter;
import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import org.junit.Before;
import static org.junit.Assert.*; import org.junit.Test;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -21,100 +23,97 @@ import static org.junit.Assert.*;
*/ */
public class LeastMedianOfSquaresEstimatorTest { public class LeastMedianOfSquaresEstimatorTest {
private LeastMedianOfSquaresEstimator lms; private LeastMedianOfSquaresEstimator lms;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
Double[] x = {18d,24d,30d,34d,38d}; Double[] x = {18d, 24d, 30d, 34d, 38d};
Double[] y = {18d,26d,30d,40d,70d}; Double[] y = {18d, 26d, 30d, 40d, 70d};
LinkedList<Line> lines = new LinkedList<>(); LinkedList<Line> lines = new LinkedList<>();
LinkedList<Point> intersections = new LinkedList<>(); LinkedList<Point> intersections = new LinkedList<>();
for (int i=0; i<5; i++) for (int i = 0; i < 5; i++) {
lines.add(new Line(x[i], y[i])); lines.add(new Line(x[i], y[i]));
}
lms = new LeastMedianOfSquaresEstimator(lines, intersections);
}
@Test
public void approximateLMS() throws Exception {
}
@Test
public void mergeSort() throws Exception {
lms = new LeastMedianOfSquaresEstimator(lines, intersections);
}
@Test
public void approximateLMS() throws Exception {
}
@Test
public void mergeSort() throws Exception {
// double[] umin = {6,3,4,1,2,5}; // double[] umin = {6,3,4,1,2,5};
// double[] umax = {3,5,2,6,1,4}; // double[] umax = {3,5,2,6,1,4};
double[] umin = {1,2,3,4}; double[] umin = {1, 2, 3, 4};
double[] umax = {2,3,4,1}; double[] umax = {2, 3, 4, 1};
ArrayList<Integer> a = new ArrayList<>(); ArrayList<Integer> a = new ArrayList<>();
ArrayList<Integer> b = new ArrayList<>(); ArrayList<Integer> b = new ArrayList<>();
for (double d :umin) {
a.add((int) d);
}
for (double d :umax) {
b.add((int) d);
}
InversionCounter invCounter = new InversionCounter();
int ret = invCounter.run(a, b);
assertEquals(3d, ret, 0.001);
for (double d : umin) {
a.add((int) d);
} }
@Test for (double d : umax) {
public void geEjValues() throws Exception { b.add((int) d);
Double[] expected = {36d,50d,60d,74d,108d};
ArrayList<Double> actual = lms.getEjValues(1d);
assertArrayEquals(expected, actual.toArray());
} }
InversionCounter invCounter = new InversionCounter();
int ret = invCounter.run(a, b);
assertEquals(3d, ret, 0.001);
@Test }
public void calcKMinusBracelet() throws Exception {
Point point = new Point(1d, 1d); @Test
Double[] expected = {24d, 36d, 60d}; public void geEjValues() throws Exception {
Double[] actual = lms.calcKMinusBracelet(point, 3);
assertArrayEquals(expected, actual); Double[] expected = {36d, 50d, 60d, 74d, 108d};
ArrayList<Double> actual = lms.getEjValues(1d);
assertArrayEquals(expected, actual.toArray());
}
} @Test
public void calcKMinusBracelet() throws Exception {
@Test Point point = new Point(1d, 1d);
public void upperBound() throws Exception { Double[] expected = {24d, 36d, 60d};
lms.setkMinus(3); Double[] actual = lms.calcKMinusBracelet(point, 3);
lms.setHeightsigmaMin(500);
lms.setSigmaMin(new Line(0,0,0,0));
lms.setN(5);
Line expected = new Line(5,5,146,210);
lms.upperBound(5d);
assertEquals(expected.getX1(), lms.getSigmaMin().getX1(),0.01); assertArrayEquals(expected, actual);
assertEquals(expected.getX2(), lms.getSigmaMin().getX2(),0.01);
assertEquals(expected.getY1(), lms.getSigmaMin().getY1(),0.01);
assertEquals(expected.getY2(), lms.getSigmaMin().getY2(),0.01);
}
@Test }
public void lowerBound() throws Exception {
//kann nur über sout geprüft werden test passt aber
Double[] expectedAlpha = {0d,0d,0d,2d,4d};
Double[] expectedBeta = {2d,4d,4d,2d,1d};
lms.setHeightsigmaMin(500);
Slab slab = new Slab(-2,0); @Test
lms.lowerBound(slab); public void upperBound() throws Exception {
assertTrue(slab.getActivity()); lms.setkMinus(3);
} lms.setHeightsigmaMin(500);
lms.setSigmaMin(new Line(0, 0, 0, 0));
lms.setN(5);
Line expected = new Line(5, 5, 146, 210);
lms.upperBound(5d);
assertEquals(expected.getX1(), lms.getSigmaMin().getX1(), 0.01);
assertEquals(expected.getX2(), lms.getSigmaMin().getX2(), 0.01);
assertEquals(expected.getY1(), lms.getSigmaMin().getY1(), 0.01);
assertEquals(expected.getY2(), lms.getSigmaMin().getY2(), 0.01);
}
@Test
public void lowerBound() throws Exception {
//kann nur über sout geprüft werden test passt aber
Double[] expectedAlpha = {0d, 0d, 0d, 2d, 4d};
Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d};
lms.setHeightsigmaMin(500);
Slab slab = new Slab(-2, 0);
lms.lowerBound(slab);
assertTrue(slab.getActivity());
}
} }