bisschen refactor :D About Page müsste noch mit Text gefüllt werden. Theil-Sen läuft stabieler. Menubar ist aufgefüllt. DataExport muss noch bei der Evaluation eingeflegt werden.
This commit is contained in:
parent
ccd6160745
commit
634d9361ea
|
@ -1,6 +1,6 @@
|
|||
import Model.LineModel;
|
||||
import Presenter.Presenter;
|
||||
import View.MainFrame;
|
||||
import model.LineModel;
|
||||
import presenter.Presenter;
|
||||
import view.MainFrame;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
@ -14,46 +14,48 @@ import java.awt.*;
|
|||
*/
|
||||
public class App {
|
||||
|
||||
private static void setUIFont(javax.swing.plaf.FontUIResource f)
|
||||
{
|
||||
java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
|
||||
while (keys.hasMoreElements())
|
||||
{
|
||||
Object key = keys.nextElement();
|
||||
Object value = UIManager.get(key);
|
||||
if (value instanceof javax.swing.plaf.FontUIResource)
|
||||
{
|
||||
UIManager.put(key, f);
|
||||
}
|
||||
private static void setUIFont(javax.swing.plaf.FontUIResource f) {
|
||||
java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
|
||||
while (keys.hasMoreElements()) {
|
||||
Object key = keys.nextElement();
|
||||
Object value = UIManager.get(key);
|
||||
if (value instanceof javax.swing.plaf.FontUIResource) {
|
||||
UIManager.put(key, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setLookAndFeel(JFrame view){
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.jtattoo.plaf.aluminium.AluminiumLookAndFeel");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (UnsupportedLookAndFeelException e) {
|
||||
e.printStackTrace();
|
||||
private static void setLookAndFeel(JFrame view) {
|
||||
String[] laf = {"com.jtattoo.plaf.aluminium.AluminiumLookAndFeel",
|
||||
"com.jtattoo.plaf.acryl.AcrylLookAndFeel",
|
||||
"com.jtattoo.plaf.aero.AeroLookAndFeel",
|
||||
"com.jtattoo.plaf.fast.FastLookAndFeel",
|
||||
"com.jtattoo.plaf.graphite.GraphiteLookAndFeel"};
|
||||
try {
|
||||
UIManager.setLookAndFeel(laf[4]);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (UnsupportedLookAndFeelException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SwingUtilities.updateComponentTreeUI(view);
|
||||
}
|
||||
SwingUtilities.updateComponentTreeUI(view);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) {
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JFrame.setDefaultLookAndFeelDecorated(true);
|
||||
MainFrame view = new MainFrame();
|
||||
setLookAndFeel(view);
|
||||
setUIFont (new javax.swing.plaf.FontUIResource(new Font("Verdana",Font.PLAIN, 12)));
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JFrame.setDefaultLookAndFeelDecorated(true);
|
||||
MainFrame view = new MainFrame();
|
||||
setLookAndFeel(view);
|
||||
setUIFont(new javax.swing.plaf.FontUIResource(new Font("Verdana", Font.PLAIN, 12)));
|
||||
view.setPresenter(new Presenter(new LineModel(), view));
|
||||
view.setActionListeners();
|
||||
});
|
||||
|
||||
view.setPresenter(new Presenter(new LineModel(), view));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
package Model.DCEL;
|
||||
|
||||
|
||||
import Model.Point;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class DoublyConnectedEdgeList {
|
||||
|
||||
private LinkedList<Node> nodes;
|
||||
private LinkedList<Edge> edges;
|
||||
private LinkedList<Face> faces;
|
||||
|
||||
public DoublyConnectedEdgeList() {
|
||||
this.nodes = new LinkedList<>();
|
||||
this.edges = 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));
|
||||
}
|
||||
|
||||
if (innerComponent != null) {
|
||||
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) {
|
||||
Edge edge = node.getIncidentEdge();
|
||||
LinkedList list = new LinkedList();
|
||||
do {
|
||||
list.add(edge);
|
||||
edge = edge.getNext();
|
||||
} while (node != edge.getOrigin());
|
||||
return list;
|
||||
}
|
||||
|
||||
public LinkedList<Node> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public void setNodes(LinkedList<Node> nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
public LinkedList<Edge> getEdges() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
public void setEdges(LinkedList<Edge> edges) {
|
||||
this.edges = edges;
|
||||
}
|
||||
|
||||
public LinkedList<Face> getFaces() {
|
||||
return faces;
|
||||
}
|
||||
|
||||
public void setFaces(LinkedList<Face> faces) {
|
||||
this.faces = faces;
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
package Model.DCEL;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class Edge {
|
||||
|
||||
private Node origin;
|
||||
private Edge twin;
|
||||
private Face incidentFace;
|
||||
private Edge next;
|
||||
private Edge prev;
|
||||
private String id;
|
||||
|
||||
public Edge() {
|
||||
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 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;
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
package Model.DCEL;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class Face {
|
||||
|
||||
private LinkedList<Edge> innerComponents;
|
||||
private Edge outerComponent;
|
||||
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 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 String getID() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setID(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package Model.DCEL;
|
||||
|
||||
import Model.Point;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class Node {
|
||||
|
||||
private Point point;
|
||||
private Edge incidentEdge;
|
||||
private String id;
|
||||
|
||||
public Node() {
|
||||
new Node(null, null);
|
||||
}
|
||||
|
||||
public Node(Point point, Edge incidentEdge) {
|
||||
this.point = point;
|
||||
this.incidentEdge = incidentEdge;
|
||||
}
|
||||
|
||||
public Point getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
public void setPoint(Point point) {
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
public Edge getIncidentEdge() {
|
||||
return incidentEdge;
|
||||
}
|
||||
|
||||
public void setIncidentEdge(Edge incidentEdge) {
|
||||
this.incidentEdge = incidentEdge;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setID(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package Model;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 16.06.2017.
|
||||
*/
|
||||
public class Interval {
|
||||
|
||||
private double upper;
|
||||
private double lower;
|
||||
private Boolean activity;
|
||||
|
||||
public Interval(double lower, double upper) {
|
||||
this.upper = upper;
|
||||
this.lower = lower;
|
||||
this.activity = true;
|
||||
}
|
||||
|
||||
public Boolean getActivity() {
|
||||
return activity;
|
||||
}
|
||||
|
||||
public void setActivity(Boolean isActive) {
|
||||
this.activity = isActive;
|
||||
}
|
||||
|
||||
public double getUpper() {
|
||||
return upper;
|
||||
}
|
||||
|
||||
public void setUpper(double upper) {
|
||||
this.upper = upper;
|
||||
}
|
||||
|
||||
public double getLower() {
|
||||
return lower;
|
||||
}
|
||||
|
||||
public void setLower(double lower) {
|
||||
this.lower = lower;
|
||||
}
|
||||
|
||||
public Double getDistance() {
|
||||
|
||||
return Math.abs(this.upper - this.lower);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package Model;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 12.06.2017.
|
||||
*/
|
||||
public class Line {
|
||||
|
||||
private final Double MAX = 9999d;
|
||||
private final Double MIN = -9999d;
|
||||
|
||||
|
||||
private Double m;
|
||||
private Double b;
|
||||
|
||||
private Double x1;
|
||||
private Double x2;
|
||||
private Double y1;
|
||||
private Double y2;
|
||||
|
||||
private String id;
|
||||
|
||||
public Line(double m, double b, String id) {
|
||||
this.m = m;
|
||||
this.b = b;
|
||||
|
||||
this.x1 = MIN;
|
||||
this.y1 = (MIN * m) + b;
|
||||
this.x2 = MAX * 0.5;
|
||||
this.y2 = ((MAX * 0.5) * m) + b;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
public Line(double m, double b) {
|
||||
this.m = m;
|
||||
this.b = b;
|
||||
|
||||
this.x1 = MIN;
|
||||
this.y1 = (MIN * m) + b;
|
||||
this.x2 = MAX * 0.5;
|
||||
this.y2 = ((MAX * 0.5) * m) + b;
|
||||
}
|
||||
|
||||
public Line(double x1, double x2, double y1, double y2) {
|
||||
this.x1 = x1;
|
||||
this.x2 = x2;
|
||||
this.y1 = y1;
|
||||
this.y2 = y2;
|
||||
|
||||
this.m = (y2 - y1) / (x2 - x1);
|
||||
this.b = y2 - (x2 * m);
|
||||
|
||||
}
|
||||
|
||||
public Double getM() {
|
||||
return m;
|
||||
}
|
||||
|
||||
public void setM(double m) {
|
||||
this.m = m;
|
||||
}
|
||||
|
||||
public Double getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
public void setB(double b) {
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getX1() {
|
||||
return x1;
|
||||
}
|
||||
|
||||
public Double getX2() {
|
||||
return x2;
|
||||
}
|
||||
|
||||
public Double getY1() {
|
||||
return y1;
|
||||
}
|
||||
|
||||
public Double getY2() {
|
||||
return y2;
|
||||
}
|
||||
|
||||
public void setEndPoints(double x1, double y1, double x2, double y2) {
|
||||
this.x1 = x1;
|
||||
this.x2 = x2;
|
||||
this.y1 = y1;
|
||||
this.y2 = y2;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
package Model;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class LineModel {
|
||||
|
||||
private LinkedList<Point> nodes;
|
||||
private LinkedList<Line> lines;
|
||||
private Double xMinimum;
|
||||
private Double xMaximum;
|
||||
private Double yMinimum;
|
||||
private Double yMaximum;
|
||||
|
||||
public LineModel() {
|
||||
nodes = new LinkedList<>();
|
||||
lines = new LinkedList<>();
|
||||
}
|
||||
|
||||
public void setXbounds(){
|
||||
LinkedList<Double> xlist = new LinkedList<>();
|
||||
for (Point p : nodes){
|
||||
xlist.add(p.getX());
|
||||
}
|
||||
|
||||
xMaximum = Collections.max(xlist);
|
||||
xMinimum = Collections.min(xlist);
|
||||
}
|
||||
|
||||
public void setYbounds(){
|
||||
LinkedList<Double> ylist = new LinkedList<>();
|
||||
for (Point p : nodes){
|
||||
ylist.add(p.getY());
|
||||
}
|
||||
|
||||
yMaximum = Collections.max(ylist);
|
||||
yMinimum = Collections.min(ylist);
|
||||
}
|
||||
|
||||
public void addNode(Point node) {
|
||||
this.nodes.add(node);
|
||||
}
|
||||
|
||||
public void addLine(Line line) {
|
||||
this.lines.add(line);
|
||||
}
|
||||
|
||||
public LinkedList<Point> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public LinkedList<Line> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
public void setLines(LinkedList<Line> lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
public Double getxMinimum() {
|
||||
return xMinimum;
|
||||
}
|
||||
|
||||
public void setxMinimum(Double xMinimum) {
|
||||
this.xMinimum = xMinimum;
|
||||
}
|
||||
|
||||
public Double getxMaximum() {
|
||||
return xMaximum;
|
||||
}
|
||||
|
||||
public void setxMaximum(Double xMaximum) {
|
||||
this.xMaximum = xMaximum;
|
||||
}
|
||||
|
||||
public Double getyMinimum() {
|
||||
return yMinimum;
|
||||
}
|
||||
|
||||
public void setyMinimum(Double yMinimum) {
|
||||
this.yMinimum = yMinimum;
|
||||
}
|
||||
|
||||
public Double getyMaximum() {
|
||||
return yMaximum;
|
||||
}
|
||||
|
||||
public void setyMaximum(Double yMaximum) {
|
||||
this.yMaximum = yMaximum;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package Model;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 19.06.2017.
|
||||
*/
|
||||
public class Pair {
|
||||
|
||||
private Integer p1;
|
||||
private Integer p2;
|
||||
|
||||
public Pair(Integer p1, Integer p2) {
|
||||
this.p1 = p1;
|
||||
this.p2 = p2;
|
||||
}
|
||||
|
||||
public Integer getP1() {
|
||||
return p1;
|
||||
}
|
||||
|
||||
public void setP1(Integer p1) {
|
||||
this.p1 = p1;
|
||||
}
|
||||
|
||||
public Integer getP2() {
|
||||
return p2;
|
||||
}
|
||||
|
||||
public void setP2(Integer p2) {
|
||||
this.p2 = p2;
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
package Model;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class Point implements Comparable<Point> {
|
||||
|
||||
private Double x;
|
||||
private Double y;
|
||||
private String id;
|
||||
|
||||
public Point(Double x, Double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Point(Double x, Double y, String id) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(Double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public Double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(Double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Point o) {
|
||||
if (this.getX() == o.getX()) {
|
||||
if (this.getY() <= o.getY()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else if (this.getX() < o.getX()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package Presenter.Algorithms;
|
||||
|
||||
import Presenter.Presenter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 26.06.2017.
|
||||
*/
|
||||
public class BinomialCoeffizient {
|
||||
|
||||
public static Double run(int n, int k) {
|
||||
int res = 1;
|
||||
|
||||
if ( k > n - k )
|
||||
k = n - k;
|
||||
|
||||
for (int i = 0; i < k; ++i){
|
||||
res *= (n - i);
|
||||
res /= (i + 1);
|
||||
}
|
||||
|
||||
return Double.valueOf(res);
|
||||
}
|
||||
}
|
|
@ -1,272 +0,0 @@
|
|||
package Presenter.Algorithms;
|
||||
|
||||
import Model.*;
|
||||
import Presenter.Algorithms.Comparators.YOrderLineComparatorBegin;
|
||||
import Presenter.Algorithms.Comparators.YOrderLineComparatorEnd;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
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 IntersectionCounter {
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Berechnet die Inversionen zwischen zwei Listen mit Integer Werten. Diese Methode dient als
|
||||
* Wrapper Methode. Die Logik steht in der <code>countInversions</code> Funktion.
|
||||
*
|
||||
* @param a Liste
|
||||
* @param b Liste
|
||||
* @return Anzahl an Inversionen
|
||||
*/
|
||||
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);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper Methode um herauszufinden wieviele Inversionen zwischen den Schnittpunkten der Werte
|
||||
* in der Liste und den Endpunkten des Intervalls entstehen.
|
||||
*
|
||||
* @param set Liste mit Werten (m,b) um Schnittpunkte zu berechnen
|
||||
* @param interval Interval
|
||||
* @return Anzahl an Inversionen
|
||||
*/
|
||||
public int run(List<Line> set, Interval interval) {
|
||||
ArrayList<Integer> listA = new ArrayList<>();
|
||||
ArrayList<Integer> listB = new ArrayList<>();
|
||||
|
||||
prepareData(set, interval, listA, listB);
|
||||
return run(listA, listB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Methode die, die Daten für die Funktion <code>run</code> vorbereitet. Es werden die Schnittpunkte
|
||||
* bzgl. der unteren und oberen Grenze des Intervals und den Werten der Liste (m,b) berechnet. Diese
|
||||
* Werte haben die selbe x Koordinate aber verschiedene y Koordinaten.
|
||||
*
|
||||
* @param set Liste mit Werten m,b
|
||||
* @param interval Interval
|
||||
* @param listA Schnittpunkte bzgl. unteren Grenze
|
||||
* @param listB Schnittpunkte bzgl. oberen Grenze
|
||||
*/
|
||||
private void prepareData(List<Line> set, Interval interval, 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(), interval.getLower() * p.getM() + p.getB(),
|
||||
interval.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 Temporäres Array das beim Mergen eine Kopie des original Arrays ist.
|
||||
* @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;
|
||||
//hier beginnt das merging
|
||||
//iteriere über die Teillisten
|
||||
//Two-way Merge - Knuth Vol 3 The Art of Computer Programming -
|
||||
while (left <= mid && right <= end) {
|
||||
//wenn die linke Teilliste das kleinere Element besitzt kopiere
|
||||
//das Element in das neue Array
|
||||
if (aux.get(left) < aux.get(right)) {
|
||||
a.set(index++, aux.get(left++));
|
||||
} else {
|
||||
//merke die inversionspaare
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
|
||||
*
|
||||
* @return Map mit Schnittpunkt Paaren.
|
||||
*/
|
||||
public HashMap<Line, ArrayList<Line>> getIntersectionLinePairs() {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
|
||||
*/
|
||||
public void calculateIntersectionAbscissas(LineModel model){
|
||||
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) {
|
||||
Line line = secondaryDictionaryBACK.get(p.getP1());
|
||||
Line sampledLine = secondaryDictionaryBACK.get(p.getP2());
|
||||
if (!line.equals(sampledLine)){
|
||||
double intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
|
||||
double yintercept = sampledLine.getM() * intersection + sampledLine.getB();
|
||||
model.addNode(new Point(intersection, yintercept));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet die Schnittpunkte zwischen einer gegebenen Gerade und einer Menge an Geraden.
|
||||
*
|
||||
* @param set Menge an Geraden
|
||||
* @param sampledLine eine spezielle Gerade
|
||||
* @return Liste mit x Koordinaten der Schnittpunkte
|
||||
*/
|
||||
public ArrayList<Double> calculateIntersectionAbscissas(ArrayList<Line> set, Line sampledLine){
|
||||
LinkedList<Line> lines = new LinkedList<>(set);
|
||||
ArrayList<Double> intersections = new ArrayList<>();
|
||||
double intersection;
|
||||
|
||||
for (Line line : lines) {
|
||||
if (line != sampledLine) {
|
||||
intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
|
||||
intersections.add(intersection);
|
||||
}
|
||||
}
|
||||
|
||||
return intersections;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,484 +0,0 @@
|
|||
package Presenter.Algorithms;
|
||||
|
||||
import Model.Interval;
|
||||
import Model.Line;
|
||||
import Model.Point;
|
||||
import Presenter.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Observable;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class LeastMedianOfSquaresEstimator extends Observable implements Algorithm {
|
||||
|
||||
|
||||
private Presenter presenter;
|
||||
|
||||
private LinkedList<Line> set = new LinkedList<>();
|
||||
private LinkedList<Point> intersections = new LinkedList<>();
|
||||
private IntersectionCounter invCounter = new IntersectionCounter();
|
||||
private int n;
|
||||
private double quantileError;
|
||||
private int kPlus;
|
||||
private int kMinus;
|
||||
private PriorityQueue<Interval> intervals;
|
||||
private Interval subSlabU1;
|
||||
private Interval subSlabU2;
|
||||
private Line sigmaMin;
|
||||
private double heightsigmaMin;
|
||||
private Double intersectionsPoint;
|
||||
private Double constant = 0.5;
|
||||
|
||||
private Double slope;
|
||||
private Double yInterception;
|
||||
|
||||
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections,
|
||||
Presenter presenter) {
|
||||
this.set = set;
|
||||
this.intersections = intersections;
|
||||
|
||||
//(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);....
|
||||
n = set.size();
|
||||
double quantile = 0.5;
|
||||
double qPlus = quantile;
|
||||
quantileError = 0.1;
|
||||
double qMinus = qPlus * (1 - quantileError);
|
||||
kMinus = (int) Math.ceil(n * qMinus);
|
||||
kPlus = (int) Math.ceil(n * qPlus);
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections) {
|
||||
this(set, intersections, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
//(2.) Let U <- (-inf, inf) be the initial active intervals...
|
||||
Comparator<Interval> comparator = (o1, o2) -> {
|
||||
if (o1.getDistance() < o2.getDistance()) {
|
||||
return -1;
|
||||
}
|
||||
if (o1.getDistance() > o2.getDistance()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
intervals = new PriorityQueue<>(comparator);
|
||||
intervals.add(new Interval(-100000, 100000));
|
||||
heightsigmaMin = Double.MAX_VALUE;
|
||||
LinkedList<Point> tmpIntersections = intersections;
|
||||
|
||||
//(3.) Apply the following steps as long as the exists active intervals
|
||||
boolean active = true;
|
||||
Interval interval;
|
||||
while (!this.intervals.isEmpty()) {
|
||||
interval = this.intervals.peek();
|
||||
if (interval.getActivity()) {
|
||||
//(a.) Select any active Interval and calc. the inversions
|
||||
int numberOfIntersections = countInversions(interval);
|
||||
|
||||
//(b.) apply plane sweep
|
||||
if ((constant * n) >= numberOfIntersections) {
|
||||
sigmaMin = planeSweep(interval);
|
||||
} 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() > interval.getLower()
|
||||
&& tmpIntersections.get(i).getX() < interval.getUpper()) {
|
||||
intersectionsPoint = tmpIntersections.get(i).getX();
|
||||
break;
|
||||
} else {
|
||||
intersectionsPoint = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (intersectionsPoint != null) {
|
||||
splitActiveSlab(intersectionsPoint, interval);
|
||||
//(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.intervals.add(subSlabU1);
|
||||
}
|
||||
if (subSlabU2.getActivity()) {
|
||||
this.intervals.add(subSlabU2);
|
||||
}
|
||||
|
||||
} else {
|
||||
this.intervals.poll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
this.intervals.remove(interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param interval
|
||||
* @return
|
||||
*/
|
||||
public int countInversions(Interval interval) {
|
||||
|
||||
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, interval);
|
||||
|
||||
return numberOfInversions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param interval
|
||||
* @return
|
||||
*/
|
||||
public Line planeSweep(Interval interval) {
|
||||
|
||||
//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() >= interval.getLower() && point.getX() < interval.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]);
|
||||
}
|
||||
}
|
||||
|
||||
interval.setActivity(false);
|
||||
return bracelet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode spaltet den aktiven Interval 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, Interval active) {
|
||||
subSlabU1 = new Interval(active.getLower() + 0.01, point);
|
||||
subSlabU2 = new Interval(point, active.getUpper());
|
||||
|
||||
this.intervals.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(Interval 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 {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResult() {
|
||||
if (presenter != null) {
|
||||
setChanged();
|
||||
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
|
||||
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
|
||||
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
|
||||
String[] result = {"lms", m+"", b+""};
|
||||
notifyObservers(result);
|
||||
} else {
|
||||
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
|
||||
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
|
||||
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den
|
||||
* JUnit Testfällen.
|
||||
*/
|
||||
|
||||
public LinkedList<Line> getSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
public void setSet(LinkedList<Line> set) {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public LinkedList<Point> getIntersections() {
|
||||
return intersections;
|
||||
}
|
||||
|
||||
public void setIntersections(LinkedList<Point> intersections) {
|
||||
this.intersections = intersections;
|
||||
}
|
||||
|
||||
public int getN() {
|
||||
return n;
|
||||
}
|
||||
|
||||
public void setN(int n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public double getQuantileError() {
|
||||
return quantileError;
|
||||
}
|
||||
|
||||
public void setQuantileError(double quantileError) {
|
||||
this.quantileError = quantileError;
|
||||
}
|
||||
|
||||
public int getkPlus() {
|
||||
return kPlus;
|
||||
}
|
||||
|
||||
public void setkPlus(int kPlus) {
|
||||
this.kPlus = kPlus;
|
||||
}
|
||||
|
||||
public int getkMinus() {
|
||||
return kMinus;
|
||||
}
|
||||
|
||||
public void setkMinus(int kMinus) {
|
||||
this.kMinus = kMinus;
|
||||
}
|
||||
|
||||
public Interval getSubSlabU1() {
|
||||
return subSlabU1;
|
||||
}
|
||||
|
||||
public void setSubSlabU1(Interval subSlabU1) {
|
||||
this.subSlabU1 = subSlabU1;
|
||||
}
|
||||
|
||||
public Interval getSubSlabU2() {
|
||||
return subSlabU2;
|
||||
}
|
||||
|
||||
public void setSubSlabU2(Interval subSlabU2) {
|
||||
this.subSlabU2 = subSlabU2;
|
||||
}
|
||||
|
||||
public Line getSigmaMin() {
|
||||
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;
|
||||
}
|
||||
|
||||
public Double getSlope() {
|
||||
return slope;
|
||||
}
|
||||
|
||||
public Double getyInterception() {
|
||||
return yInterception;
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package Presenter.Algorithms;
|
||||
|
||||
import Model.Line;
|
||||
import Model.Point;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 26.06.2017.
|
||||
*/
|
||||
public class RandomSampler {
|
||||
|
||||
/**
|
||||
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe an Geraden.
|
||||
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
|
||||
* @param r Anzahl der zu wählenden Geraden
|
||||
* @return <code>r</code> Elementige zufällige Stichprobe an Geraden
|
||||
*/
|
||||
public static ArrayList<Line> run(ArrayList<Line> set, Double r, Integer indexOfEnd) {
|
||||
|
||||
ArrayList<Line> sampledLines = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < r; i++) {
|
||||
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, indexOfEnd)));
|
||||
}
|
||||
|
||||
return sampledLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe van Schnittpunkten.
|
||||
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
|
||||
* @param r Anzahl der zu wählenden Geraden
|
||||
* @return <code>r</code> Elementige zufällige Stichprobe an Schnittpunkten
|
||||
*/
|
||||
public static ArrayList<Double> run(ArrayList<Point> set, Double r) {
|
||||
|
||||
ArrayList<Double> sampledLines = new ArrayList<>();
|
||||
Integer indexOfEnd = set.size();
|
||||
|
||||
for (int i = 0; i < r; i++) {
|
||||
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, indexOfEnd)).getX());
|
||||
}
|
||||
|
||||
return sampledLines;
|
||||
}
|
||||
}
|
|
@ -1,459 +0,0 @@
|
|||
package Presenter.Algorithms;
|
||||
|
||||
import Model.Interval;
|
||||
import Model.Line;
|
||||
import Presenter.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class RepeatedMedianEstimator extends Observable implements Algorithm {
|
||||
|
||||
private Presenter presenter;
|
||||
private LinkedList<Line> set;
|
||||
private HashMap<Line, ArrayList<Line>> linePairs;
|
||||
private HashMap<Line, Double> medianIntersections = new HashMap<>();
|
||||
private HashMap<Line, ArrayList<Double>> intersectionAbscissas = new HashMap<>();
|
||||
private Interval interval;
|
||||
|
||||
//in der Literatur als L_i, C_i, und R_i bekannt
|
||||
private ArrayList<Double> countLeftSlab;
|
||||
private ArrayList<Double> countCenterSlab;
|
||||
private ArrayList<Double> countRightSlab;
|
||||
|
||||
//die Mengen L,C und R
|
||||
private ArrayList<Line> linesInLeftSlab;
|
||||
private ArrayList<Line> linesInCenterSlab;
|
||||
private ArrayList<Line> linesInRightSlab;
|
||||
|
||||
private Double r;
|
||||
private Integer n;
|
||||
private Double k;
|
||||
private Double kLow;
|
||||
private Double kHigh;
|
||||
private Double beta;
|
||||
|
||||
private Double thetaLow;
|
||||
private Double thetaHigh;
|
||||
|
||||
private Double slope;
|
||||
private Double yInterception;
|
||||
|
||||
|
||||
public RepeatedMedianEstimator(LinkedList<Line> set, Presenter presenter) {
|
||||
this.set = set;
|
||||
this.presenter = presenter;
|
||||
interval = new Interval(-10000, 10000);
|
||||
n = set.size();
|
||||
beta = 0.5;
|
||||
countLeftSlab = new ArrayList<>();
|
||||
countCenterSlab = new ArrayList<>();
|
||||
countRightSlab = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
countLeftSlab.add(0d);
|
||||
countRightSlab.add(0d);
|
||||
countCenterSlab.add(n - 1.0);
|
||||
intersectionAbscissas.put(set.get(i), new ArrayList<>());
|
||||
}
|
||||
|
||||
linesInLeftSlab = new ArrayList<>();
|
||||
linesInCenterSlab = new ArrayList<>(set);
|
||||
linesInRightSlab = new ArrayList<>();
|
||||
linePairs = new HashMap<>();
|
||||
}
|
||||
|
||||
public RepeatedMedianEstimator(LinkedList<Line> set) {
|
||||
this(set,null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
while (linesInCenterSlab.size() != 1) {
|
||||
n = linesInCenterSlab.size();
|
||||
r = Math.ceil(Math.pow(n, beta));
|
||||
ArrayList<Line> lines = RandomSampler.run(linesInCenterSlab, r, linesInCenterSlab.size());
|
||||
|
||||
|
||||
//For each Sampled Line, compute its median intersection abscissa
|
||||
ArrayList<Double> medianIntersectionAbscissas = new ArrayList<>();
|
||||
for (Line l : lines) {
|
||||
Double abscissa = estimateMedianIntersectionAbscissas(l);
|
||||
medianIntersections.put(l, abscissa);
|
||||
medianIntersectionAbscissas.add(abscissa);
|
||||
}
|
||||
|
||||
//rank of the repeated median in C
|
||||
k = Math.max(1,Math.min(set.size(),(Math.ceil(n * 0.5) - linesInLeftSlab.size())));
|
||||
|
||||
//compute k_lo and k_hi
|
||||
computeSlabBorders();
|
||||
|
||||
|
||||
// if (medianIntersectionAbscissas.size() < kLow || medianIntersectionAbscissas.size()<kHigh || kLow < 0 || kHigh<0 )
|
||||
// System.err.print("#medianIntersectionAbscissa: "+medianIntersectionAbscissas.size()+"\t\t klow: "+kLow+" kHigh: "+kHigh+"\n\n");
|
||||
|
||||
//Employ fast selection algorithm to determine the Elements Theta_lo and Theta_hi
|
||||
thetaLow = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kLow);
|
||||
thetaHigh = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kHigh);
|
||||
|
||||
//For each dual Line in C count the number of intersection abscissas that lie
|
||||
//in each of the intervals.
|
||||
countNumberOfIntersectionsAbscissas();
|
||||
|
||||
//Based on this 3 counts, determine which of the subintervals contains the repeated median
|
||||
//and contract to this subiinterval.
|
||||
contractIntervals();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param set
|
||||
* @param r
|
||||
* @return
|
||||
*/
|
||||
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, linesInCenterSlab.size())));
|
||||
}
|
||||
|
||||
return sampledLines;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sampledLine
|
||||
* @return
|
||||
*/
|
||||
public Double estimateMedianIntersectionAbscissas(Line sampledLine) {
|
||||
|
||||
Integer index = Integer.parseInt(sampledLine.getId());
|
||||
ArrayList<Double> intersections = new ArrayList<>();
|
||||
double intersection;
|
||||
|
||||
IntersectionCounter intersectionCounter = new IntersectionCounter();
|
||||
intersections = intersectionCounter.calculateIntersectionAbscissas(linesInCenterSlab, sampledLine);
|
||||
|
||||
//Collections.sort(intersections);
|
||||
//double ki = Math.ceil((n - 1) / 2) - countLeftSlab.get(index);
|
||||
//double i = (Math.ceil((Math.sqrt(n) * ki) / countCenterSlab.get(index)));
|
||||
double ki = Math.ceil((n - 1) / 2) - FastElementSelector.randomizedSelect(countLeftSlab, index);
|
||||
double i = (Math.ceil((Math.sqrt(n) * ki) / FastElementSelector.randomizedSelect(countCenterSlab, index)));
|
||||
int accessIndex;
|
||||
if (i < 0)
|
||||
accessIndex = 0;
|
||||
else if (i >= intersections.size())
|
||||
accessIndex = intersections.size()-1;
|
||||
else
|
||||
accessIndex = (int) i;
|
||||
|
||||
//System.out.println(accessIndex);
|
||||
|
||||
//return intersections.get(accessIndex);
|
||||
return FastElementSelector.randomizedSelect(intersections, accessIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void computeSlabBorders() {
|
||||
kLow = Math
|
||||
.max(1, Math.floor(
|
||||
( (r * k) / (linesInCenterSlab.size()))
|
||||
- ( (3 * Math.sqrt(r)) / (2))
|
||||
)
|
||||
);
|
||||
kHigh = Math
|
||||
.min(r, Math.floor(
|
||||
((r * k) / (linesInCenterSlab.size()))
|
||||
+ ((3 * Math.sqrt(r)) / (2))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void countNumberOfIntersectionsAbscissas() {
|
||||
|
||||
for (Line line : linesInCenterSlab) {
|
||||
ArrayList<Double> intersections = intersectionAbscissas.get(line);
|
||||
Integer index = Integer.parseInt(line.getId());
|
||||
int left = 0;
|
||||
int center = 0;
|
||||
int right = 0;
|
||||
|
||||
for (Double intersection : intersections) {
|
||||
if (intersection <= thetaLow) {
|
||||
left++;
|
||||
} else if (intersection > thetaLow && intersection <= thetaHigh) {
|
||||
center++;
|
||||
} else if (intersection > thetaHigh){
|
||||
right++;
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("Linie: "+line.getId()+"\tLeft: "+left+"\t Center: "+center+"\t Right: "+right);
|
||||
countLeftSlab.set(index, (double) left);
|
||||
countCenterSlab.set(index, (double) center);
|
||||
countRightSlab.set(index, (double) right);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void contractIntervals() {
|
||||
for (int i = 0; i < linesInCenterSlab.size(); i++) {
|
||||
|
||||
double left = countLeftSlab.get(i);
|
||||
double center = countCenterSlab.get(i);
|
||||
double right = countRightSlab.get(i);
|
||||
|
||||
double max = Math.max(left, Math.max(center, right));
|
||||
|
||||
if (left == max){
|
||||
linesInLeftSlab.add(linesInCenterSlab.get(i));
|
||||
linesInCenterSlab.remove(i);
|
||||
} else if (right == max) {
|
||||
linesInRightSlab.add(linesInCenterSlab.get(i));
|
||||
linesInCenterSlab.remove(i);
|
||||
}
|
||||
// if (medianIntersections.get(linesInCenterSlab.get(i)) != null) {
|
||||
// if (medianIntersections.get(linesInCenterSlab.get(i)) <= thetaLow) {
|
||||
// linesInLeftSlab.add(linesInCenterSlab.get(i));
|
||||
// linesInCenterSlab.remove(i);
|
||||
// countLeftSlab.set(i, countLeftSlab.get(i) + 1);
|
||||
// countCenterSlab.set(i, countCenterSlab.get(i) - 1);
|
||||
// } else if (medianIntersections.get(linesInCenterSlab.get(i)) > thetaHigh) {
|
||||
// linesInRightSlab.add(linesInCenterSlab.get(i));
|
||||
// linesInCenterSlab.remove(i);
|
||||
// countRightSlab.set(i, countRightSlab.get(i) + 1);
|
||||
// countCenterSlab.set(i, countCenterSlab.get(i) - 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
}
|
||||
|
||||
//wähle C als C
|
||||
if (linesInLeftSlab.size() < Math.ceil(n/2) && Math.ceil(n/2) <= linesInLeftSlab.size()+linesInCenterSlab.size()){
|
||||
interval.setLower(thetaLow + 0.1);
|
||||
interval.setUpper(thetaHigh);
|
||||
}
|
||||
// wähle L als C
|
||||
else if (Math.ceil(n/2) <= linesInLeftSlab.size()){
|
||||
interval.setUpper(thetaLow);
|
||||
}
|
||||
//wähle R als C
|
||||
else if (linesInLeftSlab.size()+linesInCenterSlab.size() < Math.ceil(n/2) && Math.ceil(n/2) <= (linesInLeftSlab.size()+linesInCenterSlab.size()+linesInRightSlab.size()) ){
|
||||
interval.setLower(thetaHigh - 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResult() {
|
||||
if (presenter != null) {
|
||||
setChanged();
|
||||
double m = thetaLow;
|
||||
double b = (-1)*(
|
||||
(linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0)
|
||||
.getB());
|
||||
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
String[] result = new String[]{"rm", m+"", b+""};
|
||||
notifyObservers(result);
|
||||
}else {
|
||||
double m = thetaLow;
|
||||
double b = (-1)*((linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0).getB());
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* Getter und Setter Methoden
|
||||
******************************************************************************************************************/
|
||||
public LinkedList<Line> getSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
public void setSet(LinkedList<Line> set) {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public HashMap<Line, ArrayList<Line>> getLinePairs() {
|
||||
return linePairs;
|
||||
}
|
||||
|
||||
public void setLinePairs(HashMap<Line, ArrayList<Line>> linePairs) {
|
||||
this.linePairs = linePairs;
|
||||
}
|
||||
|
||||
public HashMap<Line, Double> getMedianIntersections() {
|
||||
return medianIntersections;
|
||||
}
|
||||
|
||||
public void setMedianIntersections(HashMap<Line, Double> medianIntersections) {
|
||||
this.medianIntersections = medianIntersections;
|
||||
}
|
||||
|
||||
public HashMap<Line, ArrayList<Double>> getIntersectionAbscissas() {
|
||||
return intersectionAbscissas;
|
||||
}
|
||||
|
||||
public void setIntersectionAbscissas(
|
||||
HashMap<Line, ArrayList<Double>> intersectionAbscissas) {
|
||||
this.intersectionAbscissas = intersectionAbscissas;
|
||||
}
|
||||
|
||||
public Interval getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public void setInterval(Interval interval) {
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
public ArrayList<Double> getCountLeftSlab() {
|
||||
return countLeftSlab;
|
||||
}
|
||||
|
||||
public void setCountLeftSlab(ArrayList<Double> countLeftSlab) {
|
||||
this.countLeftSlab = countLeftSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Double> getCountCenterSlab() {
|
||||
return countCenterSlab;
|
||||
}
|
||||
|
||||
public void setCountCenterSlab(ArrayList<Double> countCenterSlab) {
|
||||
this.countCenterSlab = countCenterSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Double> getCountRightSlab() {
|
||||
return countRightSlab;
|
||||
}
|
||||
|
||||
public void setCountRightSlab(ArrayList<Double> countRightSlab) {
|
||||
this.countRightSlab = countRightSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Line> getLinesInLeftSlab() {
|
||||
return linesInLeftSlab;
|
||||
}
|
||||
|
||||
public void setLinesInLeftSlab(ArrayList<Line> linesInLeftSlab) {
|
||||
this.linesInLeftSlab = linesInLeftSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Line> getLinesInCenterSlab() {
|
||||
return linesInCenterSlab;
|
||||
}
|
||||
|
||||
public void setLinesInCenterSlab(ArrayList<Line> linesInCenterSlab) {
|
||||
this.linesInCenterSlab = linesInCenterSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Line> getLinesInRightSlab() {
|
||||
return linesInRightSlab;
|
||||
}
|
||||
|
||||
public void setLinesInRightSlab(ArrayList<Line> linesInRightSlab) {
|
||||
this.linesInRightSlab = linesInRightSlab;
|
||||
}
|
||||
|
||||
public Double getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
public void setR(Double r) {
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
public Integer getN() {
|
||||
return n;
|
||||
}
|
||||
|
||||
public void setN(Integer n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public Double getK() {
|
||||
return k;
|
||||
}
|
||||
|
||||
public void setK(Double k) {
|
||||
this.k = k;
|
||||
}
|
||||
|
||||
public Double getkLow() {
|
||||
return kLow;
|
||||
}
|
||||
|
||||
public void setkLow(Double kLow) {
|
||||
this.kLow = kLow;
|
||||
}
|
||||
|
||||
public Double getkHigh() {
|
||||
return kHigh;
|
||||
}
|
||||
|
||||
public void setkHigh(Double kHigh) {
|
||||
this.kHigh = kHigh;
|
||||
}
|
||||
|
||||
public Double getBeta() {
|
||||
return beta;
|
||||
}
|
||||
|
||||
public void setBeta(Double beta) {
|
||||
this.beta = beta;
|
||||
}
|
||||
|
||||
public Double getThetaLow() {
|
||||
return thetaLow;
|
||||
}
|
||||
|
||||
public void setThetaLow(Double thetaLow) {
|
||||
this.thetaLow = thetaLow;
|
||||
}
|
||||
|
||||
public Double getThetaHigh() {
|
||||
return thetaHigh;
|
||||
}
|
||||
|
||||
public void setThetaHigh(Double thetaHigh) {
|
||||
this.thetaHigh = thetaHigh;
|
||||
}
|
||||
|
||||
public Double getSlope() {
|
||||
return slope;
|
||||
}
|
||||
|
||||
public Double getyInterception() {
|
||||
return yInterception;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
package Presenter.Evaluation;
|
||||
|
||||
import Model.Line;
|
||||
import Presenter.Algorithms.FastElementSelector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 07.09.2017.
|
||||
*/
|
||||
public class PercentageErrorBasedMeasure {
|
||||
|
||||
|
||||
private ArrayList<Double> percentageError;
|
||||
|
||||
public PercentageErrorBasedMeasure(final LinkedList<Line> lines, Double m, Double b){
|
||||
|
||||
ArrayList<Double> sampson = new ArrayList<>();
|
||||
|
||||
for (Line line : lines) {
|
||||
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
|
||||
sampson.add(e);
|
||||
}
|
||||
|
||||
percentageError = new ArrayList<>();
|
||||
|
||||
for (int j=0;j<sampson.size();j++){
|
||||
percentageError.add(100 * sampson.get(j) / lines.get(j).getB());
|
||||
}
|
||||
}
|
||||
|
||||
/* Percentege Error Approximation Measures */
|
||||
//verschiedene Eingaben für einen Alg.
|
||||
public Double mape(){
|
||||
double error = 0;
|
||||
|
||||
for (Double d : percentageError) {
|
||||
error += Math.abs(d);
|
||||
}
|
||||
|
||||
error /= percentageError.size();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double mdape(){
|
||||
|
||||
ArrayList<Double> abs = new ArrayList<>();
|
||||
|
||||
for (Double d : percentageError){
|
||||
abs.add(Math.abs(d));
|
||||
}
|
||||
|
||||
return FastElementSelector.randomizedSelect(abs, abs.size() * 0.5);
|
||||
}
|
||||
|
||||
public Double rmspe(){
|
||||
double error = 0;
|
||||
|
||||
for (Double d : percentageError) {
|
||||
error += Math.pow(d, 2);
|
||||
}
|
||||
|
||||
error /= percentageError.size();
|
||||
|
||||
return Math.sqrt(error);
|
||||
}
|
||||
|
||||
public Double rmdspe(){
|
||||
ArrayList squares = new ArrayList();
|
||||
for (Double d : percentageError){
|
||||
squares.add(Math.pow(d,2));
|
||||
}
|
||||
|
||||
return Math.sqrt(FastElementSelector.randomizedSelect(squares, squares.size() * 0.5));
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package Presenter.Evaluation;
|
||||
|
||||
import Model.Line;
|
||||
import Presenter.Algorithms.FastElementSelector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 07.09.2017.
|
||||
*/
|
||||
public class ScaleDependentMeasure {
|
||||
|
||||
private ArrayList<Double> errorValues;
|
||||
|
||||
public ScaleDependentMeasure(final LinkedList<Line> lines, Double m, Double b){
|
||||
//Liste mit den Fehler zu jedem Punkt
|
||||
errorValues = new ArrayList<>();
|
||||
|
||||
for (Line line : lines) {
|
||||
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
|
||||
errorValues.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skalierungs Abhängige Approximationsgüten */
|
||||
//unterschiedliche Alg.- auf einem Datensatz
|
||||
public Double mse() {
|
||||
double error = 0;
|
||||
|
||||
for (Double d : errorValues) {
|
||||
error += Math.pow(d, 2);
|
||||
}
|
||||
|
||||
error /= errorValues.size();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double rmse() {
|
||||
return Math.sqrt(mse());
|
||||
}
|
||||
|
||||
public Double mae() {
|
||||
double error = 0;
|
||||
for (Double d : errorValues) {
|
||||
error += Math.abs(d);
|
||||
}
|
||||
error /= errorValues.size();
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double mdae() {
|
||||
return FastElementSelector
|
||||
.randomizedSelect(errorValues, errorValues.size() * 0.5);
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package Presenter.Evaluation;
|
||||
|
||||
import Model.Line;
|
||||
import Presenter.Algorithms.FastElementSelector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 07.09.2017.
|
||||
*/
|
||||
public class ScaledErrorBasedMeasure {
|
||||
|
||||
|
||||
private ArrayList<Double> scaledError;
|
||||
|
||||
public ScaledErrorBasedMeasure(final LinkedList<Line> lines, Double m, Double b){
|
||||
//Liste mit den Fehler zu jedem Punkt
|
||||
ArrayList<Double> sampson = new ArrayList<>();
|
||||
|
||||
|
||||
Double denum = 0d;
|
||||
for (int i=2;i<lines.size();i++){
|
||||
denum += Math.abs(lines.get(i).getM() - lines.get(i-1).getM());
|
||||
}
|
||||
denum *= 1/(lines.size() - 1);
|
||||
|
||||
for (Line line : lines) {
|
||||
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
|
||||
sampson.add(e);
|
||||
|
||||
Double val = e / (denum);
|
||||
scaledError.add(val);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Skalierungs Abhängige Approximationsgüten */
|
||||
//unterschiedliche Alg.- auf einem Datensatz
|
||||
public Double mse() {
|
||||
double error = 0;
|
||||
for (Double d : scaledError) {
|
||||
error += Math.pow(d, 2);
|
||||
}
|
||||
error /= scaledError.size();
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double rmse() {
|
||||
return Math.sqrt(mse());
|
||||
}
|
||||
|
||||
public Double mae() {
|
||||
double error = 0;
|
||||
for (Double d : scaledError) {
|
||||
error += Math.abs(d);
|
||||
}
|
||||
error /= scaledError.size();
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double mdae() {
|
||||
return FastElementSelector
|
||||
.randomizedSelect(scaledError, scaledError.size() * 0.5);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package Presenter.ImportExport;
|
||||
|
||||
import Model.LineModel;
|
||||
import Model.Line;
|
||||
import Presenter.Presenter;
|
||||
import com.opencsv.CSVReader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 21.06.2017.
|
||||
*/
|
||||
public class DataImporter extends Observable{
|
||||
|
||||
private File file;
|
||||
private CSVReader reader;
|
||||
private LineModel model;
|
||||
private Presenter presenter;
|
||||
|
||||
|
||||
public DataImporter(File file, Presenter presenter) {
|
||||
this.model = new LineModel();
|
||||
this.presenter = presenter;
|
||||
this.presenter.setModel(this.model);
|
||||
//System.out.println(this.model.getLines().size()+ " die Anzahl der aktuellen Lines.");
|
||||
|
||||
|
||||
this.file = file;
|
||||
try {
|
||||
|
||||
this.reader = new CSVReader(new FileReader(file));
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void run(){
|
||||
|
||||
try {
|
||||
List<String[]> lines = reader.readAll();
|
||||
int counter = 0;
|
||||
String[] result = {"import", lines.size()+"", ""};
|
||||
//System.out.println("+-------------------------------------------------------------------------------+");
|
||||
for(String[] nextLine : lines) {
|
||||
// nextLine[] is an array of values from the line
|
||||
Double x = Double.parseDouble(nextLine[1]);
|
||||
Double y = Double.parseDouble(nextLine[2]) * (-1);
|
||||
Line line = new Line(x,y);
|
||||
line.setId(counter+"");
|
||||
this.presenter.getModel().addLine(line);
|
||||
//System.out.format("|\t\t\t\t\t %-11d \t|\t\t\t\t\t %-11f \t|\t\t\t\t\t %-11f \t\t\t\t\t|\n", id,x,y);
|
||||
setChanged();
|
||||
counter++;
|
||||
result[2] = counter + "";
|
||||
Thread.sleep(1);
|
||||
notifyObservers(result);
|
||||
}
|
||||
|
||||
//System.out.println("+-------------------------------------------------------------------------------+");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
package Presenter.ImportExport;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 08.09.2017.
|
||||
*/
|
||||
public class EvalResultLatexExport {
|
||||
|
||||
private DefaultTableModel model;
|
||||
private File file;
|
||||
|
||||
public EvalResultLatexExport(DefaultTableModel model, File file ) {
|
||||
this.model = model;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* e.g. Source: <url>https://en.wikibooks.org/wiki/LaTeX/Tables</url>
|
||||
* \begin{tabular}{l*{3}{c}}
|
||||
* Team & P & W & D & L & F & A & Pts \\\hline
|
||||
* Manchester United & 6 & 4 & 0 & 2 & 10 & 5 & 12 \\
|
||||
* Celtic & 6 & 3 & 0 & 3 & 8 & 9 & 9 \\
|
||||
* Benfica & 6 & 2 & 1 & 3 & 7 & 8 & 7 \\
|
||||
* FC Copenhagen & 6 & 2 & 1 & 3 & 5 & 8 & 7 \\
|
||||
* \end{tabular}
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String createOutputData(){
|
||||
String split = "&";
|
||||
StringBuilder doc = new StringBuilder();
|
||||
doc.append("\\begin{tabular}{l|*{3}{r}}"+"\r\n");
|
||||
for (int i=0;i<model.getColumnCount();i++){
|
||||
if (model.getValueAt(0,i).toString() != "" || model.getRowCount() > 5)
|
||||
doc.append("\\textsc{" + model.getColumnName(i) + "}"+split);
|
||||
}
|
||||
|
||||
doc.deleteCharAt(doc.lastIndexOf(split));
|
||||
doc.append("\\\\\\hline\\hline"+"\r\n");
|
||||
|
||||
for (int i=0;i<model.getRowCount()-1;i++){
|
||||
for (int j=0;j<model.getColumnCount();j++){
|
||||
if (model.getValueAt(i,j).toString() != "") {
|
||||
if (j == 0){
|
||||
doc.append("\\textbf{"+model.getValueAt(i, j).toString()+ "}" + split);
|
||||
} else {
|
||||
Double val = Double.parseDouble((String) model.getValueAt(i, j));
|
||||
doc.append(String.format("%.3f",val) + split);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (model.getValueAt(i,0) != "") {
|
||||
doc.deleteCharAt(doc.lastIndexOf(split));
|
||||
}
|
||||
doc.append("\\\\"+"\r\n");
|
||||
}
|
||||
doc.append("\\end{tabular}");
|
||||
return doc.toString();
|
||||
}
|
||||
|
||||
public void writeFile(){
|
||||
FileWriter fileWriter = null;
|
||||
BufferedWriter bufferedWriter = null;
|
||||
try {
|
||||
fileWriter = new FileWriter(file);
|
||||
bufferedWriter = new BufferedWriter(fileWriter);
|
||||
bufferedWriter.write(createOutputData());
|
||||
SwingUtilities.invokeLater(()->{
|
||||
JOptionPane.showMessageDialog(null,"Export war Erfolgreich!");
|
||||
});
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
bufferedWriter.close();
|
||||
fileWriter.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,384 +0,0 @@
|
|||
package Presenter;
|
||||
|
||||
import Model.LineModel;
|
||||
import Model.Interval;
|
||||
import Model.Line;
|
||||
import Presenter.Algorithms.IntersectionCounter;
|
||||
import Presenter.Algorithms.LeastMedianOfSquaresEstimator;
|
||||
import Presenter.Algorithms.RepeatedMedianEstimator;
|
||||
import Presenter.Algorithms.TheilSenEstimator;
|
||||
import Presenter.Evaluation.EvaluateAlgorithms;
|
||||
import Presenter.Generator.DatasetGenerator;
|
||||
import Presenter.ImportExport.DataExporter;
|
||||
import Presenter.ImportExport.DataImporter;
|
||||
import Presenter.ImportExport.EvalResultLatexExport;
|
||||
import View.MainFrame;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class Presenter implements Observer {
|
||||
|
||||
private LineModel model;
|
||||
private MainFrame view;
|
||||
private EvaluateAlgorithms eval;
|
||||
|
||||
/* Threads */
|
||||
private Thread tsThread;
|
||||
private Thread rmThread;
|
||||
private Thread lmsThread;
|
||||
private Thread importThread;
|
||||
private Thread exportThread;
|
||||
private Thread exportResultThread;
|
||||
private Thread generatorThread;
|
||||
private Thread evalThread;
|
||||
|
||||
public Presenter(LineModel model, MainFrame view) {
|
||||
this.model = model;
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
String[] result = ((String[]) arg);
|
||||
|
||||
if (result[0] == "eval-dataset-generated"){
|
||||
SwingUtilities.invokeLater(() -> getView().addEvalDataset(eval.getData()));
|
||||
}
|
||||
|
||||
if (result[0] == "eval-d"){
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result,Integer.parseInt(result[1]),false));
|
||||
}
|
||||
|
||||
if (result[0] == "eval-ds"){
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result));
|
||||
}
|
||||
|
||||
if (result[0] == "eval-t"){
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result,Integer.parseInt(result[1]),true));
|
||||
}
|
||||
|
||||
if (result[0] == "lines-res"){
|
||||
SwingUtilities.invokeLater(() -> getView().drawLineResult(result, Integer.parseInt(result[1])));
|
||||
}
|
||||
|
||||
if (result[0] == "lines-res-mult"){
|
||||
SwingUtilities.invokeLater(() -> getView().drawLineResults(result));
|
||||
}
|
||||
|
||||
if (result[0] == "lms"){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().visualizeLMS(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
|
||||
//getView().setLmsIsComplete(true);
|
||||
getView().logHeading("Least Median of Squares");
|
||||
getView().log("<b>m:</b> " + result[1]);
|
||||
getView().log("<b>b:</b> " + result[2]);
|
||||
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
|
||||
});
|
||||
}
|
||||
|
||||
if (result[0] == "rm"){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().visualizeRM(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
|
||||
getView().logHeading("Repeated Median Estimator");
|
||||
getView().log("<b>m:</b> " + result[1]);
|
||||
getView().log("<b>b:</b> " + result[2]);
|
||||
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
|
||||
});
|
||||
}
|
||||
|
||||
if (result[0] == "ts"){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().visualizeTS(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
|
||||
getView().logHeading("Theil-Sen Estimator");
|
||||
getView().log("<b>m:</b> " + result[1]);
|
||||
getView().log("<b>b:</b> " + result[2]);
|
||||
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
|
||||
});
|
||||
}
|
||||
|
||||
if (result[0] == "import"){
|
||||
Double max = Double.parseDouble(result[1]);
|
||||
Double current = Double.parseDouble(result[2]);
|
||||
Integer progress = (int) (100 * (current/max));
|
||||
//100% erreicht
|
||||
if (progress == 100){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().showImportProgress(progress);
|
||||
getView().enableFunctionality();
|
||||
getView().getProgressDialog().dispose();
|
||||
});
|
||||
setup();
|
||||
Thread t = new Thread(() -> {
|
||||
calculateIntersections();
|
||||
});
|
||||
t.start();
|
||||
try {
|
||||
t.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().showImportProgress(progress);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (result[0] == "export"){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().logSuccess("Export Erfolgreich");
|
||||
getView().log(result[1]+"<hr>");
|
||||
});
|
||||
}
|
||||
|
||||
if (result[0] == "generator"){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().logSuccess("Generierung Erfolgreich");
|
||||
getView().log(result[1]);
|
||||
getView().log(result[2]);
|
||||
getView().log(result[3] + "<hr>");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void visualizeDualLines() {
|
||||
view.createDualityDialog();
|
||||
}
|
||||
|
||||
/***************************************************************************************************************************
|
||||
* Ausführung der Algorithmen
|
||||
***************************************************************************************************************************/
|
||||
public void calculateLMS(String[] input) {
|
||||
if (input[0] != null && input[1] != null){
|
||||
if (lmsThread == null || !lmsThread.isAlive()){
|
||||
lmsThread = new Thread(() -> {
|
||||
Double constant = Double.parseDouble(input[0]);
|
||||
Double error = Double.parseDouble(input[1]);
|
||||
LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
|
||||
lms.setConstant(constant);
|
||||
lms.setQuantileError(error);
|
||||
lms.addObserver(this);
|
||||
lms.run();
|
||||
lms.getResult();
|
||||
});
|
||||
lmsThread.start();
|
||||
try {
|
||||
lmsThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateRM(String input){
|
||||
if (input != null){
|
||||
if (rmThread == null || !rmThread.isAlive()){
|
||||
rmThread = new Thread(() -> {
|
||||
RepeatedMedianEstimator rm = new RepeatedMedianEstimator(getModel().getLines(), this);
|
||||
Double parameter = Double.parseDouble(input);
|
||||
rm.setBeta(parameter);
|
||||
rm.addObserver(this);
|
||||
rm.run();
|
||||
rm.getResult();
|
||||
});
|
||||
rmThread.start();
|
||||
try {
|
||||
rmThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateTS(String input){
|
||||
if (input != null){
|
||||
if (tsThread == null || !tsThread.isAlive()){
|
||||
tsThread = new Thread(() ->{
|
||||
TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(),this);
|
||||
ts.addObserver(this);
|
||||
ts.run();
|
||||
ts.getResult();
|
||||
});
|
||||
tsThread.start();
|
||||
try {
|
||||
tsThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************************************************
|
||||
* Hilfsmethoden
|
||||
***************************************************************************************************************************/
|
||||
public void setup(){
|
||||
//Darstellung der Schnittpunkte in einer Tabelle
|
||||
List<String> heading = new LinkedList<>();
|
||||
List<List<String>> rows = new LinkedList<>();
|
||||
heading.add("Geraden");
|
||||
for (int j = 0; j < getModel().getLines().size()-2; j++) {
|
||||
LinkedList<String> rowEntry = new LinkedList<>();
|
||||
Line p1 = getModel().getLines().get(j);
|
||||
rowEntry.add("f(x) = " + p1.getM() + "x + " + p1.getB());
|
||||
|
||||
if (j+1 < getModel().getLines().size()){
|
||||
Line p2 = getModel().getLines().get(j+1);
|
||||
rowEntry.add("f(x) = " + p2.getM() + "x + " + p2.getB());
|
||||
}
|
||||
|
||||
if (j+2 < getModel().getLines().size()){
|
||||
Line p3 = getModel().getLines().get(j+2);
|
||||
rowEntry.add("f(x) = " + p3.getM() + "x + " + p3.getB());
|
||||
}
|
||||
rows.add(rowEntry);
|
||||
}
|
||||
getView().logHeading("Schnittpunkte der Dualen Geraden:");
|
||||
getView().createTable(heading, rows);
|
||||
|
||||
getView().log("<hr>");
|
||||
}
|
||||
|
||||
public void calculateIntersections() {
|
||||
try {
|
||||
Thread thread = new Thread(() -> {
|
||||
IntersectionCounter counter = new IntersectionCounter();
|
||||
counter.run(getLines(), new Interval(-99999,99999));
|
||||
counter.calculateIntersectionAbscissas(getModel());
|
||||
getModel().setXbounds();
|
||||
getModel().setYbounds();
|
||||
|
||||
});
|
||||
thread.start();
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void startImport(File file){
|
||||
if (importThread == null || !importThread.isAlive()){
|
||||
importThread = new Thread(()->{
|
||||
DataImporter importer = new DataImporter(file, this);
|
||||
importer.addObserver(this);
|
||||
importer.run();
|
||||
});
|
||||
importThread.start();
|
||||
try {
|
||||
importThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startExport(File file){
|
||||
if (exportThread == null || !exportThread.isAlive()){
|
||||
exportThread = new Thread(()->{
|
||||
DataExporter exporter = new DataExporter(getModel(), file);
|
||||
exporter.addObserver(this);
|
||||
exporter.export();
|
||||
});
|
||||
exportThread.start();
|
||||
try {
|
||||
exportThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startResultExport(DefaultTableModel model, File file){
|
||||
if (exportResultThread == null || !exportResultThread.isAlive()){
|
||||
exportResultThread = new Thread(()->{
|
||||
EvalResultLatexExport exporter = new EvalResultLatexExport(model, file);
|
||||
exporter.writeFile();
|
||||
});
|
||||
exportResultThread.start();
|
||||
try {
|
||||
exportResultThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateDataset(){
|
||||
if (generatorThread == null || !generatorThread.isAlive()){
|
||||
generatorThread = new Thread(() -> {
|
||||
DatasetGenerator generator = new DatasetGenerator();
|
||||
generator.addObserver(this);
|
||||
getModel().setLines(generator.generateCircle(100));
|
||||
calculateIntersections();
|
||||
getView().enableFunctionality();
|
||||
});
|
||||
generatorThread.start();
|
||||
try {
|
||||
generatorThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startEvaluation(int typ, int n, int alg, String datasettyp){
|
||||
|
||||
if (evalThread == null || !evalThread.isAlive()){
|
||||
evalThread = new Thread(() ->{
|
||||
try {
|
||||
eval = new EvaluateAlgorithms(typ,n,alg,datasettyp);
|
||||
eval.addObserver(this);
|
||||
eval.run();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
evalThread.start();
|
||||
}
|
||||
}
|
||||
/***************************************************************************************************************************
|
||||
* Getter und Setter Methoden
|
||||
***************************************************************************************************************************/
|
||||
|
||||
|
||||
public LineModel getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(LineModel 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,232 +0,0 @@
|
|||
package View;
|
||||
|
||||
import Model.Line;
|
||||
import Model.Point;
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.axis.ValueAxis;
|
||||
import org.jfree.chart.plot.PlotOrientation;
|
||||
import org.jfree.chart.plot.XYPlot;
|
||||
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
|
||||
import org.jfree.data.time.DateRange;
|
||||
import org.jfree.data.xy.XYSeries;
|
||||
import org.jfree.data.xy.XYSeriesCollection;
|
||||
import org.jfree.util.ShapeUtilities;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class DualityDialog extends JPanel {
|
||||
|
||||
private LinkedList<Line> lines;
|
||||
private LinkedList<Point> points;
|
||||
private JFreeChart chart;
|
||||
private ChartPanel panel;
|
||||
private XYSeriesCollection dataset;
|
||||
private JScrollPane scrollPane;
|
||||
private double domainMin, domainMax;
|
||||
private double rangeMin, rangeMax;
|
||||
private ValueAxis domain;
|
||||
private ValueAxis range;
|
||||
private Double delta = 1d;
|
||||
|
||||
|
||||
private Boolean ctrlPressed = false;
|
||||
private Boolean shiftPressed = false;
|
||||
|
||||
public DualityDialog() {
|
||||
super();
|
||||
this.setPreferredSize(new Dimension(800, 800));
|
||||
this.setMinimumSize(new Dimension(800, 800));
|
||||
this.setLayout(new BorderLayout());
|
||||
}
|
||||
|
||||
public void setPrameters(LinkedList<Line> lines, LinkedList<Point> points, Double xmin, Double xmax, Double ymin, Double ymax) {
|
||||
this.lines = new LinkedList<>(lines);
|
||||
this.points = new LinkedList<>(points);
|
||||
this.domainMin = xmin;
|
||||
this.domainMax = xmax;
|
||||
this.rangeMin = ymin;
|
||||
this.rangeMax = ymax;
|
||||
}
|
||||
|
||||
public void createArrangement() {
|
||||
dataset = new XYSeriesCollection();
|
||||
|
||||
for (Line p : lines) {
|
||||
XYSeries series = new XYSeries(p.getId()+"#"+p.getX1()+"---"+p.getY1());
|
||||
series.add(p.getX1(), p.getY1());
|
||||
series.add(p.getX2(), p.getY2());
|
||||
dataset.addSeries(series);
|
||||
}
|
||||
|
||||
XYSeries intersections = new XYSeries("intersections");
|
||||
for (Point p : points) {
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
addKeyListener(this);
|
||||
addZooming(panel);
|
||||
this.setFocusable(true);
|
||||
|
||||
JTextArea info = new JTextArea();
|
||||
info.setText("Um in dem Plot hineinzuzoomen kann das Mausrad verwendett werden. \nUm sich anschließen vertikal bzw. horizontal zu bewegen kann die Kombination (Umschalt/Steuerung)\nund Mausrad verwendett werden.");
|
||||
Font font = new Font("Serif", Font.ITALIC, 12);
|
||||
info.setFont(font);
|
||||
info.setForeground(Color.DARK_GRAY);
|
||||
info.setEditable(false);
|
||||
info.setWrapStyleWord(true);
|
||||
|
||||
this.add(info, BorderLayout.SOUTH);
|
||||
this.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void addKeyListener(JComponent component){
|
||||
component.addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
ctrlPressed = false;
|
||||
shiftPressed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.isControlDown()){
|
||||
ctrlPressed = true;
|
||||
}
|
||||
|
||||
if (e.isShiftDown()){
|
||||
shiftPressed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void addZooming(ChartPanel chartPanel) {
|
||||
|
||||
chartPanel.addMouseWheelListener(new MouseWheelListener() {
|
||||
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
|
||||
Double min;
|
||||
Double max;
|
||||
Double val = e.getPreciseWheelRotation() * -1;
|
||||
|
||||
if(ctrlPressed == true){
|
||||
//System.out.println("CTRL + ZOOM");
|
||||
min = range.getLowerBound();
|
||||
max = range.getUpperBound();
|
||||
DateRange dateRangeX = move(val, min, max);
|
||||
range.setRange(dateRangeX);
|
||||
} else if (shiftPressed == true){
|
||||
//System.out.println("SHIFT + ZOOM");
|
||||
min = domain.getLowerBound();
|
||||
max = domain.getUpperBound();
|
||||
DateRange dateRangeY = move(val, min, max);
|
||||
domain.setRange(dateRangeY);
|
||||
} else {
|
||||
Double x = Double.valueOf(e.getY());
|
||||
Double y = Double.valueOf(e.getY());
|
||||
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL)
|
||||
return;
|
||||
if (e.getWheelRotation() < 0)
|
||||
increaseZoom((ChartPanel) e.getComponent(), true, x, y);
|
||||
else
|
||||
decreaseZoom((ChartPanel) e.getComponent(), true, x, y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private DateRange move(Double val, Double min, Double max){
|
||||
Double minimum = min;
|
||||
Double maximum = max;
|
||||
delta = Math.abs(maximum - minimum) * 0.01 * val;
|
||||
|
||||
minimum = minimum + delta;
|
||||
maximum = maximum + delta;
|
||||
|
||||
return new DateRange(minimum,maximum);
|
||||
}
|
||||
|
||||
public synchronized void increaseZoom(JComponent chart, boolean saveAction, Double x, Double y) {
|
||||
ChartPanel ch = (ChartPanel) chart;
|
||||
zoomChartAxis(ch, true, x, y);
|
||||
}
|
||||
|
||||
public synchronized void decreaseZoom(JComponent chart, boolean saveAction, Double x, Double y) {
|
||||
ChartPanel ch = (ChartPanel) chart;
|
||||
zoomChartAxis(ch, false, x, y);
|
||||
}
|
||||
|
||||
private void zoomChartAxis(ChartPanel chartP, boolean increase, Double x, Double y) {
|
||||
int width = chartP.getMaximumDrawWidth() - chartP.getMinimumDrawWidth();
|
||||
int height = chartP.getMaximumDrawHeight() - chartP.getMinimumDrawWidth();
|
||||
if (increase) {
|
||||
chartP.zoomInBoth(width / 2, height / 2);
|
||||
} else {
|
||||
chartP.zoomOutBoth(width / 2, height / 2);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
if (dataset != null)
|
||||
dataset.removeAllSeries();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,604 +0,0 @@
|
|||
package View;
|
||||
|
||||
|
||||
import Model.Line;
|
||||
import Presenter.Presenter;
|
||||
import View.Panels.*;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class MainFrame extends JFrame {
|
||||
|
||||
private Presenter presenter;
|
||||
private Boolean lmsIsComplete = false;
|
||||
private Boolean rmIsComplete = false;
|
||||
private Boolean tsIsComplete = false;
|
||||
|
||||
private JButton arrangementButton;
|
||||
private JButton importButton;
|
||||
private JButton generateButton;
|
||||
private JButton exportButton;
|
||||
|
||||
private OutputPanel output;
|
||||
private MenuPanel menupanel;
|
||||
private LMSPanel lmsPanel;
|
||||
private RMPanel rmPanel;
|
||||
private TSPanel tsPanel;
|
||||
private JPanel pane;
|
||||
private JPanel northPanel;
|
||||
|
||||
private DualityDialog arrangement;
|
||||
private JDialog arrangementDialog;
|
||||
private PlotDialog plotLMS;
|
||||
private PlotDialog plotRM;
|
||||
private PlotDialog plotTS;
|
||||
private JDialog progressDialog;
|
||||
private JDialog evaluationDialog;
|
||||
|
||||
private Container progressContent;
|
||||
private JProgressBar progressBar;
|
||||
|
||||
|
||||
|
||||
private JSplitPane splitpane;
|
||||
private JScrollPane scrollPane;
|
||||
private JTabbedPane tabbedPane;
|
||||
private EvaluationPanel evaluationPanel;
|
||||
|
||||
public MainFrame() {
|
||||
initializeComponents();
|
||||
setDimensions();
|
||||
setLayouts();
|
||||
setTitles();
|
||||
|
||||
addComponents();
|
||||
|
||||
setCloseOperations();
|
||||
setActionListeners();
|
||||
setIcons();
|
||||
disableFunctionality();
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* visualisierungs methoden
|
||||
******************************************************************************************************************/
|
||||
|
||||
public void createDualityDialog() {
|
||||
arrangement = new DualityDialog();
|
||||
arrangementDialog = new JDialog();
|
||||
arrangementDialog.setTitle("Dual Representation - Dialog");
|
||||
arrangementDialog.setSize(new Dimension(800, 800));
|
||||
arrangementDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
arrangement.clear();
|
||||
arrangement.setPrameters(getPresenter().getLines(),
|
||||
getPresenter().getModel().getNodes(),
|
||||
getPresenter().getModel().getxMinimum(),
|
||||
getPresenter().getModel().getxMaximum(),
|
||||
getPresenter().getModel().getyMinimum(),
|
||||
getPresenter().getModel().getyMaximum());
|
||||
arrangement.createArrangement();
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
arrangementDialog.add(arrangement);
|
||||
arrangementDialog.revalidate();
|
||||
arrangementDialog.repaint();
|
||||
arrangementDialog.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void visualizeLMS(double m, double b) {
|
||||
plotLMS = new PlotDialog();
|
||||
lmsPanel.setPlotDialog(plotLMS);
|
||||
createPlot(m,b,plotLMS,lmsPanel, "LMS");
|
||||
}
|
||||
|
||||
public void visualizeRM(double m, double b) {
|
||||
plotRM = new PlotDialog();
|
||||
rmPanel.setPlotDialog(plotRM);
|
||||
createPlot(m,b,plotRM,rmPanel, "RM");
|
||||
}
|
||||
|
||||
public void visualizeTS(double m, double b){
|
||||
plotTS = new PlotDialog();
|
||||
tsPanel.setPlotDialog(plotTS);
|
||||
createPlot(m,b,plotTS, tsPanel, "TS");
|
||||
}
|
||||
|
||||
public void createPlot(double m, double b, PlotDialog plot, JPanel panel, String name){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
plot.clear();
|
||||
plot.createPlot(getPresenter().getLines());
|
||||
plot.addLineToPlot(m, b, name);
|
||||
panel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void showImportProgress(Integer progress){
|
||||
progressBar.setValue(progress);
|
||||
progressBar.setStringPainted(true);
|
||||
progressDialog.setVisible(true);
|
||||
}
|
||||
|
||||
public void showEvauluationDialog(){
|
||||
if (evaluationDialog == null){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
evaluationDialog = new JDialog();
|
||||
evaluationDialog.setTitle("Evaluation");
|
||||
evaluationDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
evaluationDialog.setSize(1800,800);
|
||||
evaluationDialog.setLocationRelativeTo(null);
|
||||
|
||||
evaluationPanel = new EvaluationPanel(this);
|
||||
evaluationDialog.add(evaluationPanel);
|
||||
evaluationDialog.setVisible(true);
|
||||
});
|
||||
} else {
|
||||
SwingUtilities.invokeLater(()->{
|
||||
evaluationDialog.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void appendEvalResult(Object[] res,int col, boolean isApprCol){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] tmp = Arrays.asList(res).subList(2,res.length).toArray();
|
||||
if (isApprCol){
|
||||
evaluationPanel.setCurrentRow(tmp.length);
|
||||
evaluationPanel.addColumn(tmp, col,true);
|
||||
} else {
|
||||
evaluationPanel.addColumn(tmp, col+1, false);
|
||||
}
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
public void appendEvalResult(Object[] res){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] tmp = Arrays.asList(res).subList(1,res.length).toArray();
|
||||
evaluationPanel.addRow(tmp);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void drawLineResult(Object[] res, int alg){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] result = Arrays.asList(res).subList(2,res.length).toArray();
|
||||
evaluationPanel.drawLines(result, alg);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void drawLineResults(Object[] res){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] result = Arrays.asList(res).subList(1,res.length).toArray();
|
||||
ArrayList<Double[]> algs = new ArrayList<>();
|
||||
|
||||
for (int i=0;i< (result.length+1) / 3;i++){
|
||||
String name = (String) result[(3*i)];
|
||||
String m = (String) result[(3*i)+1];
|
||||
String b = (String) result[(3*i)+2];
|
||||
Double[] tmp = {Double.parseDouble(name), Double.parseDouble(m), Double.parseDouble(b)};
|
||||
algs.add(tmp);
|
||||
}
|
||||
|
||||
evaluationPanel.drawLines(algs);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void addEvalDataset(LinkedList<Line> lines){
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
evaluationPanel.setDualPoints(lines);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* init GUI
|
||||
******************************************************************************************************************/
|
||||
private void setTitles() {
|
||||
this.setTitle("Algorithmen zur Berechnung von Ausgleichgeraden");
|
||||
importButton.setText("Import");
|
||||
exportButton.setText("Export");
|
||||
generateButton.setText("Generiere");
|
||||
arrangementButton.setText("Dualraum");
|
||||
}
|
||||
|
||||
private void setupTabbedPane() {
|
||||
tabbedPane.add("Least Median of Squares", lmsPanel);
|
||||
tabbedPane.add("Repeated Median", rmPanel);
|
||||
tabbedPane.add("Theil-Sen", tsPanel);
|
||||
}
|
||||
|
||||
private void addComponents() {
|
||||
pane.add(arrangementButton);
|
||||
pane.add(importButton);
|
||||
pane.add(exportButton);
|
||||
pane.add(generateButton);
|
||||
|
||||
northPanel.add(menupanel);
|
||||
northPanel.add(pane);
|
||||
|
||||
setupSplitPane();
|
||||
setupTabbedPane();
|
||||
|
||||
progressContent.add(progressBar, BorderLayout.NORTH);
|
||||
progressBar.setBorder(BorderFactory.createTitledBorder("Import..."));
|
||||
|
||||
this.add(northPanel, BorderLayout.NORTH);
|
||||
this.add(splitpane, BorderLayout.CENTER);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
progressDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
}
|
||||
|
||||
private void setDimensions() {
|
||||
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
|
||||
this.setResizable(false);
|
||||
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
this.setMaximizedBounds(env.getMaximumWindowBounds());
|
||||
lmsPanel.setMinimumSize(new Dimension(400, 500));
|
||||
rmPanel.setMinimumSize(new Dimension(400, 500));
|
||||
tsPanel.setMinimumSize(new Dimension(400, 500));
|
||||
output.setMinimumSize(new Dimension(400, 500));
|
||||
progressDialog.setSize(300, 80);
|
||||
progressDialog.setResizable(false);
|
||||
}
|
||||
|
||||
private void setLayouts() {
|
||||
this.setLayout(new BorderLayout());
|
||||
pane.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS));
|
||||
}
|
||||
|
||||
private void initializeComponents() {
|
||||
//Panels
|
||||
pane = new JPanel();
|
||||
lmsPanel = new LMSPanel();
|
||||
rmPanel = new RMPanel();
|
||||
tsPanel = new TSPanel();
|
||||
menupanel = new MenuPanel(this);
|
||||
northPanel = new JPanel();
|
||||
|
||||
//Dialogs
|
||||
progressDialog = new JDialog();
|
||||
progressDialog.setLocationRelativeTo(null);
|
||||
progressContent = progressDialog.getContentPane();
|
||||
progressBar = new JProgressBar();
|
||||
|
||||
//Panes
|
||||
tabbedPane = new JTabbedPane();
|
||||
output = new OutputPanel();
|
||||
splitpane = new JSplitPane();
|
||||
|
||||
//Buttons
|
||||
arrangementButton = new JButton();
|
||||
importButton = new JButton();
|
||||
generateButton = new JButton();
|
||||
exportButton = new JButton();
|
||||
}
|
||||
|
||||
private void setIcons(){
|
||||
try {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
Image imgImport = ImageIO.read(classLoader.getResource("import.png")).getScaledInstance(16,16,Image.SCALE_SMOOTH);
|
||||
Image imgPlot = ImageIO.read(classLoader.getResource("plot.png")).getScaledInstance(16,16,Image.SCALE_SMOOTH);
|
||||
Image imgStart = ImageIO.read(classLoader.getResource("start.png")).getScaledInstance(32,32,Image.SCALE_SMOOTH);
|
||||
Image imgGenerate = ImageIO.read(classLoader.getResource("generate.png")).getScaledInstance(16,16,Image.SCALE_SMOOTH);
|
||||
Image imgExport = ImageIO.read(classLoader.getResource("export.png")).getScaledInstance(16,16,Image.SCALE_SMOOTH);
|
||||
Image imgFrame = ImageIO.read(classLoader.getResource("frame.png")).getScaledInstance(32,23,Image.SCALE_SMOOTH);
|
||||
|
||||
|
||||
importButton.setIcon(new ImageIcon(imgImport));
|
||||
exportButton.setIcon(new ImageIcon(imgExport));
|
||||
generateButton.setIcon(new ImageIcon(imgGenerate));
|
||||
arrangementButton.setIcon(new ImageIcon(imgPlot));
|
||||
lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
|
||||
rmPanel.getStartButton().setIcon(new ImageIcon(imgStart));
|
||||
tsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
|
||||
this.setIconImage(imgFrame);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void setActionListeners() {
|
||||
arrangementButton.addActionListener((ActionEvent e) -> {
|
||||
Thread t = new Thread(() -> getPresenter().visualizeDualLines());
|
||||
t.start();
|
||||
});
|
||||
|
||||
lmsPanel.getStartButton().addActionListener((ActionEvent e) -> {
|
||||
if (lmsPanel.getInput() != null){
|
||||
Thread t = new Thread(
|
||||
() -> this.getPresenter().calculateLMS(lmsPanel.getInput()));
|
||||
t.start();
|
||||
}
|
||||
});
|
||||
|
||||
rmPanel.getStartButton().addActionListener((ActionEvent e) -> {
|
||||
if (rmPanel.getInput() != null){
|
||||
Thread t = new Thread(
|
||||
() -> this.getPresenter().calculateRM(rmPanel.getInput()));
|
||||
t.start();
|
||||
}
|
||||
});
|
||||
|
||||
tsPanel.getStartButton().addActionListener((ActionEvent e) -> {
|
||||
Thread t = new Thread(
|
||||
() -> this.getPresenter().calculateTS(""));
|
||||
t.start();
|
||||
});
|
||||
|
||||
importButton.addActionListener((ActionEvent e) -> {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
File file = null;
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setPreferredSize(new Dimension(800,700));
|
||||
File workingDirectory = new File(System.getProperty("user.dir"));
|
||||
chooser.setCurrentDirectory(workingDirectory);
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Value", "csv", "text"));
|
||||
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
|
||||
|
||||
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
|
||||
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
|
||||
file = chooser.getSelectedFile();
|
||||
final File input = file;
|
||||
Thread t = new Thread(() -> this.getPresenter().startImport(input));
|
||||
t.start();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
exportButton.addActionListener((ActionEvent e) -> {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
File file = null;
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setPreferredSize(new Dimension(800,700));
|
||||
File workingDirectory = new File(System.getProperty("user.dir"));
|
||||
chooser.setCurrentDirectory(workingDirectory);
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Value", "csv", "text"));
|
||||
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
|
||||
|
||||
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){
|
||||
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
|
||||
file = chooser.getSelectedFile();
|
||||
String filename = file.getAbsolutePath().contains(".csv") ? file.getAbsolutePath() : file.getAbsolutePath().concat(".csv");
|
||||
File withExtension = new File(filename);
|
||||
final File input = withExtension;
|
||||
Thread t = new Thread(() -> this.getPresenter().startExport(input));
|
||||
t.start();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
generateButton.addActionListener((ActionEvent e) -> {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getPresenter().generateDataset();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void enableFunctionality(){
|
||||
this.getLmsPanel().getStartButton().setEnabled(true);
|
||||
this.getRmPanel().getStartButton().setEnabled(true);
|
||||
this.getTsPanel().getStartButton().setEnabled(true);
|
||||
this.getArrangementButton().setEnabled(true);
|
||||
this.getExportButton().setEnabled(true);
|
||||
}
|
||||
|
||||
public void disableFunctionality(){
|
||||
this.getLmsPanel().getStartButton().setEnabled(false);
|
||||
this.getRmPanel().getStartButton().setEnabled(false);
|
||||
this.getTsPanel().getStartButton().setEnabled(false);
|
||||
this.getArrangementButton().setEnabled(false);
|
||||
this.getExportButton().setEnabled(false);
|
||||
}
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* log Methode
|
||||
******************************************************************************************************************/
|
||||
public void log(String s) {
|
||||
SwingUtilities.invokeLater(() -> output.appendParagraph(s));
|
||||
}
|
||||
|
||||
public void logError(String s) {
|
||||
SwingUtilities.invokeLater(() -> output.appendParagraphRed(s));
|
||||
}
|
||||
|
||||
public void logSuccess(String s) {
|
||||
SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s));
|
||||
}
|
||||
|
||||
public void logHeading(String s) {
|
||||
SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s));
|
||||
}
|
||||
|
||||
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 getImportButton() {
|
||||
return importButton;
|
||||
}
|
||||
|
||||
public void setImportButton(JButton importButton) {
|
||||
this.importButton = importButton;
|
||||
}
|
||||
|
||||
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 MenuPanel getMenupanel() {
|
||||
return menupanel;
|
||||
}
|
||||
|
||||
public LMSPanel getLmsPanel() {
|
||||
return lmsPanel;
|
||||
}
|
||||
|
||||
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 RMPanel getRmPanel() {
|
||||
return rmPanel;
|
||||
}
|
||||
|
||||
public void setRmPanel(RMPanel rmPanel) {
|
||||
this.rmPanel = rmPanel;
|
||||
}
|
||||
|
||||
public PlotDialog getPlotLMS() {
|
||||
return plotLMS;
|
||||
}
|
||||
|
||||
public void setPlotLMS(PlotDialog plotLMS) {
|
||||
this.plotLMS = plotLMS;
|
||||
}
|
||||
|
||||
public Presenter getPresenter() {
|
||||
return presenter;
|
||||
}
|
||||
|
||||
public void setPresenter(Presenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public JDialog getProgressDialog() {
|
||||
return progressDialog;
|
||||
}
|
||||
|
||||
public void setProgressDialog(JDialog progressDialog) {
|
||||
this.progressDialog = progressDialog;
|
||||
}
|
||||
|
||||
public TSPanel getTsPanel() {
|
||||
return tsPanel;
|
||||
}
|
||||
|
||||
public void setTsPanel(TSPanel tsPanel) {
|
||||
this.tsPanel = tsPanel;
|
||||
}
|
||||
|
||||
public JButton getExportButton() {
|
||||
return exportButton;
|
||||
}
|
||||
|
||||
public void setExportButton(JButton exportButton) {
|
||||
this.exportButton = exportButton;
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
package View.Panels;
|
||||
|
||||
import View.PlotDialog;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 02.06.2017.
|
||||
*/
|
||||
public class LMSPanel extends JPanel {
|
||||
|
||||
|
||||
private JLabel[] labels;
|
||||
private JTextField[] input;
|
||||
private JButton startButton;
|
||||
private JPanel continer;
|
||||
private JPanel northPanel;
|
||||
private JPanel centerPanel;
|
||||
private PlotDialog plotDialog;
|
||||
private GridBagConstraints gbc;
|
||||
|
||||
public LMSPanel() {
|
||||
this.labels = new JLabel[2];
|
||||
this.input = new JTextField[2];
|
||||
this.setLayout(new BorderLayout());
|
||||
this.northPanel = new JPanel(new BorderLayout());
|
||||
this.centerPanel = new JPanel(new BorderLayout());
|
||||
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
|
||||
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");
|
||||
this.startButton.setFont(new Font("Verdana",Font.PLAIN, 16));
|
||||
addButton(2, startButton);
|
||||
|
||||
this.northPanel.add(continer, BorderLayout.CENTER);
|
||||
this.add(northPanel, BorderLayout.NORTH);
|
||||
this.add(centerPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
|
||||
private void addTextfieldAndInput(int row, String name, Double value) {
|
||||
this.labels[row] = new JLabel(name);
|
||||
this.labels[row].setFont(new Font("SansSerif", Font.PLAIN, 12));
|
||||
this.input[row] = new JTextField();
|
||||
this.input[row].setText("" + value);
|
||||
|
||||
gbc.insets = new Insets(0, 5, 0, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
continer.add(this.labels[row], gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
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);
|
||||
}
|
||||
|
||||
private void addButton(int row, JButton button) {
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
|
||||
gbc.insets = new Insets(30, 0, 5, 0);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
gbc.gridwidth = 1;
|
||||
buttonPanel.add(button);
|
||||
continer.add(buttonPanel, gbc);
|
||||
}
|
||||
|
||||
public JButton getStartButton() {
|
||||
return startButton;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String[] getInput() {
|
||||
String[] input = new String[3];
|
||||
input[0] = this.input[0].getText();
|
||||
input[1] = this.input[1].getText();
|
||||
|
||||
if (isNumeric(input[0]) && isNumeric(input[1])){
|
||||
return input;
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(null, "Bitte geben Sie numerische Werte als Parameter an.","Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setInput(JTextField[] input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public PlotDialog getPlotDialog() {
|
||||
return plotDialog;
|
||||
}
|
||||
|
||||
public void setPlotDialog(PlotDialog plotDialog) {
|
||||
this.plotDialog = plotDialog;
|
||||
if (this.centerPanel.getComponents().length > 0)
|
||||
this.centerPanel.remove(0);
|
||||
|
||||
this.centerPanel.add(plotDialog, BorderLayout.CENTER);
|
||||
this.plotDialog.setVisible(true);
|
||||
this.repaint();
|
||||
this.revalidate();
|
||||
}
|
||||
|
||||
public boolean isNumeric(String str) {
|
||||
try{
|
||||
double d = Double.parseDouble(str);
|
||||
}
|
||||
catch(NumberFormatException nfe){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package View.Panels;
|
||||
|
||||
import View.MainFrame;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 29.05.2017.
|
||||
*/
|
||||
public class MenuPanel extends JPanel {
|
||||
|
||||
private MainFrame view;
|
||||
private JMenuBar menuBar;
|
||||
|
||||
private JMenu fileMenu;
|
||||
private JMenu toolsMenu;
|
||||
|
||||
private JMenuItem item;
|
||||
private JMenuItem evaluate;
|
||||
|
||||
public MenuPanel(MainFrame view) {
|
||||
this.view = view;
|
||||
this.setLayout(new BorderLayout());
|
||||
this.menuBar = new JMenuBar();
|
||||
this.fileMenu = new JMenu("Datei");
|
||||
this.toolsMenu = new JMenu("Extras");
|
||||
|
||||
|
||||
this.item = new JMenuItem("Exit");
|
||||
this.item.addActionListener(e -> {
|
||||
System.exit(0);
|
||||
});
|
||||
|
||||
this.evaluate = new JMenuItem("Evaluation");
|
||||
this.evaluate.addActionListener(e -> {
|
||||
view.showEvauluationDialog();
|
||||
});
|
||||
|
||||
fileMenu.add(item);
|
||||
toolsMenu.add(evaluate);
|
||||
|
||||
menuBar.add(fileMenu);
|
||||
menuBar.add(toolsMenu);
|
||||
this.add(menuBar, BorderLayout.WEST);
|
||||
this.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.SOUTH);
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
package View.Panels;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
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.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 02.06.2017.
|
||||
*/
|
||||
public class OutputPanel extends JPanel {
|
||||
|
||||
private JTextPane output;
|
||||
private JScrollPane scrollPane;
|
||||
private StringBuilder content;
|
||||
|
||||
public OutputPanel() {
|
||||
this.setBorder(new TitledBorder("Ausgabekanal"));
|
||||
this.setLayout(new BorderLayout());
|
||||
output = new JTextPane();
|
||||
output.setEditable(false);
|
||||
output.setContentType("text/html");
|
||||
|
||||
content = new StringBuilder();
|
||||
|
||||
scrollPane = new JScrollPane(output);
|
||||
scrollPane.setWheelScrollingEnabled(true);
|
||||
this.add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void appendParagraph(String p) {
|
||||
|
||||
content.append("<p>" + p + "</p>");
|
||||
|
||||
output.setText(content.toString());
|
||||
}
|
||||
|
||||
public void appendParagraphWithHeading(String h1) {
|
||||
|
||||
content.append("<h1>" + h1 + "</h1>");
|
||||
|
||||
output.setText(content.toString());
|
||||
}
|
||||
|
||||
public void appendParagraphRed(String p) {
|
||||
|
||||
content.append("<p style=\" color:red \"><em><strong>" + p + "</strong></em></p>");
|
||||
|
||||
output.setText(content.toString());
|
||||
}
|
||||
|
||||
public void appendParagraphGreen(String p) {
|
||||
|
||||
content.append("<p style=\" color:green \"><em><strong>" + p + "</strong></em></p>");
|
||||
|
||||
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>");
|
||||
if (heading.size()>1){
|
||||
for (String str : heading) {
|
||||
content.append("<th style=\" border: 1px solid black; \">" + str + "</th>");
|
||||
}
|
||||
} else {
|
||||
content.append("<th style=\" border: 1px solid black;\" colspan=\""+ rows.get(0).size() +"\"; >" + heading.get(0) + "</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());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
package View.Panels;
|
||||
|
||||
import View.PlotDialog;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.LineBorder;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 21.06.2017.
|
||||
*/
|
||||
public class RMPanel extends JPanel {
|
||||
|
||||
private JLabel labels;
|
||||
private JTextField input;
|
||||
private JButton startButton;
|
||||
private JPanel continer;
|
||||
private JPanel northPanel;
|
||||
private JPanel centerPanel;
|
||||
private PlotDialog plotDialog;
|
||||
private GridBagConstraints gbc;
|
||||
|
||||
public RMPanel() {
|
||||
this.labels = new JLabel();
|
||||
|
||||
this.input = new JTextField();
|
||||
this.setLayout(new BorderLayout());
|
||||
this.northPanel = new JPanel(new BorderLayout());
|
||||
this.centerPanel = new JPanel(new BorderLayout());
|
||||
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
|
||||
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, "\u00df (0 < \u00df < 1)", 0.5);
|
||||
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
this.startButton = new JButton("Start");
|
||||
this.startButton.setFont(new Font("Verdana",Font.PLAIN, 16));
|
||||
gbc.insets = new Insets(30, 0, 10, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 2;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
buttonPanel.add(startButton);
|
||||
continer.add(buttonPanel, gbc);
|
||||
|
||||
this.northPanel.add(continer, BorderLayout.CENTER);
|
||||
this.add(northPanel, BorderLayout.NORTH);
|
||||
this.add(centerPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
|
||||
private void addTextfieldAndInput(int row, String name, Double value) {
|
||||
this.labels = new JLabel(name);
|
||||
this.labels.setFont(new Font("SansSerif", Font.PLAIN, 13));
|
||||
this.input = new JTextField();
|
||||
this.input.setText("" + value);
|
||||
|
||||
gbc.insets = new Insets(0, 5, 0, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
continer.add(this.labels, gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.9;
|
||||
gbc.weighty = 0.05;
|
||||
gbc.insets = new Insets(0, 0, 0, 5);
|
||||
continer.add(this.input, gbc);
|
||||
}
|
||||
|
||||
|
||||
public JButton getStartButton() {
|
||||
return startButton;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getInput() {
|
||||
String input = "";
|
||||
input = this.input.getText();
|
||||
if (isNumeric(input))
|
||||
return input;
|
||||
else
|
||||
JOptionPane.showMessageDialog(null, "Bitte geben Sie numerische Werte als Parameter an.","Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setInput(JTextField input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public PlotDialog getPlotDialog() {
|
||||
return plotDialog;
|
||||
}
|
||||
|
||||
public void setPlotDialog(PlotDialog plotDialog) {
|
||||
this.plotDialog = plotDialog;
|
||||
if (this.centerPanel.getComponents().length > 0)
|
||||
this.centerPanel.remove(0);
|
||||
|
||||
this.centerPanel.add(plotDialog, BorderLayout.CENTER);
|
||||
this.plotDialog.setVisible(true);
|
||||
this.repaint();
|
||||
this.revalidate();
|
||||
}
|
||||
|
||||
public boolean isNumeric(String str) {
|
||||
try{
|
||||
double d = Double.parseDouble(str);
|
||||
}
|
||||
catch(NumberFormatException nfe){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
package View.Panels;
|
||||
|
||||
import View.PlotDialog;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 26.06.2017.
|
||||
*/
|
||||
public class TSPanel extends JPanel{
|
||||
|
||||
private JLabel labels;
|
||||
private JTextField input;
|
||||
private JButton startButton;
|
||||
private JPanel continer;
|
||||
private JPanel northPanel;
|
||||
private JPanel centerPanel;
|
||||
private PlotDialog plotDialog;
|
||||
private GridBagConstraints gbc;
|
||||
|
||||
public TSPanel() {
|
||||
this.labels = new JLabel();
|
||||
|
||||
this.input = new JTextField();
|
||||
this.setLayout(new BorderLayout());
|
||||
this.northPanel = new JPanel(new BorderLayout());
|
||||
this.centerPanel = new JPanel(new BorderLayout());
|
||||
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
|
||||
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, "\u00df (0 < \u00df < 1)", 0.5);
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
this.startButton = new JButton("Start");
|
||||
this.startButton.setFont(new Font("Verdana",Font.PLAIN, 16));
|
||||
gbc.insets = new Insets(10, 0, 10, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
buttonPanel.add(startButton);
|
||||
continer.add(buttonPanel, gbc);
|
||||
|
||||
this.northPanel.add(continer, BorderLayout.CENTER);
|
||||
this.add(northPanel, BorderLayout.NORTH);
|
||||
this.add(centerPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
|
||||
private void addTextfieldAndInput(int row, String name, Double value) {
|
||||
this.labels = new JLabel(name);
|
||||
this.labels.setFont(new Font("SansSerif", Font.PLAIN, 13));
|
||||
this.input = new JTextField();
|
||||
this.input.setText("" + value);
|
||||
|
||||
gbc.insets = new Insets(0, 5, 0, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
continer.add(this.labels, gbc);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.9;
|
||||
gbc.weighty = 0.05;
|
||||
gbc.insets = new Insets(0, 0, 0, 5);
|
||||
continer.add(this.input, gbc);
|
||||
}
|
||||
|
||||
|
||||
public JButton getStartButton() {
|
||||
return startButton;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getInput() {
|
||||
String input = "";
|
||||
input = this.input.getText();
|
||||
if (isNumeric(input))
|
||||
return input;
|
||||
else
|
||||
JOptionPane.showMessageDialog(null, "Bitte geben Sie numerische Werte als Parameter an.","Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setInput(JTextField input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public PlotDialog getPlotDialog() {
|
||||
return plotDialog;
|
||||
}
|
||||
|
||||
public void setPlotDialog(PlotDialog plotDialog) {
|
||||
this.plotDialog = plotDialog;
|
||||
if (this.centerPanel.getComponents().length > 0)
|
||||
this.centerPanel.remove(0);
|
||||
|
||||
this.centerPanel.add(plotDialog, BorderLayout.CENTER);
|
||||
this.plotDialog.setVisible(true);
|
||||
this.repaint();
|
||||
this.revalidate();
|
||||
}
|
||||
|
||||
public boolean isNumeric(String str) {
|
||||
try{
|
||||
double d = Double.parseDouble(str);
|
||||
}
|
||||
catch(NumberFormatException nfe){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
package View;
|
||||
|
||||
import Model.Line;
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.plot.PlotOrientation;
|
||||
import org.jfree.chart.plot.XYPlot;
|
||||
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
|
||||
import org.jfree.data.xy.XYSeries;
|
||||
import org.jfree.data.xy.XYSeriesCollection;
|
||||
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.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 29.05.2017.
|
||||
*/
|
||||
public class PlotDialog extends JPanel {
|
||||
|
||||
private JFreeChart chart;
|
||||
private ChartPanel panel;
|
||||
private XYSeriesCollection datapoints;
|
||||
private XYSeries series;
|
||||
private Double min;
|
||||
private Double max;
|
||||
private XYPlot xyPlot;
|
||||
private int seriesCount;
|
||||
|
||||
private XYLineAndShapeRenderer renderer;
|
||||
private Shape diamond;
|
||||
|
||||
public PlotDialog() {
|
||||
super();
|
||||
// this.setPreferredSize(new Dimension(1000, 1000));
|
||||
// this.setMinimumSize(new Dimension(1000, 800));
|
||||
this.setLayout(new BorderLayout());
|
||||
seriesCount = 1;
|
||||
}
|
||||
|
||||
public void createPlot(LinkedList<Line> points) {
|
||||
if (!points.isEmpty()) {
|
||||
try {
|
||||
Thread thread = new Thread(() -> convertData(points));
|
||||
thread.start();
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//createScatterPlot
|
||||
chart = ChartFactory.createXYLineChart("",
|
||||
"X", "Y", datapoints, PlotOrientation.VERTICAL, true, true, false);
|
||||
diamond = ShapeUtilities.createDiamond(2f);
|
||||
chart.setBorderVisible(false);
|
||||
chart.setAntiAlias(true);
|
||||
chart.getPlot().setBackgroundPaint(Color.WHITE);
|
||||
chart.setBorderVisible(false);
|
||||
|
||||
|
||||
xyPlot = (XYPlot) chart.getPlot();
|
||||
xyPlot.setDomainCrosshairVisible(true);
|
||||
xyPlot.setRangeCrosshairVisible(true);
|
||||
|
||||
|
||||
renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
|
||||
renderer.setSeriesLinesVisible(0, false);
|
||||
renderer.setSeriesShapesVisible(0, true);
|
||||
renderer.setSeriesLinesVisible(1, true);
|
||||
renderer.setSeriesLinesVisible(1, true);
|
||||
renderer.setSeriesPaint(0, Color.blue);
|
||||
renderer.setSeriesShape(0, diamond);
|
||||
renderer.setBaseSeriesVisible(true);
|
||||
|
||||
|
||||
xyPlot.setDomainCrosshairVisible(true);
|
||||
xyPlot.setRangeCrosshairVisible(true);
|
||||
|
||||
panel = new ChartPanel(chart);
|
||||
panel.setMouseZoomable(false);
|
||||
this.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
if (datapoints != null)
|
||||
datapoints.removeAllSeries();
|
||||
}
|
||||
|
||||
public void addLineToPlot(double m, double b, Paint color, String name) {
|
||||
|
||||
XYSeries linesA = new XYSeries(name);
|
||||
linesA.add(min.doubleValue(), min * m + b);
|
||||
linesA.add(max.doubleValue(), max * m + b);
|
||||
|
||||
datapoints.addSeries(linesA);
|
||||
|
||||
renderer.setSeriesPaint(seriesCount, color);
|
||||
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
|
||||
renderer.setBaseSeriesVisible(true);
|
||||
renderer.setSeriesLinesVisible(seriesCount, true);
|
||||
seriesCount++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void addLineToPlot(double m, double b, String name) {
|
||||
|
||||
XYSeries linesA = new XYSeries(name);
|
||||
linesA.add(min.intValue(), min.intValue() * m + b);
|
||||
linesA.add(max.intValue(), max.intValue() * m + b);
|
||||
|
||||
datapoints.addSeries(linesA);
|
||||
seriesCount = xyPlot.getSeriesCount();
|
||||
renderer.setSeriesPaint(seriesCount, Color.red);
|
||||
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
|
||||
renderer.setBaseSeriesVisible(true);
|
||||
renderer.setSeriesLinesVisible(seriesCount, 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().doubleValue(), p.getB().doubleValue() * (-1));
|
||||
coordinates.add(p.getM());
|
||||
|
||||
}
|
||||
this.max = series.getMaxX();
|
||||
this.min = series.getMinX();
|
||||
datapoints.addSeries(series);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
package View.custom;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.ButtonModel;
|
||||
|
||||
/**
|
||||
* Source: <url>https://stackoverflow.com/questions/14892515/how-to-enforce-at-least-one-checkbox-in-a-group-is-selected</url>
|
||||
*
|
||||
* A ButtonGroup for check-boxes enforcing that at least two remains selected.
|
||||
*
|
||||
* When the group has exactly two buttons, deselecting the last selected one
|
||||
* automatically selects the other.
|
||||
*
|
||||
* When the group has more buttons, deselection of the last selected one is denied.
|
||||
*/
|
||||
public class ButtonGroupAtLeastOne extends ButtonGroup {
|
||||
|
||||
private final Set<ButtonModel> selected = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void setSelected(ButtonModel model, boolean b) {
|
||||
if (b && !this.selected.contains(model) ) {
|
||||
select(model, true);
|
||||
} else if (!b && this.selected.contains(model)) {
|
||||
if (this.buttons.size() == 3 && this.selected.size() == 2) {
|
||||
select(model, false);
|
||||
|
||||
AbstractButton otherOne = this.buttons.get(0).getModel() == model ?
|
||||
this.buttons.get(1) : this.buttons.get(0);
|
||||
|
||||
AbstractButton otherTwo = this.buttons.get(1).getModel() == model ?
|
||||
this.buttons.get(2) : this.buttons.get(1);
|
||||
|
||||
AbstractButton otherThree = this.buttons.get(2).getModel() == model ?
|
||||
this.buttons.get(1) : this.buttons.get(2);
|
||||
|
||||
|
||||
select(otherOne.getModel(), true);
|
||||
select(otherTwo.getModel(), true);
|
||||
select(otherThree.getModel(), true);
|
||||
} else if (this.selected.size() > 2) {
|
||||
this.selected.remove(model);
|
||||
model.setSelected(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void select(ButtonModel model, boolean b) {
|
||||
if (b) {
|
||||
this.selected.add(model);
|
||||
} else {
|
||||
this.selected.remove(model);
|
||||
}
|
||||
model.setSelected(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(ButtonModel m) {
|
||||
return this.selected.contains(m);
|
||||
}
|
||||
|
||||
public void addAll(AbstractButton... buttons) {
|
||||
for (AbstractButton button : buttons) {
|
||||
add(button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(AbstractButton button) {
|
||||
if (button.isSelected()) {
|
||||
this.selected.add(button.getModel());
|
||||
}
|
||||
super.add(button);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package View.custom;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
/**
|
||||
* Source: <url> http://esus.com/creating-a-jtable-with-a-different-background-color-per-column/ </url>
|
||||
*
|
||||
* Applied background and foreground color to single column of a JTable
|
||||
* in order to distinguish it apart from other columns.
|
||||
*/
|
||||
public class ColorColumnRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
Color bkgndColor, fgndColor;
|
||||
|
||||
public ColorColumnRenderer(Color bkgnd, Color foregnd) {
|
||||
super();
|
||||
bkgndColor = bkgnd;
|
||||
fgndColor = foregnd;
|
||||
}
|
||||
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
|
||||
boolean hasFocus, int row, int column) {
|
||||
Component cell = super.getTableCellRendererComponent
|
||||
(table, value, isSelected, hasFocus, row, column);
|
||||
|
||||
cell.setBackground(bkgndColor);
|
||||
cell.setForeground(fgndColor);
|
||||
cell.setFont(new Font("SansSerif", Font.BOLD, 12));
|
||||
this.setHorizontalAlignment(JLabel.CENTER);
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
package model.DCEL;
|
||||
|
||||
|
||||
import model.Point;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class DoublyConnectedEdgeList {
|
||||
|
||||
private LinkedList<Node> nodes;
|
||||
private LinkedList<Edge> edges;
|
||||
private LinkedList<Face> faces;
|
||||
|
||||
public DoublyConnectedEdgeList() {
|
||||
this.nodes = new LinkedList<>();
|
||||
this.edges = 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));
|
||||
}
|
||||
|
||||
if (innerComponent != null) {
|
||||
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) {
|
||||
Edge edge = node.getIncidentEdge();
|
||||
LinkedList list = new LinkedList();
|
||||
do {
|
||||
list.add(edge);
|
||||
edge = edge.getNext();
|
||||
} while (node != edge.getOrigin());
|
||||
return list;
|
||||
}
|
||||
|
||||
public LinkedList<Node> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public void setNodes(LinkedList<Node> nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
public LinkedList<Edge> getEdges() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
public void setEdges(LinkedList<Edge> edges) {
|
||||
this.edges = edges;
|
||||
}
|
||||
|
||||
public LinkedList<Face> getFaces() {
|
||||
return faces;
|
||||
}
|
||||
|
||||
public void setFaces(LinkedList<Face> faces) {
|
||||
this.faces = faces;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package model.DCEL;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class Edge {
|
||||
|
||||
private Node origin;
|
||||
private Edge twin;
|
||||
private Face incidentFace;
|
||||
private Edge next;
|
||||
private Edge prev;
|
||||
private String id;
|
||||
|
||||
public Edge() {
|
||||
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 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package model.DCEL;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class Face {
|
||||
|
||||
private LinkedList<Edge> innerComponents;
|
||||
private Edge outerComponent;
|
||||
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 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 String getID() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setID(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package model.DCEL;
|
||||
|
||||
import model.Point;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class Node {
|
||||
|
||||
private Point point;
|
||||
private Edge incidentEdge;
|
||||
private String id;
|
||||
|
||||
public Node() {
|
||||
new Node(null, null);
|
||||
}
|
||||
|
||||
public Node(Point point, Edge incidentEdge) {
|
||||
this.point = point;
|
||||
this.incidentEdge = incidentEdge;
|
||||
}
|
||||
|
||||
public Point getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
public void setPoint(Point point) {
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
public Edge getIncidentEdge() {
|
||||
return incidentEdge;
|
||||
}
|
||||
|
||||
public void setIncidentEdge(Edge incidentEdge) {
|
||||
this.incidentEdge = incidentEdge;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setID(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package model;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 16.06.2017.
|
||||
*/
|
||||
public class Interval {
|
||||
|
||||
private double upper;
|
||||
private double lower;
|
||||
private Boolean activity;
|
||||
|
||||
public Interval(double lower, double upper) {
|
||||
this.upper = upper;
|
||||
this.lower = lower;
|
||||
this.activity = true;
|
||||
}
|
||||
|
||||
public Boolean getActivity() {
|
||||
return activity;
|
||||
}
|
||||
|
||||
public void setActivity(Boolean isActive) {
|
||||
this.activity = isActive;
|
||||
}
|
||||
|
||||
public double getUpper() {
|
||||
return upper;
|
||||
}
|
||||
|
||||
public void setUpper(double upper) {
|
||||
this.upper = upper;
|
||||
}
|
||||
|
||||
public double getLower() {
|
||||
return lower;
|
||||
}
|
||||
|
||||
public void setLower(double lower) {
|
||||
this.lower = lower;
|
||||
}
|
||||
|
||||
public Double getDistance() {
|
||||
|
||||
return Math.abs(this.upper - this.lower);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package model;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 12.06.2017.
|
||||
*/
|
||||
public class Line {
|
||||
|
||||
private final Double MAX = 9999d;
|
||||
private final Double MIN = -9999d;
|
||||
|
||||
|
||||
private Double m;
|
||||
private Double b;
|
||||
|
||||
private Double x1;
|
||||
private Double x2;
|
||||
private Double y1;
|
||||
private Double y2;
|
||||
|
||||
private String id;
|
||||
|
||||
public Line(double m, double b, String id) {
|
||||
this.m = m;
|
||||
this.b = b;
|
||||
|
||||
this.x1 = MIN;
|
||||
this.y1 = (MIN * m) + b;
|
||||
this.x2 = MAX * 0.5;
|
||||
this.y2 = ((MAX * 0.5) * m) + b;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
public Line(double m, double b) {
|
||||
this.m = m;
|
||||
this.b = b;
|
||||
|
||||
this.x1 = MIN;
|
||||
this.y1 = (MIN * m) + b;
|
||||
this.x2 = MAX * 0.5;
|
||||
this.y2 = ((MAX * 0.5) * m) + b;
|
||||
}
|
||||
|
||||
public Line(double x1, double x2, double y1, double y2) {
|
||||
this.x1 = x1;
|
||||
this.x2 = x2;
|
||||
this.y1 = y1;
|
||||
this.y2 = y2;
|
||||
|
||||
this.m = (y2 - y1) / (x2 - x1);
|
||||
this.b = y2 - (x2 * m);
|
||||
|
||||
}
|
||||
|
||||
public Double getM() {
|
||||
return m;
|
||||
}
|
||||
|
||||
public void setM(double m) {
|
||||
this.m = m;
|
||||
}
|
||||
|
||||
public Double getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
public void setB(double b) {
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getX1() {
|
||||
return x1;
|
||||
}
|
||||
|
||||
public Double getX2() {
|
||||
return x2;
|
||||
}
|
||||
|
||||
public Double getY1() {
|
||||
return y1;
|
||||
}
|
||||
|
||||
public Double getY2() {
|
||||
return y2;
|
||||
}
|
||||
|
||||
public void setEndPoints(double x1, double y1, double x2, double y2) {
|
||||
this.x1 = x1;
|
||||
this.x2 = x2;
|
||||
this.y1 = y1;
|
||||
this.y2 = y2;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package model;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class LineModel {
|
||||
|
||||
private LinkedList<Point> nodes;
|
||||
private LinkedList<Line> lines;
|
||||
private Double xMinimum;
|
||||
private Double xMaximum;
|
||||
private Double yMinimum;
|
||||
private Double yMaximum;
|
||||
|
||||
public LineModel() {
|
||||
nodes = new LinkedList<>();
|
||||
lines = new LinkedList<>();
|
||||
}
|
||||
|
||||
public void setXbounds() {
|
||||
LinkedList<Double> xlist = new LinkedList<>();
|
||||
for (Point p : nodes) {
|
||||
xlist.add(p.getX());
|
||||
}
|
||||
|
||||
xMaximum = Collections.max(xlist);
|
||||
xMinimum = Collections.min(xlist);
|
||||
}
|
||||
|
||||
public void setYbounds() {
|
||||
LinkedList<Double> ylist = new LinkedList<>();
|
||||
for (Point p : nodes) {
|
||||
ylist.add(p.getY());
|
||||
}
|
||||
|
||||
yMaximum = Collections.max(ylist);
|
||||
yMinimum = Collections.min(ylist);
|
||||
}
|
||||
|
||||
public void addNode(Point node) {
|
||||
this.nodes.add(node);
|
||||
}
|
||||
|
||||
public void addLine(Line line) {
|
||||
this.lines.add(line);
|
||||
}
|
||||
|
||||
public LinkedList<Point> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public LinkedList<Line> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
public void setLines(LinkedList<Line> lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
public Double getxMinimum() {
|
||||
return xMinimum;
|
||||
}
|
||||
|
||||
public void setxMinimum(Double xMinimum) {
|
||||
this.xMinimum = xMinimum;
|
||||
}
|
||||
|
||||
public Double getxMaximum() {
|
||||
return xMaximum;
|
||||
}
|
||||
|
||||
public void setxMaximum(Double xMaximum) {
|
||||
this.xMaximum = xMaximum;
|
||||
}
|
||||
|
||||
public Double getyMinimum() {
|
||||
return yMinimum;
|
||||
}
|
||||
|
||||
public void setyMinimum(Double yMinimum) {
|
||||
this.yMinimum = yMinimum;
|
||||
}
|
||||
|
||||
public Double getyMaximum() {
|
||||
return yMaximum;
|
||||
}
|
||||
|
||||
public void setyMaximum(Double yMaximum) {
|
||||
this.yMaximum = yMaximum;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package model;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 19.06.2017.
|
||||
*/
|
||||
public class Pair {
|
||||
|
||||
private Integer p1;
|
||||
private Integer p2;
|
||||
|
||||
public Pair(Integer p1, Integer p2) {
|
||||
this.p1 = p1;
|
||||
this.p2 = p2;
|
||||
}
|
||||
|
||||
public Integer getP1() {
|
||||
return p1;
|
||||
}
|
||||
|
||||
public void setP1(Integer p1) {
|
||||
this.p1 = p1;
|
||||
}
|
||||
|
||||
public Integer getP2() {
|
||||
return p2;
|
||||
}
|
||||
|
||||
public void setP2(Integer p2) {
|
||||
this.p2 = p2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package model;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class Point implements Comparable<Point> {
|
||||
|
||||
private Double x;
|
||||
private Double y;
|
||||
private String id;
|
||||
|
||||
public Point(Double x, Double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Point(Double x, Double y, String id) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(Double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public Double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(Double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Point o) {
|
||||
if (this.getX() == o.getX()) {
|
||||
if (this.getY() <= o.getY()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else if (this.getX() < o.getX()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
package presenter;
|
||||
|
||||
import model.Interval;
|
||||
import model.Line;
|
||||
import model.LineModel;
|
||||
import presenter.algorithms.IntersectionCounter;
|
||||
import presenter.evaluation.EvaluateAlgorithms;
|
||||
import view.MainFrame;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 10.09.2017.
|
||||
*/
|
||||
public abstract class AbstractPresenter implements Observer {
|
||||
|
||||
private LineModel model;
|
||||
private MainFrame view;
|
||||
|
||||
private EvaluateAlgorithms eval;
|
||||
|
||||
|
||||
public AbstractPresenter(LineModel model, MainFrame view) {
|
||||
this.model = model;
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
String[] result = ((String[]) arg);
|
||||
|
||||
if (result[0] == "eval-dataset-generated") {
|
||||
SwingUtilities.invokeLater(() -> getView().addEvalDataset(getEval().getData()));
|
||||
}
|
||||
|
||||
if (result[0] == "eval-d") {
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result, Integer.parseInt(result[1]), false));
|
||||
}
|
||||
|
||||
if (result[0] == "eval-ds") {
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result));
|
||||
}
|
||||
|
||||
if (result[0] == "eval-t") {
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result, Integer.parseInt(result[1]), true));
|
||||
}
|
||||
|
||||
if (result[0] == "lines-res") {
|
||||
SwingUtilities.invokeLater(() -> getView().drawLineResult(result, Integer.parseInt(result[1])));
|
||||
}
|
||||
|
||||
if (result[0] == "lines-res-mult") {
|
||||
SwingUtilities.invokeLater(() -> getView().drawLineResults(result));
|
||||
}
|
||||
|
||||
if (result[0] == "lms") {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().visualizeLMS(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
|
||||
//getView().setLmsIsComplete(true);
|
||||
getView().logHeading("Least Median of Squares");
|
||||
getView().log("<b>m:</b> " + result[1]);
|
||||
getView().log("<b>b:</b> " + result[2]);
|
||||
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
|
||||
});
|
||||
}
|
||||
|
||||
if (result[0] == "rm") {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().visualizeRM(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
|
||||
getView().logHeading("Repeated Median Estimator");
|
||||
getView().log("<b>m:</b> " + result[1]);
|
||||
getView().log("<b>b:</b> " + result[2]);
|
||||
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
|
||||
});
|
||||
}
|
||||
|
||||
if (result[0] == "ts") {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().visualizeTS(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
|
||||
getView().logHeading("Theil-Sen Estimator");
|
||||
getView().log("<b>m:</b> " + result[1]);
|
||||
getView().log("<b>b:</b> " + result[2]);
|
||||
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
|
||||
});
|
||||
}
|
||||
|
||||
if (result[0] == "import") {
|
||||
Double max = Double.parseDouble(result[1]);
|
||||
Double current = Double.parseDouble(result[2]);
|
||||
Integer progress = (int) (100 * (current / max));
|
||||
//100% erreicht
|
||||
if (progress == 100) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().showImportProgress(progress);
|
||||
getView().enableFunctionality();
|
||||
getView().getProgressDialog().dispose();
|
||||
});
|
||||
setup();
|
||||
Thread t = new Thread(() -> {
|
||||
calculateIntersections();
|
||||
});
|
||||
t.start();
|
||||
try {
|
||||
t.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().showImportProgress(progress);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (result[0] == "export") {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().logSuccess("Export Erfolgreich");
|
||||
getView().log(result[1] + "<hr>");
|
||||
});
|
||||
}
|
||||
|
||||
if (result[0] == "generator") {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
getView().logSuccess("Generierung Erfolgreich");
|
||||
getView().log(result[1] + "<hr>");
|
||||
setup();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void setup() {
|
||||
//Darstellung der Schnittpunkte in einer Tabelle
|
||||
List<String> heading = new LinkedList<>();
|
||||
List<List<String>> rows = new LinkedList<>();
|
||||
heading.add("Geraden im Dualraum");
|
||||
for (int j = 0; j < getModel().getLines().size() - 2; j++) {
|
||||
LinkedList<String> rowEntry = new LinkedList<>();
|
||||
Line p1 = getModel().getLines().get(j);
|
||||
String sign = p1.getB() < 0 ? "" : "+";
|
||||
rowEntry.add("f(x) = " +String.format("%.3f", p1.getM()) + "x "+ sign + String.format("%.3f",p1.getB()));
|
||||
|
||||
if (j + 1 < getModel().getLines().size()) {
|
||||
Line p2 = getModel().getLines().get(j + 1);
|
||||
sign = p2.getB() < 0 ? "" : "+";
|
||||
rowEntry.add("f(x) = " +String.format("%.3f",p2.getM()) + "x" + sign + String.format("%.3f", p2.getB()));
|
||||
}
|
||||
|
||||
if (j + 2 < getModel().getLines().size()) {
|
||||
Line p3 = getModel().getLines().get(j + 2);
|
||||
sign = p3.getB() < 0 ? "" : "+";
|
||||
rowEntry.add("f(x) = " + String.format("%.3f",p3.getM()) + "x"+ sign + String.format("%.3f",p3.getB()));
|
||||
}
|
||||
rows.add(rowEntry);
|
||||
}
|
||||
getView().createTable(heading, rows);
|
||||
|
||||
getView().log("<hr>");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void calculateIntersections() {
|
||||
try {
|
||||
Thread thread = new Thread(() -> {
|
||||
IntersectionCounter counter = new IntersectionCounter();
|
||||
counter.run(getModel().getLines(), new Interval(-99999, 99999));
|
||||
counter.calculateIntersectionAbscissas(getModel());
|
||||
getModel().setXbounds();
|
||||
getModel().setYbounds();
|
||||
|
||||
});
|
||||
thread.start();
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public LineModel getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(LineModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public MainFrame getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
public void setView(MainFrame view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public EvaluateAlgorithms getEval() {
|
||||
return eval;
|
||||
}
|
||||
|
||||
public void setEval(EvaluateAlgorithms eval) {
|
||||
this.eval = eval;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
package presenter;
|
||||
|
||||
import model.LineModel;
|
||||
import presenter.algorithms.LeastMedianOfSquaresEstimator;
|
||||
import presenter.algorithms.RepeatedMedianEstimator;
|
||||
import presenter.algorithms.TheilSenEstimator;
|
||||
import presenter.evaluation.EvaluateAlgorithms;
|
||||
import presenter.generator.DatasetGenerator;
|
||||
import presenter.io.DataExporter;
|
||||
import presenter.io.DataImporter;
|
||||
import presenter.io.EvalResultLatexExport;
|
||||
import view.MainFrame;
|
||||
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import java.io.File;
|
||||
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class Presenter extends AbstractPresenter{
|
||||
|
||||
/* Threads */
|
||||
private Thread tsThread;
|
||||
private Thread rmThread;
|
||||
private Thread lmsThread;
|
||||
private Thread importThread;
|
||||
private Thread exportThread;
|
||||
private Thread exportResultThread;
|
||||
private Thread generatorThread;
|
||||
private Thread evalThread;
|
||||
|
||||
public Presenter(LineModel model, MainFrame view) {
|
||||
super(model, view);
|
||||
}
|
||||
|
||||
|
||||
public void visualizeDualLines() {
|
||||
getView().createDualityDialog();
|
||||
}
|
||||
|
||||
/***************************************************************************************************************************
|
||||
* Ausführung der Algorithmen
|
||||
***************************************************************************************************************************/
|
||||
public void calculateLMS(String[] input) {
|
||||
if (input[0] != null && input[1] != null) {
|
||||
if (lmsThread == null || !lmsThread.isAlive()) {
|
||||
lmsThread = new Thread(() -> {
|
||||
Double constant = Double.parseDouble(input[0]);
|
||||
Double error = Double.parseDouble(input[1]);
|
||||
LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
|
||||
lms.setConstant(constant);
|
||||
lms.setQuantileError(error);
|
||||
lms.addObserver(this);
|
||||
lms.run();
|
||||
lms.getResult();
|
||||
});
|
||||
lmsThread.start();
|
||||
try {
|
||||
lmsThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateRM(String input) {
|
||||
if (input != null) {
|
||||
if (rmThread == null || !rmThread.isAlive()) {
|
||||
rmThread = new Thread(() -> {
|
||||
RepeatedMedianEstimator rm = new RepeatedMedianEstimator(getModel().getLines(), this);
|
||||
Double parameter = Double.parseDouble(input);
|
||||
rm.setBeta(parameter);
|
||||
rm.addObserver(this);
|
||||
rm.run();
|
||||
rm.getResult();
|
||||
});
|
||||
rmThread.start();
|
||||
try {
|
||||
rmThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateTS(String input) {
|
||||
if (input != null) {
|
||||
if (tsThread == null || !tsThread.isAlive()) {
|
||||
tsThread = new Thread(() -> {
|
||||
TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(), this);
|
||||
ts.addObserver(this);
|
||||
ts.run();
|
||||
ts.getResult();
|
||||
});
|
||||
tsThread.start();
|
||||
try {
|
||||
tsThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************************************************
|
||||
* Hilfsmethoden
|
||||
***************************************************************************************************************************/
|
||||
|
||||
public void startImport(File file) {
|
||||
if (importThread == null || !importThread.isAlive()) {
|
||||
importThread = new Thread(() -> {
|
||||
DataImporter importer = new DataImporter(file, this);
|
||||
importer.addObserver(this);
|
||||
importer.run();
|
||||
});
|
||||
importThread.start();
|
||||
try {
|
||||
importThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startExport(File file) {
|
||||
if (exportThread == null || !exportThread.isAlive()) {
|
||||
exportThread = new Thread(() -> {
|
||||
DataExporter exporter = new DataExporter(getModel(), file);
|
||||
exporter.addObserver(this);
|
||||
exporter.export();
|
||||
});
|
||||
exportThread.start();
|
||||
try {
|
||||
exportThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startResultExport(DefaultTableModel model, File file) {
|
||||
if (exportResultThread == null || !exportResultThread.isAlive()) {
|
||||
exportResultThread = new Thread(() -> {
|
||||
EvalResultLatexExport exporter = new EvalResultLatexExport(model, file);
|
||||
exporter.writeFile();
|
||||
});
|
||||
exportResultThread.start();
|
||||
try {
|
||||
exportResultThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateDataset() {
|
||||
if (generatorThread == null || !generatorThread.isAlive()) {
|
||||
generatorThread = new Thread(() -> {
|
||||
DatasetGenerator generator = new DatasetGenerator();
|
||||
generator.addObserver(this);
|
||||
getModel().setLines(generator.generateCircle(100));
|
||||
calculateIntersections();
|
||||
getView().enableFunctionality();
|
||||
});
|
||||
generatorThread.start();
|
||||
try {
|
||||
generatorThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startEvaluation(int typ, int n, int alg, String datasettyp) {
|
||||
|
||||
if (evalThread == null || !evalThread.isAlive()) {
|
||||
evalThread = new Thread(() -> {
|
||||
try {
|
||||
setEval(new EvaluateAlgorithms(typ, n, alg, datasettyp));
|
||||
getEval().addObserver(this);
|
||||
getEval().run();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
evalThread.start();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package Presenter.Algorithms;
|
||||
package presenter.algorithms;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
|
@ -9,6 +9,7 @@ package Presenter.Algorithms;
|
|||
*/
|
||||
public interface Algorithm {
|
||||
|
||||
void run();
|
||||
void getResult();
|
||||
void run();
|
||||
|
||||
void getResult();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package presenter.algorithms;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 26.06.2017.
|
||||
*/
|
||||
public class BinomialCoeffizient {
|
||||
|
||||
public static Double run(int n, int k) {
|
||||
int res = 1;
|
||||
|
||||
if (k > n - k)
|
||||
k = n - k;
|
||||
|
||||
for (int i = 0; i < k; ++i) {
|
||||
res *= (n - i);
|
||||
res /= (i + 1);
|
||||
}
|
||||
|
||||
return Double.valueOf(res);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package Presenter.Algorithms.Comparators;
|
||||
package presenter.algorithms.Comparators;
|
||||
|
||||
import model.Line;
|
||||
|
||||
import Model.Line;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
|
@ -12,8 +13,8 @@ import java.util.Comparator;
|
|||
*/
|
||||
public class YOrderLineComparatorBegin implements Comparator<Line> {
|
||||
|
||||
@Override
|
||||
public int compare(Line o1, Line o2) {
|
||||
@Override
|
||||
public int compare(Line o1, Line o2) {
|
||||
// if (o1.getY1() == o2.getY1()) {
|
||||
// if (o1.getX1() <= o2.getX1()) {
|
||||
// return -1;
|
||||
|
@ -25,6 +26,6 @@ public class YOrderLineComparatorBegin implements Comparator<Line> {
|
|||
// } else {
|
||||
// return 1;
|
||||
// }
|
||||
return o1.getY1().compareTo(o2.getY1());
|
||||
}
|
||||
return o1.getY1().compareTo(o2.getY1());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package Presenter.Algorithms.Comparators;
|
||||
package presenter.algorithms.Comparators;
|
||||
|
||||
import model.Line;
|
||||
|
||||
import Model.Line;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
|
@ -12,8 +13,8 @@ import java.util.Comparator;
|
|||
*/
|
||||
public class YOrderLineComparatorEnd implements Comparator<Line> {
|
||||
|
||||
@Override
|
||||
public int compare(Line o1, Line o2) {
|
||||
@Override
|
||||
public int compare(Line o1, Line o2) {
|
||||
// if (o1.getY2() == o2.getY2()) {
|
||||
// if (o1.getX2() <= o2.getX2()) {
|
||||
// return -1;
|
||||
|
@ -25,6 +26,6 @@ public class YOrderLineComparatorEnd implements Comparator<Line> {
|
|||
// } else {
|
||||
// return 1;
|
||||
// }
|
||||
return o1.getY2().compareTo(o2.getY2());
|
||||
}
|
||||
return o1.getY2().compareTo(o2.getY2());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
package Presenter.Algorithms;
|
||||
|
||||
import Presenter.Presenter;
|
||||
package presenter.algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -12,43 +10,39 @@ import java.util.Random;
|
|||
public class FastElementSelector {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param a
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public static Double randomizedSelect(ArrayList<Double> a, double i) {
|
||||
int start = 0;
|
||||
int end = a.size()-1;
|
||||
int end = a.size() - 1;
|
||||
|
||||
if (i >= end+1){
|
||||
if (i >= end + 1) {
|
||||
return a.get(end);
|
||||
}
|
||||
|
||||
while(true){
|
||||
|
||||
if(start == end){
|
||||
while (true) {
|
||||
if (start >= end) {
|
||||
return a.get(start);
|
||||
}
|
||||
int q = randomizedPartition(a, start, end);
|
||||
int k = q-start+1;
|
||||
int k = q - start + 1;
|
||||
|
||||
if(i == k){
|
||||
if (i == k) {
|
||||
return a.get(q);
|
||||
}
|
||||
else{
|
||||
if(i <k){
|
||||
} else {
|
||||
if (i < k) {
|
||||
end = q - 1;
|
||||
}else{
|
||||
i = i - k;
|
||||
} else {
|
||||
start = q + 1;
|
||||
i = i - k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param a
|
||||
* @param start
|
||||
* @param end
|
||||
|
@ -59,10 +53,10 @@ public class FastElementSelector {
|
|||
Random random = new Random(System.currentTimeMillis());
|
||||
|
||||
//alternative: ThreadLocalRandom.current()
|
||||
if(start < end){
|
||||
i = start + random.nextInt(end-start);
|
||||
}else{
|
||||
i = end + random.nextInt(start-end);
|
||||
if (start < end) {
|
||||
i = start + random.nextInt(end - start);
|
||||
} else {
|
||||
i = end + random.nextInt(start - end);
|
||||
}
|
||||
|
||||
Collections.swap(a, end, i);
|
||||
|
@ -70,7 +64,6 @@ public class FastElementSelector {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param a
|
||||
* @param start
|
||||
* @param end
|
||||
|
@ -79,13 +72,13 @@ public class FastElementSelector {
|
|||
private static int partition(ArrayList<Double> a, int start, int end) {
|
||||
Double x = a.get(end);
|
||||
int i = start - 1;
|
||||
for (int j = start; j <= end-1; j++) {
|
||||
for (int j = start; j <= end - 1; j++) {
|
||||
if (a.get(j) <= x) {
|
||||
i++;
|
||||
Collections.swap(a, i, j);
|
||||
}
|
||||
}
|
||||
Collections.swap(a, i+1, end);
|
||||
return i+1;
|
||||
Collections.swap(a, i + 1, end);
|
||||
return i + 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
package presenter.algorithms;
|
||||
|
||||
import model.*;
|
||||
import presenter.algorithms.Comparators.YOrderLineComparatorBegin;
|
||||
import presenter.algorithms.Comparators.YOrderLineComparatorEnd;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 18.06.2017.
|
||||
*/
|
||||
public class IntersectionCounter {
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Berechnet die Inversionen zwischen zwei Listen mit Integer Werten. Diese Methode dient als
|
||||
* Wrapper Methode. Die Logik steht in der <code>countInversions</code> Funktion.
|
||||
*
|
||||
* @param a Liste
|
||||
* @param b Liste
|
||||
* @return Anzahl an Inversionen
|
||||
*/
|
||||
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);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper Methode um herauszufinden wieviele Inversionen zwischen den Schnittpunkten der Werte
|
||||
* in der Liste und den Endpunkten des Intervalls entstehen.
|
||||
*
|
||||
* @param set Liste mit Werten (m,b) um Schnittpunkte zu berechnen
|
||||
* @param interval Interval
|
||||
* @return Anzahl an Inversionen
|
||||
*/
|
||||
public int run(List<Line> set, Interval interval) {
|
||||
ArrayList<Integer> listA = new ArrayList<>();
|
||||
ArrayList<Integer> listB = new ArrayList<>();
|
||||
|
||||
prepareData(set, interval, listA, listB);
|
||||
return run(listA, listB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Methode die, die Daten für die Funktion <code>run</code> vorbereitet. Es werden die Schnittpunkte
|
||||
* bzgl. der unteren und oberen Grenze des Intervals und den Werten der Liste (m,b) berechnet. Diese
|
||||
* Werte haben die selbe x Koordinate aber verschiedene y Koordinaten.
|
||||
*
|
||||
* @param set Liste mit Werten m,b
|
||||
* @param interval Interval
|
||||
* @param listA Schnittpunkte bzgl. unteren Grenze
|
||||
* @param listB Schnittpunkte bzgl. oberen Grenze
|
||||
*/
|
||||
private void prepareData(List<Line> set, Interval interval, 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(), interval.getLower() * p.getM() + p.getB(),
|
||||
interval.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 Temporäres Array das beim Mergen eine Kopie des original Arrays ist.
|
||||
* @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;
|
||||
//hier beginnt das merging
|
||||
//iteriere über die Teillisten
|
||||
//Two-way Merge - Knuth Vol 3 The Art of Computer Programming -
|
||||
while (left <= mid && right <= end) {
|
||||
//wenn die linke Teilliste das kleinere Element besitzt kopiere
|
||||
//das Element in das neue Array
|
||||
if (aux.get(left) < aux.get(right)) {
|
||||
a.set(index++, aux.get(left++));
|
||||
} else {
|
||||
//merke die inversionspaare
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
|
||||
*
|
||||
* @return Map mit Schnittpunkt Paaren.
|
||||
*/
|
||||
public HashMap<Line, ArrayList<Line>> getIntersectionLinePairs() {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
|
||||
*/
|
||||
public void calculateIntersectionAbscissas(LineModel model) {
|
||||
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) {
|
||||
Line line = secondaryDictionaryBACK.get(p.getP1());
|
||||
Line sampledLine = secondaryDictionaryBACK.get(p.getP2());
|
||||
if (!line.equals(sampledLine)) {
|
||||
double intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
|
||||
double yintercept = sampledLine.getM() * intersection + sampledLine.getB();
|
||||
model.addNode(new Point(intersection, yintercept));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet die Schnittpunkte zwischen einer gegebenen Gerade und einer Menge an Geraden.
|
||||
*
|
||||
* @param set Menge an Geraden
|
||||
* @param sampledLine eine spezielle Gerade
|
||||
* @return Liste mit x Koordinaten der Schnittpunkte
|
||||
*/
|
||||
public ArrayList<Double> calculateIntersectionAbscissas(ArrayList<Line> set, Line sampledLine) {
|
||||
LinkedList<Line> lines = new LinkedList<>(set);
|
||||
ArrayList<Double> intersections = new ArrayList<>();
|
||||
double intersection;
|
||||
|
||||
for (Line line : lines) {
|
||||
if (line != sampledLine) {
|
||||
intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
|
||||
intersections.add(intersection);
|
||||
}
|
||||
}
|
||||
|
||||
return intersections;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,478 @@
|
|||
package presenter.algorithms;
|
||||
|
||||
import model.Interval;
|
||||
import model.Line;
|
||||
import model.Point;
|
||||
import presenter.Presenter;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class LeastMedianOfSquaresEstimator extends Observable implements Algorithm {
|
||||
|
||||
|
||||
private Presenter presenter;
|
||||
|
||||
private LinkedList<Line> set = new LinkedList<>();
|
||||
private LinkedList<Point> intersections = new LinkedList<>();
|
||||
private IntersectionCounter invCounter = new IntersectionCounter();
|
||||
private int n;
|
||||
private double quantileError;
|
||||
private int kPlus;
|
||||
private int kMinus;
|
||||
private PriorityQueue<Interval> intervals;
|
||||
private Interval subSlabU1;
|
||||
private Interval subSlabU2;
|
||||
private Line sigmaMin;
|
||||
private double heightsigmaMin;
|
||||
private Double intersectionsPoint;
|
||||
private Double constant = 0.5;
|
||||
|
||||
private Double slope;
|
||||
private Double yInterception;
|
||||
|
||||
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections,
|
||||
Presenter presenter) {
|
||||
this.set = set;
|
||||
this.intersections = intersections;
|
||||
|
||||
//(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);....
|
||||
n = set.size();
|
||||
double quantile = 0.5;
|
||||
double qPlus = quantile;
|
||||
quantileError = 0.1;
|
||||
double qMinus = qPlus * (1 - quantileError);
|
||||
kMinus = (int) Math.ceil(n * qMinus);
|
||||
kPlus = (int) Math.ceil(n * qPlus);
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections) {
|
||||
this(set, intersections, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
//(2.) Let U <- (-inf, inf) be the initial active intervals...
|
||||
Comparator<Interval> comparator = (o1, o2) -> {
|
||||
if (o1.getDistance() < o2.getDistance()) {
|
||||
return -1;
|
||||
}
|
||||
if (o1.getDistance() > o2.getDistance()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
intervals = new PriorityQueue<>(comparator);
|
||||
intervals.add(new Interval(-100000, 100000));
|
||||
heightsigmaMin = Double.MAX_VALUE;
|
||||
LinkedList<Point> tmpIntersections = intersections;
|
||||
|
||||
//(3.) Apply the following steps as long as the exists active intervals
|
||||
boolean active = true;
|
||||
Interval interval;
|
||||
while (!this.intervals.isEmpty()) {
|
||||
interval = this.intervals.peek();
|
||||
if (interval.getActivity()) {
|
||||
//(a.) Select any active Interval and calc. the inversions
|
||||
int numberOfIntersections = countInversions(interval);
|
||||
|
||||
//(b.) apply plane sweep
|
||||
if ((constant * n) >= numberOfIntersections) {
|
||||
sigmaMin = planeSweep(interval);
|
||||
} 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() > interval.getLower()
|
||||
&& tmpIntersections.get(i).getX() < interval.getUpper()) {
|
||||
intersectionsPoint = tmpIntersections.get(i).getX();
|
||||
break;
|
||||
} else {
|
||||
intersectionsPoint = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (intersectionsPoint != null) {
|
||||
splitActiveSlab(intersectionsPoint, interval);
|
||||
//(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.intervals.add(subSlabU1);
|
||||
}
|
||||
if (subSlabU2.getActivity()) {
|
||||
this.intervals.add(subSlabU2);
|
||||
}
|
||||
|
||||
} else {
|
||||
this.intervals.poll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
this.intervals.remove(interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param interval
|
||||
* @return
|
||||
*/
|
||||
public int countInversions(Interval interval) {
|
||||
|
||||
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, interval);
|
||||
|
||||
return numberOfInversions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param interval
|
||||
* @return
|
||||
*/
|
||||
public Line planeSweep(Interval interval) {
|
||||
|
||||
//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() >= interval.getLower() && point.getX() < interval.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]);
|
||||
}
|
||||
}
|
||||
|
||||
interval.setActivity(false);
|
||||
return bracelet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode spaltet den aktiven Interval 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, Interval active) {
|
||||
subSlabU1 = new Interval(active.getLower() + 0.01, point);
|
||||
subSlabU2 = new Interval(point, active.getUpper());
|
||||
|
||||
this.intervals.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(Interval 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 {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResult() {
|
||||
if (presenter != null) {
|
||||
setChanged();
|
||||
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
|
||||
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
|
||||
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
|
||||
String[] result = {"lms", m + "", b + ""};
|
||||
notifyObservers(result);
|
||||
} else {
|
||||
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
|
||||
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
|
||||
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den
|
||||
* JUnit Testfällen.
|
||||
*/
|
||||
|
||||
public LinkedList<Line> getSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
public void setSet(LinkedList<Line> set) {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public LinkedList<Point> getIntersections() {
|
||||
return intersections;
|
||||
}
|
||||
|
||||
public void setIntersections(LinkedList<Point> intersections) {
|
||||
this.intersections = intersections;
|
||||
}
|
||||
|
||||
public int getN() {
|
||||
return n;
|
||||
}
|
||||
|
||||
public void setN(int n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public double getQuantileError() {
|
||||
return quantileError;
|
||||
}
|
||||
|
||||
public void setQuantileError(double quantileError) {
|
||||
this.quantileError = quantileError;
|
||||
}
|
||||
|
||||
public int getkPlus() {
|
||||
return kPlus;
|
||||
}
|
||||
|
||||
public void setkPlus(int kPlus) {
|
||||
this.kPlus = kPlus;
|
||||
}
|
||||
|
||||
public int getkMinus() {
|
||||
return kMinus;
|
||||
}
|
||||
|
||||
public void setkMinus(int kMinus) {
|
||||
this.kMinus = kMinus;
|
||||
}
|
||||
|
||||
public Interval getSubSlabU1() {
|
||||
return subSlabU1;
|
||||
}
|
||||
|
||||
public void setSubSlabU1(Interval subSlabU1) {
|
||||
this.subSlabU1 = subSlabU1;
|
||||
}
|
||||
|
||||
public Interval getSubSlabU2() {
|
||||
return subSlabU2;
|
||||
}
|
||||
|
||||
public void setSubSlabU2(Interval subSlabU2) {
|
||||
this.subSlabU2 = subSlabU2;
|
||||
}
|
||||
|
||||
public Line getSigmaMin() {
|
||||
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;
|
||||
}
|
||||
|
||||
public Double getSlope() {
|
||||
return slope;
|
||||
}
|
||||
|
||||
public Double getyInterception() {
|
||||
return yInterception;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package presenter.algorithms;
|
||||
|
||||
import model.Line;
|
||||
import model.Point;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 26.06.2017.
|
||||
*/
|
||||
public class RandomSampler {
|
||||
|
||||
/**
|
||||
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe an Geraden.
|
||||
*
|
||||
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
|
||||
* @param r Anzahl der zu wählenden Geraden
|
||||
* @return <code>r</code> Elementige zufällige Stichprobe an Geraden
|
||||
*/
|
||||
public static ArrayList<Line> run(ArrayList<Line> set, Double r, Integer indexOfEnd) {
|
||||
|
||||
ArrayList<Line> sampledLines = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < r; i++) {
|
||||
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, indexOfEnd)));
|
||||
}
|
||||
|
||||
return sampledLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe van Schnittpunkten.
|
||||
*
|
||||
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
|
||||
* @param r Anzahl der zu wählenden Geraden
|
||||
* @return <code>r</code> Elementige zufällige Stichprobe an Schnittpunkten
|
||||
*/
|
||||
public static ArrayList<Double> run(ArrayList<Point> set, Double r) {
|
||||
|
||||
ArrayList<Double> sampledLines = new ArrayList<>();
|
||||
Integer indexOfEnd = set.size();
|
||||
|
||||
for (int i = 0; i < r; i++) {
|
||||
Double px = set.get(ThreadLocalRandom.current().nextInt(0, indexOfEnd)).getX();
|
||||
if (!sampledLines.contains(px))
|
||||
sampledLines.add(px);
|
||||
}
|
||||
|
||||
return sampledLines;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,459 @@
|
|||
package presenter.algorithms;
|
||||
|
||||
import model.Interval;
|
||||
import model.Line;
|
||||
import presenter.Presenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class RepeatedMedianEstimator extends Observable implements Algorithm {
|
||||
|
||||
private Presenter presenter;
|
||||
private LinkedList<Line> set;
|
||||
private HashMap<Line, ArrayList<Line>> linePairs;
|
||||
private HashMap<Line, Double> medianIntersections = new HashMap<>();
|
||||
private HashMap<Line, ArrayList<Double>> intersectionAbscissas = new HashMap<>();
|
||||
private Interval interval;
|
||||
|
||||
//in der Literatur als L_i, C_i, und R_i bekannt
|
||||
private ArrayList<Double> countLeftSlab;
|
||||
private ArrayList<Double> countCenterSlab;
|
||||
private ArrayList<Double> countRightSlab;
|
||||
|
||||
//die Mengen L,C und R
|
||||
private ArrayList<Line> linesInLeftSlab;
|
||||
private ArrayList<Line> linesInCenterSlab;
|
||||
private ArrayList<Line> linesInRightSlab;
|
||||
|
||||
private Double r;
|
||||
private Integer n;
|
||||
private Double k;
|
||||
private Double kLow;
|
||||
private Double kHigh;
|
||||
private Double beta;
|
||||
|
||||
private Double thetaLow;
|
||||
private Double thetaHigh;
|
||||
|
||||
private Double slope;
|
||||
private Double yInterception;
|
||||
|
||||
|
||||
public RepeatedMedianEstimator(LinkedList<Line> set, Presenter presenter) {
|
||||
this.set = set;
|
||||
this.presenter = presenter;
|
||||
interval = new Interval(-10000, 10000);
|
||||
n = set.size();
|
||||
beta = 0.5;
|
||||
countLeftSlab = new ArrayList<>();
|
||||
countCenterSlab = new ArrayList<>();
|
||||
countRightSlab = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
countLeftSlab.add(0d);
|
||||
countRightSlab.add(0d);
|
||||
countCenterSlab.add(n - 1.0);
|
||||
intersectionAbscissas.put(set.get(i), new ArrayList<>());
|
||||
}
|
||||
|
||||
linesInLeftSlab = new ArrayList<>();
|
||||
linesInCenterSlab = new ArrayList<>(set);
|
||||
linesInRightSlab = new ArrayList<>();
|
||||
linePairs = new HashMap<>();
|
||||
}
|
||||
|
||||
public RepeatedMedianEstimator(LinkedList<Line> set) {
|
||||
this(set, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
while (linesInCenterSlab.size() != 1) {
|
||||
n = linesInCenterSlab.size();
|
||||
r = Math.ceil(Math.pow(n, beta));
|
||||
ArrayList<Line> lines = RandomSampler.run(linesInCenterSlab, r, linesInCenterSlab.size());
|
||||
|
||||
|
||||
//For each Sampled Line, compute its median intersection abscissa
|
||||
ArrayList<Double> medianIntersectionAbscissas = new ArrayList<>();
|
||||
for (Line l : lines) {
|
||||
Double abscissa = estimateMedianIntersectionAbscissas(l);
|
||||
medianIntersections.put(l, abscissa);
|
||||
medianIntersectionAbscissas.add(abscissa);
|
||||
}
|
||||
|
||||
//rank of the repeated median in C
|
||||
k = Math.max(1, Math.min(set.size(), (Math.ceil(n * 0.5) - linesInLeftSlab.size())));
|
||||
|
||||
//compute k_lo and k_hi
|
||||
computeSlabBorders();
|
||||
|
||||
|
||||
// if (medianIntersectionAbscissas.size() < kLow || medianIntersectionAbscissas.size()<kHigh || kLow < 0 || kHigh<0 )
|
||||
// System.err.print("#medianIntersectionAbscissa: "+medianIntersectionAbscissas.size()+"\t\t klow: "+kLow+" kHigh: "+kHigh+"\n\n");
|
||||
|
||||
//Employ fast selection algorithm to determine the Elements Theta_lo and Theta_hi
|
||||
thetaLow = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kLow);
|
||||
thetaHigh = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kHigh);
|
||||
|
||||
//For each dual Line in C count the number of intersection abscissas that lie
|
||||
//in each of the intervals.
|
||||
countNumberOfIntersectionsAbscissas();
|
||||
|
||||
//Based on this 3 counts, determine which of the subintervals contains the repeated median
|
||||
//and contract to this subiinterval.
|
||||
contractIntervals();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param set
|
||||
* @param r
|
||||
* @return
|
||||
*/
|
||||
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, linesInCenterSlab.size())));
|
||||
}
|
||||
|
||||
return sampledLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sampledLine
|
||||
* @return
|
||||
*/
|
||||
public Double estimateMedianIntersectionAbscissas(Line sampledLine) {
|
||||
|
||||
Integer index = Integer.parseInt(sampledLine.getId());
|
||||
ArrayList<Double> intersections = new ArrayList<>();
|
||||
double intersection;
|
||||
|
||||
IntersectionCounter intersectionCounter = new IntersectionCounter();
|
||||
intersections = intersectionCounter.calculateIntersectionAbscissas(linesInCenterSlab, sampledLine);
|
||||
|
||||
//Collections.sort(intersections);
|
||||
//double ki = Math.ceil((n - 1) / 2) - countLeftSlab.get(index);
|
||||
//double i = (Math.ceil((Math.sqrt(n) * ki) / countCenterSlab.get(index)));
|
||||
double ki = Math.ceil((n - 1) / 2) - FastElementSelector.randomizedSelect(countLeftSlab, index);
|
||||
double i = (Math.ceil((Math.sqrt(n) * ki) / FastElementSelector.randomizedSelect(countCenterSlab, index)));
|
||||
int accessIndex;
|
||||
if (i < 0)
|
||||
accessIndex = 0;
|
||||
else if (i >= intersections.size())
|
||||
accessIndex = intersections.size() - 1;
|
||||
else
|
||||
accessIndex = (int) i;
|
||||
|
||||
//System.out.println(accessIndex);
|
||||
|
||||
//return intersections.get(accessIndex);
|
||||
return FastElementSelector.randomizedSelect(intersections, accessIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void computeSlabBorders() {
|
||||
kLow = Math
|
||||
.max(1, Math.floor(
|
||||
((r * k) / (linesInCenterSlab.size()))
|
||||
- ((3 * Math.sqrt(r)) / (2))
|
||||
)
|
||||
);
|
||||
kHigh = Math
|
||||
.min(r, Math.floor(
|
||||
((r * k) / (linesInCenterSlab.size()))
|
||||
+ ((3 * Math.sqrt(r)) / (2))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void countNumberOfIntersectionsAbscissas() {
|
||||
|
||||
for (Line line : linesInCenterSlab) {
|
||||
ArrayList<Double> intersections = intersectionAbscissas.get(line);
|
||||
Integer index = Integer.parseInt(line.getId());
|
||||
int left = 0;
|
||||
int center = 0;
|
||||
int right = 0;
|
||||
|
||||
for (Double intersection : intersections) {
|
||||
if (intersection <= thetaLow) {
|
||||
left++;
|
||||
} else if (intersection > thetaLow && intersection <= thetaHigh) {
|
||||
center++;
|
||||
} else if (intersection > thetaHigh) {
|
||||
right++;
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("Linie: "+line.getId()+"\tLeft: "+left+"\t Center: "+center+"\t Right: "+right);
|
||||
countLeftSlab.set(index, (double) left);
|
||||
countCenterSlab.set(index, (double) center);
|
||||
countRightSlab.set(index, (double) right);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void contractIntervals() {
|
||||
for (int i = 0; i < linesInCenterSlab.size(); i++) {
|
||||
|
||||
double left = countLeftSlab.get(i);
|
||||
double center = countCenterSlab.get(i);
|
||||
double right = countRightSlab.get(i);
|
||||
|
||||
double max = Math.max(left, Math.max(center, right));
|
||||
|
||||
if (left == max) {
|
||||
linesInLeftSlab.add(linesInCenterSlab.get(i));
|
||||
linesInCenterSlab.remove(i);
|
||||
} else if (right == max) {
|
||||
linesInRightSlab.add(linesInCenterSlab.get(i));
|
||||
linesInCenterSlab.remove(i);
|
||||
}
|
||||
// if (medianIntersections.get(linesInCenterSlab.get(i)) != null) {
|
||||
// if (medianIntersections.get(linesInCenterSlab.get(i)) <= thetaLow) {
|
||||
// linesInLeftSlab.add(linesInCenterSlab.get(i));
|
||||
// linesInCenterSlab.remove(i);
|
||||
// countLeftSlab.set(i, countLeftSlab.get(i) + 1);
|
||||
// countCenterSlab.set(i, countCenterSlab.get(i) - 1);
|
||||
// } else if (medianIntersections.get(linesInCenterSlab.get(i)) > thetaHigh) {
|
||||
// linesInRightSlab.add(linesInCenterSlab.get(i));
|
||||
// linesInCenterSlab.remove(i);
|
||||
// countRightSlab.set(i, countRightSlab.get(i) + 1);
|
||||
// countCenterSlab.set(i, countCenterSlab.get(i) - 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
}
|
||||
|
||||
//wähle C als C
|
||||
if (linesInLeftSlab.size() < Math.ceil(n / 2) && Math.ceil(n / 2) <= linesInLeftSlab.size() + linesInCenterSlab.size()) {
|
||||
interval.setLower(thetaLow + 0.1);
|
||||
interval.setUpper(thetaHigh);
|
||||
}
|
||||
// wähle L als C
|
||||
else if (Math.ceil(n / 2) <= linesInLeftSlab.size()) {
|
||||
interval.setUpper(thetaLow);
|
||||
}
|
||||
//wähle R als C
|
||||
else if (linesInLeftSlab.size() + linesInCenterSlab.size() < Math.ceil(n / 2) && Math.ceil(n / 2) <= (linesInLeftSlab.size() + linesInCenterSlab.size() + linesInRightSlab.size())) {
|
||||
interval.setLower(thetaHigh - 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResult() {
|
||||
if (presenter != null) {
|
||||
setChanged();
|
||||
double m = thetaLow;
|
||||
double b = (-1) * (
|
||||
(linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0)
|
||||
.getB());
|
||||
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
String[] result = new String[]{"rm", m + "", b + ""};
|
||||
notifyObservers(result);
|
||||
} else {
|
||||
double m = thetaLow;
|
||||
double b = (-1) * ((linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0).getB());
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* Getter und Setter Methoden
|
||||
******************************************************************************************************************/
|
||||
public LinkedList<Line> getSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
public void setSet(LinkedList<Line> set) {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public HashMap<Line, ArrayList<Line>> getLinePairs() {
|
||||
return linePairs;
|
||||
}
|
||||
|
||||
public void setLinePairs(HashMap<Line, ArrayList<Line>> linePairs) {
|
||||
this.linePairs = linePairs;
|
||||
}
|
||||
|
||||
public HashMap<Line, Double> getMedianIntersections() {
|
||||
return medianIntersections;
|
||||
}
|
||||
|
||||
public void setMedianIntersections(HashMap<Line, Double> medianIntersections) {
|
||||
this.medianIntersections = medianIntersections;
|
||||
}
|
||||
|
||||
public HashMap<Line, ArrayList<Double>> getIntersectionAbscissas() {
|
||||
return intersectionAbscissas;
|
||||
}
|
||||
|
||||
public void setIntersectionAbscissas(
|
||||
HashMap<Line, ArrayList<Double>> intersectionAbscissas) {
|
||||
this.intersectionAbscissas = intersectionAbscissas;
|
||||
}
|
||||
|
||||
public Interval getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public void setInterval(Interval interval) {
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
public ArrayList<Double> getCountLeftSlab() {
|
||||
return countLeftSlab;
|
||||
}
|
||||
|
||||
public void setCountLeftSlab(ArrayList<Double> countLeftSlab) {
|
||||
this.countLeftSlab = countLeftSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Double> getCountCenterSlab() {
|
||||
return countCenterSlab;
|
||||
}
|
||||
|
||||
public void setCountCenterSlab(ArrayList<Double> countCenterSlab) {
|
||||
this.countCenterSlab = countCenterSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Double> getCountRightSlab() {
|
||||
return countRightSlab;
|
||||
}
|
||||
|
||||
public void setCountRightSlab(ArrayList<Double> countRightSlab) {
|
||||
this.countRightSlab = countRightSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Line> getLinesInLeftSlab() {
|
||||
return linesInLeftSlab;
|
||||
}
|
||||
|
||||
public void setLinesInLeftSlab(ArrayList<Line> linesInLeftSlab) {
|
||||
this.linesInLeftSlab = linesInLeftSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Line> getLinesInCenterSlab() {
|
||||
return linesInCenterSlab;
|
||||
}
|
||||
|
||||
public void setLinesInCenterSlab(ArrayList<Line> linesInCenterSlab) {
|
||||
this.linesInCenterSlab = linesInCenterSlab;
|
||||
}
|
||||
|
||||
public ArrayList<Line> getLinesInRightSlab() {
|
||||
return linesInRightSlab;
|
||||
}
|
||||
|
||||
public void setLinesInRightSlab(ArrayList<Line> linesInRightSlab) {
|
||||
this.linesInRightSlab = linesInRightSlab;
|
||||
}
|
||||
|
||||
public Double getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
public void setR(Double r) {
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
public Integer getN() {
|
||||
return n;
|
||||
}
|
||||
|
||||
public void setN(Integer n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public Double getK() {
|
||||
return k;
|
||||
}
|
||||
|
||||
public void setK(Double k) {
|
||||
this.k = k;
|
||||
}
|
||||
|
||||
public Double getkLow() {
|
||||
return kLow;
|
||||
}
|
||||
|
||||
public void setkLow(Double kLow) {
|
||||
this.kLow = kLow;
|
||||
}
|
||||
|
||||
public Double getkHigh() {
|
||||
return kHigh;
|
||||
}
|
||||
|
||||
public void setkHigh(Double kHigh) {
|
||||
this.kHigh = kHigh;
|
||||
}
|
||||
|
||||
public Double getBeta() {
|
||||
return beta;
|
||||
}
|
||||
|
||||
public void setBeta(Double beta) {
|
||||
this.beta = beta;
|
||||
}
|
||||
|
||||
public Double getThetaLow() {
|
||||
return thetaLow;
|
||||
}
|
||||
|
||||
public void setThetaLow(Double thetaLow) {
|
||||
this.thetaLow = thetaLow;
|
||||
}
|
||||
|
||||
public Double getThetaHigh() {
|
||||
return thetaHigh;
|
||||
}
|
||||
|
||||
public void setThetaHigh(Double thetaHigh) {
|
||||
this.thetaHigh = thetaHigh;
|
||||
}
|
||||
|
||||
public Double getSlope() {
|
||||
return slope;
|
||||
}
|
||||
|
||||
public Double getyInterception() {
|
||||
return yInterception;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
package Presenter.Algorithms;
|
||||
package presenter.algorithms;
|
||||
|
||||
import Model.Interval;
|
||||
import Model.Line;
|
||||
import Model.Point;
|
||||
import Presenter.Presenter;
|
||||
import model.Interval;
|
||||
import model.Line;
|
||||
import model.Point;
|
||||
import presenter.Presenter;
|
||||
|
||||
import com.sun.org.apache.bcel.internal.generic.FASTORE;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -19,20 +18,15 @@ public class TheilSenEstimator extends Observable implements Algorithm {
|
|||
|
||||
private final Double POSITIV_INF = 99999.0;
|
||||
private final Double NEGATIV_INF = -99999.0;
|
||||
|
||||
|
||||
private final Double EPSILON = 0.00001;
|
||||
private Presenter presenter;
|
||||
private ArrayList<Line> setOfLines;
|
||||
private ArrayList<Point> setOfIntersections;
|
||||
private ArrayList<Point> intervalIntersections;
|
||||
private ArrayList<Double> sampledIntersections;
|
||||
|
||||
|
||||
//wird benötigt um den y Achsenabschnitt zu Berechnen
|
||||
private ArrayList<Double> yCoordinates;
|
||||
private ArrayList<Double> xCoordinates;
|
||||
|
||||
|
||||
//Hilfsvariablen (siehe original Paper)
|
||||
private Double j;
|
||||
private Integer jA;
|
||||
|
@ -41,17 +35,13 @@ public class TheilSenEstimator extends Observable implements Algorithm {
|
|||
private Integer n;
|
||||
private Double N;
|
||||
private Integer k;
|
||||
|
||||
//Intervall und die temporaeren Grenzen
|
||||
private Interval interval;
|
||||
private Double aVariant;
|
||||
private Double bVariant;
|
||||
|
||||
private Double slope;
|
||||
private Double yInterception;
|
||||
|
||||
private final Double EPSILON = 0.00001;
|
||||
|
||||
|
||||
public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> setOfIntersections, Presenter presenter) {
|
||||
this.presenter = presenter;
|
||||
|
@ -64,11 +54,11 @@ public class TheilSenEstimator extends Observable implements Algorithm {
|
|||
this.yCoordinates = new ArrayList<>();
|
||||
this.xCoordinates = new ArrayList<>();
|
||||
this.N = BinomialCoeffizient.run(n, 2);
|
||||
this.k = Integer.valueOf((int) (N * 0.5))-1;
|
||||
this.k = Integer.valueOf((int) (N * 0.5)) - 1;
|
||||
}
|
||||
|
||||
public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> setOfIntersections) {
|
||||
this(setOfLines,setOfIntersections,null);
|
||||
this(setOfLines, setOfIntersections, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,9 +124,9 @@ public class TheilSenEstimator extends Observable implements Algorithm {
|
|||
|
||||
Boolean cond1 = conda && condb;
|
||||
|
||||
Boolean cond2 = (higherCount-lowerCount) <= ((11 * N) / Math.sqrt(r));
|
||||
Boolean cond2 = (higherCount - lowerCount) <= ((11 * N) / Math.sqrt(r));
|
||||
|
||||
return cond1 && cond2;
|
||||
return (cond1 && cond2) || (aVariant == bVariant);
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,7 +158,7 @@ public class TheilSenEstimator extends Observable implements Algorithm {
|
|||
*/
|
||||
public int getOpenIntervalSize(double a, double b, ArrayList<Point> set) {
|
||||
int counter = 0;
|
||||
for (int i=0;i<set.size();i++) {
|
||||
for (int i = 0; i < set.size(); i++) {
|
||||
Point x = set.get(i);
|
||||
if (x.getX() > a && x.getX() < b) {
|
||||
counter++;
|
||||
|
@ -188,7 +178,7 @@ public class TheilSenEstimator extends Observable implements Algorithm {
|
|||
*/
|
||||
public ArrayList<Point> getOpenIntervalElements(double a, double b) {
|
||||
ArrayList<Point> list = new ArrayList<>();
|
||||
for (int i=0;i<intervalIntersections.size();i++) {
|
||||
for (int i = 0; i < intervalIntersections.size(); i++) {
|
||||
Point x = intervalIntersections.get(i);
|
||||
if ((x.getX() > a && x.getX() < b) || (Math.abs(interval.getUpper() - interval.getLower())) < EPSILON) {
|
||||
list.add(x);
|
||||
|
@ -207,21 +197,21 @@ public class TheilSenEstimator extends Observable implements Algorithm {
|
|||
ArrayList<Point> resultSt = getOpenIntervalElements(interval.getLower(), interval.getUpper());
|
||||
ArrayList<Double> resultAbscissas = new ArrayList<>();
|
||||
|
||||
for (Point p : resultSt){
|
||||
for (Point p : resultSt) {
|
||||
resultAbscissas.add(p.getX());
|
||||
}
|
||||
|
||||
for (Point p: setOfIntersections) {
|
||||
for (Point p : setOfIntersections) {
|
||||
yCoordinates.add(p.getY());
|
||||
}
|
||||
|
||||
int pseudoIndex = (int) getOpenIntervalSize(NEGATIV_INF, interval.getLower(), setOfIntersections);
|
||||
m = FastElementSelector.randomizedSelect(resultAbscissas, k-pseudoIndex);
|
||||
m = FastElementSelector.randomizedSelect(resultAbscissas, k - pseudoIndex);
|
||||
|
||||
Set<Double> unique = new LinkedHashSet<>(yCoordinates);
|
||||
yCoordinates.clear();
|
||||
yCoordinates.addAll(unique);
|
||||
b = FastElementSelector.randomizedSelect(yCoordinates, yCoordinates.size()*0.5) * -1;
|
||||
b = FastElementSelector.randomizedSelect(yCoordinates, yCoordinates.size() * 0.5) * -1;
|
||||
slope = m;
|
||||
yInterception = b;
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
package Presenter.Evaluation;
|
||||
package presenter.evaluation;
|
||||
|
||||
import Model.Interval;
|
||||
import Model.Line;
|
||||
import Model.LineModel;
|
||||
import Presenter.Algorithms.*;
|
||||
import Presenter.Generator.DatasetGenerator;
|
||||
import model.Interval;
|
||||
import model.Line;
|
||||
import model.LineModel;
|
||||
import presenter.algorithms.IntersectionCounter;
|
||||
import presenter.algorithms.LeastMedianOfSquaresEstimator;
|
||||
import presenter.algorithms.RepeatedMedianEstimator;
|
||||
import presenter.algorithms.TheilSenEstimator;
|
||||
import presenter.generator.DatasetGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Observable;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
|
@ -41,21 +42,22 @@ public class EvaluateAlgorithms extends Observable {
|
|||
private int alg;
|
||||
|
||||
/**
|
||||
* Konstruktor zur Evaluation
|
||||
* @param type Typ der Evaluation
|
||||
* @param n Größe des Datensatzes
|
||||
* @param alg 0 = lms,
|
||||
* 1 = rm,
|
||||
* 2 = ts,
|
||||
* 3 = lms, rm,
|
||||
* 4 = lms, ts,
|
||||
* 5 = rm, ts,
|
||||
* 6 = lms, rm, ts,
|
||||
* Konstruktor zur evaluation
|
||||
*
|
||||
* @param type Typ der evaluation
|
||||
* @param n Größe des Datensatzes
|
||||
* @param alg 0 = lms,
|
||||
* 1 = rm,
|
||||
* 2 = ts,
|
||||
* 3 = lms, rm,
|
||||
* 4 = lms, ts,
|
||||
* 5 = rm, ts,
|
||||
* 6 = lms, rm, ts,
|
||||
*/
|
||||
public EvaluateAlgorithms(int type, int n, int alg, String datasettyp){
|
||||
public EvaluateAlgorithms(int type, int n, int alg, String datasettyp) {
|
||||
this.arrangement = new LineModel();
|
||||
generator = new DatasetGenerator();
|
||||
switch (datasettyp){
|
||||
switch (datasettyp) {
|
||||
case "Punktwolke":
|
||||
arrangement.setLines(generator.generateDataCloud(n));
|
||||
break;
|
||||
|
@ -83,30 +85,30 @@ public class EvaluateAlgorithms extends Observable {
|
|||
ArrayList<String> result;
|
||||
ArrayList<ArrayList<String>> multipleResults = new ArrayList<>();
|
||||
|
||||
switch (type){
|
||||
switch (type) {
|
||||
case 0:
|
||||
result = new ArrayList<>();
|
||||
//der alg der gewählt wurde
|
||||
if (alg == 0) {
|
||||
startLMS();
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
|
||||
sendPlotLineResults(lmsRes,0);
|
||||
} else if (alg == 1) {
|
||||
startRM();
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
|
||||
sendPlotLineResults(rmRes,1);
|
||||
} else {
|
||||
startTS();
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
|
||||
sendPlotLineResults(tsRes,2);
|
||||
}
|
||||
result = new ArrayList<>();
|
||||
//der alg der gewählt wurde
|
||||
if (alg == 0) {
|
||||
startLMS();
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
|
||||
sendPlotLineResults(lmsRes, 0);
|
||||
} else if (alg == 1) {
|
||||
startRM();
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
|
||||
sendPlotLineResults(rmRes, 1);
|
||||
} else {
|
||||
startTS();
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
|
||||
sendPlotLineResults(tsRes, 2);
|
||||
}
|
||||
sendTableApproximationTypes();
|
||||
sendTableApproximationData(result, alg);
|
||||
break;
|
||||
case 1:
|
||||
result = new ArrayList<>();
|
||||
ArrayList<Double[]> lineRes;
|
||||
switch (alg){
|
||||
switch (alg) {
|
||||
case 3:
|
||||
startLMS();
|
||||
startRM();
|
||||
|
@ -121,7 +123,7 @@ public class EvaluateAlgorithms extends Observable {
|
|||
lineRes = new ArrayList<>();
|
||||
lineRes.add(lmsRes);
|
||||
lineRes.add(rmRes);
|
||||
sendPloteLineResults(lineRes, new Integer[]{0,1});
|
||||
sendPloteLineResults(lineRes, new Integer[]{0, 1});
|
||||
break;
|
||||
case 4:
|
||||
startLMS();
|
||||
|
@ -137,7 +139,7 @@ public class EvaluateAlgorithms extends Observable {
|
|||
lineRes = new ArrayList<>();
|
||||
lineRes.add(lmsRes);
|
||||
lineRes.add(tsRes);
|
||||
sendPloteLineResults(lineRes, new Integer[]{0,2});
|
||||
sendPloteLineResults(lineRes, new Integer[]{0, 2});
|
||||
break;
|
||||
case 5:
|
||||
startRM();
|
||||
|
@ -153,7 +155,7 @@ public class EvaluateAlgorithms extends Observable {
|
|||
lineRes = new ArrayList<>();
|
||||
lineRes.add(rmRes);
|
||||
lineRes.add(tsRes);
|
||||
sendPloteLineResults(lineRes, new Integer[]{1,2});
|
||||
sendPloteLineResults(lineRes, new Integer[]{1, 2});
|
||||
break;
|
||||
case 6:
|
||||
startLMS();
|
||||
|
@ -171,7 +173,7 @@ public class EvaluateAlgorithms extends Observable {
|
|||
lineRes.add(lmsRes);
|
||||
lineRes.add(rmRes);
|
||||
lineRes.add(tsRes);
|
||||
sendPloteLineResults(lineRes, new Integer[]{0,1,2});
|
||||
sendPloteLineResults(lineRes, new Integer[]{0, 1, 2});
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -180,14 +182,13 @@ public class EvaluateAlgorithms extends Observable {
|
|||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void sendTableApproximationData(ArrayList<String> result, int col){
|
||||
public void sendTableApproximationData(ArrayList<String> result, int col) {
|
||||
ArrayList<String> tableInput = new ArrayList<>();
|
||||
tableInput.add("eval-d");
|
||||
tableInput.add(""+col);
|
||||
for (int i=0;i<names[type].length;i++) {
|
||||
tableInput.add("" + col);
|
||||
for (int i = 0; i < names[type].length; i++) {
|
||||
tableInput.add(result.get(i));
|
||||
}
|
||||
tableInput.add("");
|
||||
|
@ -196,13 +197,13 @@ public class EvaluateAlgorithms extends Observable {
|
|||
tableInput.clear();
|
||||
}
|
||||
|
||||
public void sendTableApproximationData(ArrayList<ArrayList<String>> result){
|
||||
public void sendTableApproximationData(ArrayList<ArrayList<String>> result) {
|
||||
ArrayList<String> tableInput = new ArrayList<>();
|
||||
|
||||
//iteration über die ApproximationsGüten -- Zeilen
|
||||
for (int j=0;j<=result.get(0).size();j++){
|
||||
for (int j = 0; j <= result.get(0).size(); j++) {
|
||||
tableInput.add("eval-ds");
|
||||
if(j != result.get(0).size()) {
|
||||
if (j != result.get(0).size()) {
|
||||
|
||||
tableInput.add(names[type][j]);
|
||||
//iteration über die alg. -- Spalten
|
||||
|
@ -223,11 +224,11 @@ public class EvaluateAlgorithms extends Observable {
|
|||
|
||||
}
|
||||
|
||||
public void sendTableApproximationTypes(){
|
||||
public void sendTableApproximationTypes() {
|
||||
ArrayList<String> tableInput = new ArrayList<>();
|
||||
tableInput.add("eval-t");
|
||||
tableInput.add(""+0);
|
||||
for (int i=0;i<names[type].length;i++) {
|
||||
tableInput.add("" + 0);
|
||||
for (int i = 0; i < names[type].length; i++) {
|
||||
tableInput.add(names[type][i]);
|
||||
}
|
||||
tableInput.add("");
|
||||
|
@ -236,29 +237,29 @@ public class EvaluateAlgorithms extends Observable {
|
|||
tableInput.clear();
|
||||
}
|
||||
|
||||
public void sendPlotLineResults(Double[] res, int alg){
|
||||
public void sendPlotLineResults(Double[] res, int alg) {
|
||||
//visualisiere m,b
|
||||
|
||||
ArrayList<String> lines = new ArrayList<>();
|
||||
lines.add("lines-res");
|
||||
lines.add(""+alg);
|
||||
lines.add("" + alg);
|
||||
//lms res
|
||||
lines.add(res[0]+"");
|
||||
lines.add(res[1]+"");
|
||||
lines.add(res[0] + "");
|
||||
lines.add(res[1] + "");
|
||||
|
||||
setChanged();
|
||||
notifyObservers(lines.stream().toArray(String[]::new));
|
||||
}
|
||||
|
||||
public void sendPloteLineResults(ArrayList<Double[]> res, Integer[] algs){
|
||||
public void sendPloteLineResults(ArrayList<Double[]> res, Integer[] algs) {
|
||||
ArrayList<String> lines = new ArrayList<>();
|
||||
lines.add("lines-res-mult");
|
||||
for (int i=0;i<algs.length;i++){
|
||||
lines.add(""+algs[i]);
|
||||
for (int i = 0; i < algs.length; i++) {
|
||||
lines.add("" + algs[i]);
|
||||
//lms res
|
||||
Double[] tmp = res.get(i);
|
||||
lines.add(tmp[0]+"");
|
||||
lines.add(tmp[1]+"");
|
||||
lines.add(tmp[0] + "");
|
||||
lines.add(tmp[1] + "");
|
||||
}
|
||||
setChanged();
|
||||
notifyObservers(lines.stream().toArray(String[]::new));
|
||||
|
@ -322,7 +323,7 @@ public class EvaluateAlgorithms extends Observable {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public ArrayList<String> getScaledErrorBasedMeasure(LinkedList<Line> lines, Double m, Double b){
|
||||
public ArrayList<String> getScaledErrorBasedMeasure(LinkedList<Line> lines, Double m, Double b) {
|
||||
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m, b);
|
||||
ArrayList<String> ret = new ArrayList<>();
|
||||
ret.add(scaledErrorBasedMeasure.mse().toString());
|
||||
|
@ -332,17 +333,17 @@ public class EvaluateAlgorithms extends Observable {
|
|||
return ret;
|
||||
}
|
||||
|
||||
private ArrayList<String> fillPseudoResults(){
|
||||
private ArrayList<String> fillPseudoResults() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
result.add(" ");
|
||||
result.add(" ");
|
||||
result.add(" ");
|
||||
result.add(" ");
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public LinkedList<Line> getData(){
|
||||
public LinkedList<Line> getData() {
|
||||
return arrangement.getLines();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package presenter.evaluation;
|
||||
|
||||
import model.Line;
|
||||
import presenter.algorithms.FastElementSelector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 07.09.2017.
|
||||
*/
|
||||
public class PercentageErrorBasedMeasure {
|
||||
|
||||
|
||||
private ArrayList<Double> percentageError;
|
||||
|
||||
public PercentageErrorBasedMeasure(final LinkedList<Line> lines, Double m, Double b) {
|
||||
|
||||
ArrayList<Double> sampson = new ArrayList<>();
|
||||
|
||||
for (Line line : lines) {
|
||||
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
|
||||
sampson.add(e);
|
||||
}
|
||||
|
||||
percentageError = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < sampson.size(); j++) {
|
||||
percentageError.add(100 * sampson.get(j) / lines.get(j).getB());
|
||||
}
|
||||
}
|
||||
|
||||
/* Percentege Error Approximation Measures */
|
||||
//verschiedene Eingaben für einen Alg.
|
||||
public Double mape() {
|
||||
double error = 0;
|
||||
|
||||
for (Double d : percentageError) {
|
||||
error += Math.abs(d);
|
||||
}
|
||||
|
||||
error /= percentageError.size();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double mdape() {
|
||||
|
||||
ArrayList<Double> abs = new ArrayList<>();
|
||||
|
||||
for (Double d : percentageError) {
|
||||
abs.add(Math.abs(d));
|
||||
}
|
||||
|
||||
return FastElementSelector.randomizedSelect(abs, abs.size() * 0.5);
|
||||
}
|
||||
|
||||
public Double rmspe() {
|
||||
double error = 0;
|
||||
|
||||
for (Double d : percentageError) {
|
||||
error += Math.pow(d, 2);
|
||||
}
|
||||
|
||||
error /= percentageError.size();
|
||||
|
||||
return Math.sqrt(error);
|
||||
}
|
||||
|
||||
public Double rmdspe() {
|
||||
ArrayList squares = new ArrayList();
|
||||
for (Double d : percentageError) {
|
||||
squares.add(Math.pow(d, 2));
|
||||
}
|
||||
|
||||
return Math.sqrt(FastElementSelector.randomizedSelect(squares, squares.size() * 0.5));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package presenter.evaluation;
|
||||
|
||||
import model.Line;
|
||||
import presenter.algorithms.FastElementSelector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 07.09.2017.
|
||||
*/
|
||||
public class ScaleDependentMeasure {
|
||||
|
||||
private ArrayList<Double> errorValues;
|
||||
|
||||
public ScaleDependentMeasure(final LinkedList<Line> lines, Double m, Double b) {
|
||||
//Liste mit den Fehler zu jedem Punkt
|
||||
errorValues = new ArrayList<>();
|
||||
|
||||
for (Line line : lines) {
|
||||
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
|
||||
errorValues.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skalierungs Abhängige Approximationsgüten */
|
||||
//unterschiedliche Alg.- auf einem Datensatz
|
||||
public Double mse() {
|
||||
double error = 0;
|
||||
|
||||
for (Double d : errorValues) {
|
||||
error += Math.pow(d, 2);
|
||||
}
|
||||
|
||||
error /= errorValues.size();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double rmse() {
|
||||
return Math.sqrt(mse());
|
||||
}
|
||||
|
||||
public Double mae() {
|
||||
double error = 0;
|
||||
for (Double d : errorValues) {
|
||||
error += Math.abs(d);
|
||||
}
|
||||
error /= errorValues.size();
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double mdae() {
|
||||
return FastElementSelector
|
||||
.randomizedSelect(errorValues, errorValues.size() * 0.5);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package presenter.evaluation;
|
||||
|
||||
import model.Line;
|
||||
import presenter.algorithms.FastElementSelector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 07.09.2017.
|
||||
*/
|
||||
public class ScaledErrorBasedMeasure {
|
||||
|
||||
|
||||
private ArrayList<Double> scaledError;
|
||||
|
||||
public ScaledErrorBasedMeasure(final LinkedList<Line> lines, Double m, Double b) {
|
||||
//Liste mit den Fehler zu jedem Punkt
|
||||
ArrayList<Double> sampson = new ArrayList<>();
|
||||
|
||||
|
||||
Double denum = 0d;
|
||||
for (int i = 2; i < lines.size(); i++) {
|
||||
denum += Math.abs(lines.get(i).getM() - lines.get(i - 1).getM());
|
||||
}
|
||||
denum *= 1 / (lines.size() - 1);
|
||||
|
||||
for (Line line : lines) {
|
||||
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
|
||||
sampson.add(e);
|
||||
|
||||
Double val = e / (denum);
|
||||
scaledError.add(val);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Skalierungs Abhängige Approximationsgüten */
|
||||
//unterschiedliche Alg.- auf einem Datensatz
|
||||
public Double mse() {
|
||||
double error = 0;
|
||||
for (Double d : scaledError) {
|
||||
error += Math.pow(d, 2);
|
||||
}
|
||||
error /= scaledError.size();
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double rmse() {
|
||||
return Math.sqrt(mse());
|
||||
}
|
||||
|
||||
public Double mae() {
|
||||
double error = 0;
|
||||
for (Double d : scaledError) {
|
||||
error += Math.abs(d);
|
||||
}
|
||||
error /= scaledError.size();
|
||||
return error;
|
||||
}
|
||||
|
||||
public Double mdae() {
|
||||
return FastElementSelector
|
||||
.randomizedSelect(scaledError, scaledError.size() * 0.5);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
package Presenter.Generator;
|
||||
package presenter.generator;
|
||||
|
||||
import Model.Line;
|
||||
import model.Line;
|
||||
|
||||
import Model.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Observable;
|
||||
|
@ -16,53 +14,53 @@ import java.util.Random;
|
|||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 01.08.2017.
|
||||
*/
|
||||
public class DatasetGenerator extends Observable{
|
||||
public class DatasetGenerator extends Observable {
|
||||
|
||||
private Double m;
|
||||
private Double b;
|
||||
private Random random;
|
||||
|
||||
public DatasetGenerator(Double m, Double b){
|
||||
public DatasetGenerator(Double m, Double b) {
|
||||
this.m = m;
|
||||
this.b = b;
|
||||
random = new Random();
|
||||
random.setSeed(9999);
|
||||
}
|
||||
|
||||
public DatasetGenerator(){
|
||||
public DatasetGenerator() {
|
||||
random = new Random();
|
||||
}
|
||||
|
||||
|
||||
public LinkedList<Line> generateDataCloud(int size){
|
||||
public LinkedList<Line> generateDataCloud(int size) {
|
||||
LinkedList<Line> lines = new LinkedList<>();
|
||||
m = 1 + random.nextDouble();
|
||||
b = random.nextDouble();
|
||||
|
||||
|
||||
for (int i=1;i<(size+1);i++){
|
||||
for (int i = 1; i < (size + 1); i++) {
|
||||
double y = (random.nextGaussian() * 100) % 100;
|
||||
double signal = m * i + b;
|
||||
signal *= -1;
|
||||
|
||||
Line line = new Line((double) i, signal - y);
|
||||
line.setId(i-1+"");
|
||||
line.setId(i - 1 + "");
|
||||
lines.add(line);
|
||||
}
|
||||
String[] ret = {"generator","Es wurden "+100+" Daten generiert mit den Parametern",
|
||||
"</br> <b>m</b> = "+m+"",
|
||||
"</br> <b>b</b> = "+b+""};
|
||||
String[] ret = {"generator", "Es wurden " + 100 + " Daten generiert mit den Parametern",
|
||||
"</br> <b>m</b> = " + m + "",
|
||||
"</br> <b>b</b> = " + b + ""};
|
||||
setChanged();
|
||||
notifyObservers(ret);
|
||||
return lines;
|
||||
}
|
||||
|
||||
public LinkedList<Line> generateDataLines(int size){
|
||||
public LinkedList<Line> generateDataLines(int size) {
|
||||
LinkedList<Line> lines = new LinkedList<>();
|
||||
return generateDataLines(lines, size);
|
||||
}
|
||||
|
||||
private LinkedList<Line> generateDataLines(LinkedList<Line> lines, int n){
|
||||
private LinkedList<Line> generateDataLines(LinkedList<Line> lines, int n) {
|
||||
m = 5d;
|
||||
b = 0d;
|
||||
|
||||
|
@ -72,28 +70,26 @@ public class DatasetGenerator extends Observable{
|
|||
|
||||
//speichere die Koordinaten in einer HashMap, damit keine Punkte
|
||||
//entstehen deren x-Koordinate zu sehr beieinander liegt.
|
||||
while (size < n){
|
||||
while (size < n) {
|
||||
double y = random.nextGaussian();
|
||||
double signal = m * y + b;
|
||||
signal *= -1;
|
||||
|
||||
if (!points.containsKey(y)){
|
||||
points.put(y,signal);
|
||||
if (!points.containsKey(y)) {
|
||||
points.put(y, signal);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = lines.size();
|
||||
for (Double d :points.keySet()) {
|
||||
for (Double d : points.keySet()) {
|
||||
Line line = new Line((double) d, points.get(d));
|
||||
line.setId(idx+"");
|
||||
line.setId(idx + "");
|
||||
lines.add(line);
|
||||
idx++;
|
||||
}
|
||||
|
||||
String[] ret = {"generator","Es wurden "+100+" Daten generiert mit den Parametern",
|
||||
"</br> <b>m</b> = "+m+"",
|
||||
"</br> <b>b</b> = "+b+""};
|
||||
String[] ret = {"generator", "Es wurden " + 100 + " Daten generiert mit den Parametern"};
|
||||
setChanged();
|
||||
notifyObservers(ret);
|
||||
return lines;
|
||||
|
@ -106,22 +102,21 @@ public class DatasetGenerator extends Observable{
|
|||
double from = 0;
|
||||
double to = Math.PI * 5;
|
||||
//obere Grenze für die neuen Punkte
|
||||
int n = size/2 + lines.size();
|
||||
int n = size / 2 + lines.size();
|
||||
|
||||
//calculate the distance between every two points
|
||||
double distance = (to - from) / ((double) n);
|
||||
|
||||
//create points
|
||||
double currentDistance= from;
|
||||
double currentDistance = from;
|
||||
//an die aktuelle Liste dranhängen
|
||||
for(int i=lines.size(); i < n; i++)
|
||||
{
|
||||
for (int i = lines.size(); i < n; i++) {
|
||||
double x = Math.cos(currentDistance);
|
||||
double y = Math.sin(currentDistance);
|
||||
|
||||
|
||||
Line line = new Line(x,y);
|
||||
line.setId(i+"");
|
||||
Line line = new Line(x, y);
|
||||
line.setId(i + "");
|
||||
lines.add(line);
|
||||
|
||||
//distance for the next iteration
|
||||
|
@ -129,7 +124,7 @@ public class DatasetGenerator extends Observable{
|
|||
}
|
||||
|
||||
|
||||
return generateDataLines(lines,size/2);
|
||||
return generateDataLines(lines, size / 2);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package Presenter.ImportExport;
|
||||
package presenter.io;
|
||||
|
||||
import Model.Line;
|
||||
import Model.LineModel;
|
||||
import model.Line;
|
||||
import model.LineModel;
|
||||
import com.opencsv.CSVWriter;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -16,24 +16,24 @@ import java.util.Observable;
|
|||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 03.08.2017.
|
||||
*/
|
||||
public class DataExporter extends Observable{
|
||||
public class DataExporter extends Observable {
|
||||
|
||||
private LineModel lineModel;
|
||||
private File file;
|
||||
|
||||
public DataExporter(LineModel model, File file){
|
||||
public DataExporter(LineModel model, File file) {
|
||||
this.file = file;
|
||||
this.lineModel = model;
|
||||
}
|
||||
|
||||
public void export(){
|
||||
public void export() {
|
||||
CSVWriter writer = null;
|
||||
|
||||
try {
|
||||
writer = new CSVWriter(new FileWriter(file), ',');
|
||||
// feed in your array (or convert your data to an array)
|
||||
String[] entries = new String[3];
|
||||
for (Line line : lineModel.getLines()){
|
||||
for (Line line : lineModel.getLines()) {
|
||||
entries[0] = line.getId();
|
||||
entries[1] = line.getM().toString();
|
||||
Double tmp = (-1) * line.getB();
|
||||
|
@ -41,7 +41,7 @@ public class DataExporter extends Observable{
|
|||
writer.writeNext(entries);
|
||||
}
|
||||
writer.close();
|
||||
String[] ret = {"export","Das aktuelle Modell wurde erfolgreich unter: "+file.getAbsolutePath()+" gespeichert."};
|
||||
String[] ret = {"export", "Das aktuelle Modell wurde erfolgreich unter: " + file.getAbsolutePath() + " gespeichert."};
|
||||
setChanged();
|
||||
notifyObservers(ret);
|
||||
} catch (IOException e) {
|
|
@ -0,0 +1,77 @@
|
|||
package presenter.io;
|
||||
|
||||
import model.Line;
|
||||
import model.LineModel;
|
||||
import presenter.Presenter;
|
||||
import com.opencsv.CSVReader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 21.06.2017.
|
||||
*/
|
||||
public class DataImporter extends Observable {
|
||||
|
||||
private File file;
|
||||
private CSVReader reader;
|
||||
private LineModel model;
|
||||
private Presenter presenter;
|
||||
|
||||
|
||||
public DataImporter(File file, Presenter presenter) {
|
||||
this.model = new LineModel();
|
||||
this.presenter = presenter;
|
||||
this.presenter.setModel(this.model);
|
||||
//System.out.println(this.model.getLines().size()+ " die Anzahl der aktuellen Lines.");
|
||||
|
||||
|
||||
this.file = file;
|
||||
try {
|
||||
|
||||
this.reader = new CSVReader(new FileReader(file));
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
List<String[]> lines = reader.readAll();
|
||||
int counter = 0;
|
||||
String[] result = {"import", lines.size() + "", ""};
|
||||
//System.out.println("+-------------------------------------------------------------------------------+");
|
||||
for (String[] nextLine : lines) {
|
||||
// nextLine[] is an array of values from the line
|
||||
Double x = Double.parseDouble(nextLine[1]);
|
||||
Double y = Double.parseDouble(nextLine[2]) * (-1);
|
||||
Line line = new Line(x, y);
|
||||
line.setId(counter + "");
|
||||
this.presenter.getModel().addLine(line);
|
||||
//System.out.format("|\t\t\t\t\t %-11d \t|\t\t\t\t\t %-11f \t|\t\t\t\t\t %-11f \t\t\t\t\t|\n", id,x,y);
|
||||
setChanged();
|
||||
counter++;
|
||||
result[2] = counter + "";
|
||||
Thread.sleep(10);
|
||||
notifyObservers(result);
|
||||
}
|
||||
|
||||
//System.out.println("+-------------------------------------------------------------------------------+");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package presenter.io;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 08.09.2017.
|
||||
*/
|
||||
public class EvalResultLatexExport {
|
||||
|
||||
private DefaultTableModel model;
|
||||
private File file;
|
||||
|
||||
public EvalResultLatexExport(DefaultTableModel model, File file) {
|
||||
this.model = model;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* e.g. Source: <url>https://en.wikibooks.org/wiki/LaTeX/Tables</url>
|
||||
* \begin{tabular}{l*{3}{c}}
|
||||
* Team & P & W & D & L & F & A & Pts \\\hline
|
||||
* Manchester United & 6 & 4 & 0 & 2 & 10 & 5 & 12 \\
|
||||
* Celtic & 6 & 3 & 0 & 3 & 8 & 9 & 9 \\
|
||||
* Benfica & 6 & 2 & 1 & 3 & 7 & 8 & 7 \\
|
||||
* FC Copenhagen & 6 & 2 & 1 & 3 & 5 & 8 & 7 \\
|
||||
* \end{tabular}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String createOutputData() {
|
||||
String split = "&";
|
||||
StringBuilder doc = new StringBuilder();
|
||||
doc.append("\\begin{tabular}{l|*{3}{r}}" + "\r\n");
|
||||
for (int i = 0; i < model.getColumnCount(); i++) {
|
||||
if (model.getValueAt(0, i).toString() != "" || model.getRowCount() > 5)
|
||||
doc.append("\\textsc{" + model.getColumnName(i) + "}" + split);
|
||||
}
|
||||
|
||||
doc.deleteCharAt(doc.lastIndexOf(split));
|
||||
doc.append("\\\\\\hline\\hline" + "\r\n");
|
||||
|
||||
for (int i = 0; i < model.getRowCount() - 1; i++) {
|
||||
for (int j = 0; j < model.getColumnCount(); j++) {
|
||||
if (model.getValueAt(i, j).toString() != "") {
|
||||
if (j == 0) {
|
||||
doc.append("\\textbf{" + model.getValueAt(i, j).toString() + "}" + split);
|
||||
} else {
|
||||
Double val = Double.parseDouble((String) model.getValueAt(i, j));
|
||||
doc.append(String.format("%.3f", val) + split);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (model.getValueAt(i, 0) != "") {
|
||||
doc.deleteCharAt(doc.lastIndexOf(split));
|
||||
}
|
||||
doc.append("\\\\" + "\r\n");
|
||||
}
|
||||
doc.append("\\end{tabular}");
|
||||
return doc.toString();
|
||||
}
|
||||
|
||||
public void writeFile() {
|
||||
FileWriter fileWriter = null;
|
||||
BufferedWriter bufferedWriter = null;
|
||||
try {
|
||||
fileWriter = new FileWriter(file);
|
||||
bufferedWriter = new BufferedWriter(fileWriter);
|
||||
bufferedWriter.write(createOutputData());
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JOptionPane.showMessageDialog(null, "Export war Erfolgreich!");
|
||||
});
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
bufferedWriter.close();
|
||||
fileWriter.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,547 @@
|
|||
package view;
|
||||
|
||||
|
||||
import model.Line;
|
||||
import presenter.AbstractPresenter;
|
||||
import presenter.Presenter;
|
||||
import view.listener.*;
|
||||
import view.panels.*;
|
||||
import view.panels.tabs.LMSPanel;
|
||||
import view.panels.tabs.RMPanel;
|
||||
import view.panels.tabs.TSPanel;
|
||||
import view.panels.tabs.TabPanel;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class MainFrame extends JFrame {
|
||||
|
||||
private AbstractPresenter presenter;
|
||||
private Boolean lmsIsComplete = false;
|
||||
private Boolean rmIsComplete = false;
|
||||
private Boolean tsIsComplete = false;
|
||||
|
||||
private JButton arrangementButton;
|
||||
private JButton importButton;
|
||||
private JButton generateButton;
|
||||
private JButton exportButton;
|
||||
|
||||
private InfoPanel output;
|
||||
private MenuBar menu;
|
||||
private JToolBar toolBar;
|
||||
private TabPanel lmsPanel;
|
||||
private TabPanel rmPanel;
|
||||
private TabPanel tsPanel;
|
||||
|
||||
private DualityPanel arrangement;
|
||||
private JDialog arrangementDialog;
|
||||
private PlotPanel plotLMS;
|
||||
private PlotPanel plotRM;
|
||||
private PlotPanel plotTS;
|
||||
private JDialog progressDialog;
|
||||
private JDialog evaluationDialog;
|
||||
|
||||
private Container progressContent;
|
||||
private JProgressBar progressBar;
|
||||
|
||||
|
||||
private JSplitPane splitpane;
|
||||
private JScrollPane scrollPane;
|
||||
private JTabbedPane tabbedPane;
|
||||
private EvaluationPanel evaluationPanel;
|
||||
|
||||
public MainFrame() {
|
||||
super();
|
||||
initializeComponents();
|
||||
setDimensions();
|
||||
setLayouts();
|
||||
setTitles();
|
||||
|
||||
addComponents();
|
||||
|
||||
setCloseOperations();
|
||||
setIcons();
|
||||
disableFunctionality();
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* visualisierungs methoden
|
||||
******************************************************************************************************************/
|
||||
|
||||
public void createDualityDialog() {
|
||||
arrangement = new DualityPanel();
|
||||
arrangementDialog = new JDialog();
|
||||
arrangementDialog.setTitle("Dualraum - Dialog");
|
||||
arrangementDialog.setMinimumSize(new Dimension(1024, 768));
|
||||
arrangementDialog.setPreferredSize(new Dimension(800, 800));
|
||||
arrangementDialog.setLocationRelativeTo(this);
|
||||
arrangementDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
arrangementButton.addActionListener(new DualityVisualizerListener((Presenter) getPresenter()));
|
||||
arrangement.clear();
|
||||
arrangement.setPrameters(getPresenter().getModel().getLines(),
|
||||
getPresenter().getModel().getNodes(),
|
||||
getPresenter().getModel().getxMinimum(),
|
||||
getPresenter().getModel().getxMaximum(),
|
||||
getPresenter().getModel().getyMinimum(),
|
||||
getPresenter().getModel().getyMaximum());
|
||||
arrangement.createArrangement();
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
arrangementDialog.add(arrangement);
|
||||
arrangementDialog.setLocationRelativeTo(this);
|
||||
arrangementDialog.revalidate();
|
||||
arrangementDialog.repaint();
|
||||
arrangementDialog.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void visualizeLMS(double m, double b) {
|
||||
plotLMS = new PlotPanel();
|
||||
lmsPanel.setPlotPanel(plotLMS);
|
||||
createPlot(m, b, plotLMS, lmsPanel, "LMS");
|
||||
}
|
||||
|
||||
public void visualizeRM(double m, double b) {
|
||||
plotRM = new PlotPanel();
|
||||
rmPanel.setPlotPanel(plotRM);
|
||||
createPlot(m, b, plotRM, rmPanel, "RM");
|
||||
}
|
||||
|
||||
public void visualizeTS(double m, double b) {
|
||||
plotTS = new PlotPanel();
|
||||
tsPanel.setPlotPanel(plotTS);
|
||||
createPlot(m, b, plotTS, tsPanel, "TS");
|
||||
}
|
||||
|
||||
public void createPlot(double m, double b, PlotPanel plot, JPanel panel, String name) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
plot.clear();
|
||||
plot.createPlot(getPresenter().getModel().getLines());
|
||||
plot.addLineToPlot(m, b, name);
|
||||
panel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void showImportProgress(Integer progress) {
|
||||
progressBar.setValue(progress);
|
||||
progressBar.setStringPainted(true);
|
||||
progressDialog.setVisible(true);
|
||||
}
|
||||
|
||||
public void showEvauluationDialog() {
|
||||
if (evaluationDialog == null) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
evaluationDialog = new JDialog();
|
||||
evaluationDialog.setTitle("evaluation");
|
||||
evaluationDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
evaluationDialog.setSize(new Dimension(1800, 800));
|
||||
evaluationDialog.setLocationRelativeTo(null);
|
||||
|
||||
evaluationPanel = new EvaluationPanel(this);
|
||||
evaluationDialog.setLocationRelativeTo(this);
|
||||
evaluationDialog.add(evaluationPanel);
|
||||
evaluationDialog.setVisible(true);
|
||||
});
|
||||
} else {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
evaluationDialog.setLocationRelativeTo(this);
|
||||
evaluationDialog.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void appendEvalResult(Object[] res, int col, boolean isApprCol) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] tmp = Arrays.asList(res).subList(2, res.length).toArray();
|
||||
if (isApprCol) {
|
||||
evaluationPanel.setCurrentRow(tmp.length);
|
||||
evaluationPanel.addColumn(tmp, col, true);
|
||||
} else {
|
||||
evaluationPanel.addColumn(tmp, col + 1, false);
|
||||
}
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void appendEvalResult(Object[] res) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] tmp = Arrays.asList(res).subList(1, res.length).toArray();
|
||||
evaluationPanel.addRow(tmp);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void drawLineResult(Object[] res, int alg) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] result = Arrays.asList(res).subList(2, res.length).toArray();
|
||||
evaluationPanel.drawLines(result, alg);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void drawLineResults(Object[] res) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] result = Arrays.asList(res).subList(1, res.length).toArray();
|
||||
ArrayList<Double[]> algs = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < (result.length + 1) / 3; i++) {
|
||||
String name = (String) result[(3 * i)];
|
||||
String m = (String) result[(3 * i) + 1];
|
||||
String b = (String) result[(3 * i) + 2];
|
||||
Double[] tmp = {Double.parseDouble(name), Double.parseDouble(m), Double.parseDouble(b)};
|
||||
algs.add(tmp);
|
||||
}
|
||||
|
||||
evaluationPanel.drawLines(algs);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
public void addEvalDataset(LinkedList<Line> lines) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
evaluationPanel.setDualPoints(lines);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* init GUI
|
||||
******************************************************************************************************************/
|
||||
private void setTitles() {
|
||||
this.setTitle("Algorithmen zur Berechnung von Ausgleichgeraden");
|
||||
importButton.setText("Import");
|
||||
exportButton.setText("Export");
|
||||
generateButton.setText("Generiere");
|
||||
arrangementButton.setText("Dualraum");
|
||||
}
|
||||
|
||||
private void setupTabbedPane() {
|
||||
tabbedPane.add("Least Median of Squares", lmsPanel);
|
||||
tabbedPane.add("Repeated Median", rmPanel);
|
||||
tabbedPane.add("Theil-Sen", tsPanel);
|
||||
}
|
||||
|
||||
private void addComponents() {
|
||||
toolBar.add(arrangementButton);
|
||||
toolBar.add(importButton);
|
||||
toolBar.add(exportButton);
|
||||
toolBar.add(generateButton);
|
||||
toolBar.setFloatable(false);
|
||||
|
||||
setJMenuBar(menu.getMenuBar());
|
||||
add(toolBar);
|
||||
//northPanel.add(toolBar);
|
||||
|
||||
setupSplitPane();
|
||||
setupTabbedPane();
|
||||
|
||||
progressContent.add(progressBar, BorderLayout.CENTER);
|
||||
progressBar.setBorder(BorderFactory.createTitledBorder("Import..."));
|
||||
progressDialog.setLocationRelativeTo(null);
|
||||
((JPanel) progressDialog.getContentPane()).setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
|
||||
|
||||
this.add(toolBar, BorderLayout.NORTH);
|
||||
this.add(splitpane, BorderLayout.CENTER);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
progressDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
}
|
||||
|
||||
private void setDimensions() {
|
||||
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
|
||||
this.setMinimumSize(new Dimension(1024,768));
|
||||
this.setResizable(true);
|
||||
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
this.setMaximizedBounds(env.getMaximumWindowBounds());
|
||||
lmsPanel.setMinimumSize(new Dimension(400, 500));
|
||||
rmPanel.setMinimumSize(new Dimension(400, 500));
|
||||
tsPanel.setMinimumSize(new Dimension(400, 500));
|
||||
output.setMinimumSize(new Dimension(400, 500));
|
||||
progressDialog.setSize(300, 45);
|
||||
progressDialog.setResizable(false);
|
||||
progressDialog.setUndecorated(true);
|
||||
}
|
||||
|
||||
private void setLayouts() {
|
||||
this.setLayout(new BorderLayout());
|
||||
toolBar.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
}
|
||||
|
||||
private void initializeComponents() {
|
||||
//panels
|
||||
toolBar = new JToolBar();
|
||||
lmsPanel = new LMSPanel();
|
||||
rmPanel = new RMPanel();
|
||||
tsPanel = new TSPanel();
|
||||
menu = new MenuBar(this);
|
||||
|
||||
//Dialogs
|
||||
progressDialog = new JDialog();
|
||||
progressDialog.setLocationRelativeTo(null);
|
||||
progressContent = progressDialog.getContentPane();
|
||||
progressBar = new JProgressBar();
|
||||
|
||||
//Panes
|
||||
tabbedPane = new JTabbedPane();
|
||||
output = new InfoPanel();
|
||||
splitpane = new JSplitPane();
|
||||
|
||||
//Buttons
|
||||
arrangementButton = new JButton();
|
||||
importButton = new JButton();
|
||||
generateButton = new JButton();
|
||||
exportButton = new JButton();
|
||||
}
|
||||
|
||||
private void setIcons() {
|
||||
try {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
Image imgImport = ImageIO.read(classLoader.getResource("import.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
|
||||
Image imgPlot = ImageIO.read(classLoader.getResource("plot.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
|
||||
Image imgStart = ImageIO.read(classLoader.getResource("start.png")).getScaledInstance(32, 32, Image.SCALE_SMOOTH);
|
||||
Image imgGenerate = ImageIO.read(classLoader.getResource("generate.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
|
||||
Image imgExport = ImageIO.read(classLoader.getResource("export.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
|
||||
Image imgFrame = ImageIO.read(classLoader.getResource("frame.png")).getScaledInstance(32, 23, Image.SCALE_SMOOTH);
|
||||
|
||||
|
||||
importButton.setIcon(new ImageIcon(imgImport));
|
||||
exportButton.setIcon(new ImageIcon(imgExport));
|
||||
generateButton.setIcon(new ImageIcon(imgGenerate));
|
||||
arrangementButton.setIcon(new ImageIcon(imgPlot));
|
||||
lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
|
||||
rmPanel.getStartButton().setIcon(new ImageIcon(imgStart));
|
||||
tsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
|
||||
this.setIconImage(imgFrame);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setActionListeners() {
|
||||
|
||||
//action listener für MenuItems
|
||||
menu.addActionListeners();
|
||||
|
||||
//action listener für diese Klasse
|
||||
arrangementButton.addActionListener(new DualityVisualizerListener((Presenter) getPresenter()));
|
||||
lmsPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), lmsPanel));
|
||||
rmPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), rmPanel));
|
||||
tsPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), tsPanel));
|
||||
importButton.addActionListener(new ImportDataListener((Presenter) this.getPresenter() , this));
|
||||
exportButton.addActionListener(new ExportDataListener((Presenter) this.getPresenter() , this));
|
||||
generateButton.addActionListener(new GenerateDataListener((Presenter) this.getPresenter()));
|
||||
|
||||
}
|
||||
|
||||
public void enableFunctionality() {
|
||||
this.getLmsPanel().getStartButton().setEnabled(true);
|
||||
this.getRmPanel().getStartButton().setEnabled(true);
|
||||
this.getTsPanel().getStartButton().setEnabled(true);
|
||||
this.getArrangementButton().setEnabled(true);
|
||||
this.getExportButton().setEnabled(true);
|
||||
}
|
||||
|
||||
public void disableFunctionality() {
|
||||
this.getLmsPanel().getStartButton().setEnabled(false);
|
||||
this.getRmPanel().getStartButton().setEnabled(false);
|
||||
this.getTsPanel().getStartButton().setEnabled(false);
|
||||
this.getArrangementButton().setEnabled(false);
|
||||
this.getExportButton().setEnabled(false);
|
||||
}
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* log Methode
|
||||
******************************************************************************************************************/
|
||||
public void log(String s) {
|
||||
SwingUtilities.invokeLater(() -> output.appendParagraph(s));
|
||||
}
|
||||
|
||||
public void logError(String s) {
|
||||
SwingUtilities.invokeLater(() -> output.appendParagraphRed(s));
|
||||
}
|
||||
|
||||
public void logSuccess(String s) {
|
||||
SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s));
|
||||
}
|
||||
|
||||
public void logHeading(String s) {
|
||||
SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s));
|
||||
}
|
||||
|
||||
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 getImportButton() {
|
||||
return importButton;
|
||||
}
|
||||
|
||||
public void setImportButton(JButton importButton) {
|
||||
this.importButton = importButton;
|
||||
}
|
||||
|
||||
public JToolBar getToolBar() {
|
||||
return toolBar;
|
||||
}
|
||||
|
||||
public void setToolBar(JToolBar toolBar) {
|
||||
this.toolBar = toolBar;
|
||||
}
|
||||
|
||||
public JDialog getArrangementDialog() {
|
||||
return arrangementDialog;
|
||||
}
|
||||
|
||||
public void setArrangementDialog(JDialog arrangementDialog) {
|
||||
this.arrangementDialog = arrangementDialog;
|
||||
}
|
||||
|
||||
public InfoPanel getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
public void setOutput(InfoPanel output) {
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public MenuBar getMenu() {
|
||||
return menu;
|
||||
}
|
||||
|
||||
public TabPanel getLmsPanel() {
|
||||
return lmsPanel;
|
||||
}
|
||||
|
||||
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 TabPanel getRmPanel() {
|
||||
return rmPanel;
|
||||
}
|
||||
|
||||
public void setRmPanel(TabPanel rmPanel) {
|
||||
this.rmPanel = rmPanel;
|
||||
}
|
||||
|
||||
public PlotPanel getPlotLMS() {
|
||||
return plotLMS;
|
||||
}
|
||||
|
||||
public void setPlotLMS(PlotPanel plotLMS) {
|
||||
this.plotLMS = plotLMS;
|
||||
}
|
||||
|
||||
public AbstractPresenter getPresenter() {
|
||||
return presenter;
|
||||
}
|
||||
|
||||
public void setPresenter(AbstractPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public JDialog getProgressDialog() {
|
||||
return progressDialog;
|
||||
}
|
||||
|
||||
public void setProgressDialog(JDialog progressDialog) {
|
||||
this.progressDialog = progressDialog;
|
||||
}
|
||||
|
||||
public TabPanel getTsPanel() {
|
||||
return tsPanel;
|
||||
}
|
||||
|
||||
public void setTsPanel(TabPanel tsPanel) {
|
||||
this.tsPanel = tsPanel;
|
||||
}
|
||||
|
||||
public JButton getExportButton() {
|
||||
return exportButton;
|
||||
}
|
||||
|
||||
public void setExportButton(JButton exportButton) {
|
||||
this.exportButton = exportButton;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package view;
|
||||
|
||||
import presenter.Presenter;
|
||||
import view.MainFrame;
|
||||
import view.listener.ExportDataListener;
|
||||
import view.listener.GenerateDataListener;
|
||||
import view.listener.ImportDataListener;
|
||||
import view.panels.AboutPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 29.05.2017.
|
||||
*/
|
||||
public class MenuBar {
|
||||
|
||||
private MainFrame view;
|
||||
|
||||
private JMenuBar menuBar;
|
||||
private JMenu fileMenu;
|
||||
private JMenu toolsMenu;
|
||||
private JMenu aboutMenu;
|
||||
|
||||
private JMenuItem exitItem;
|
||||
private JMenuItem importItem;
|
||||
private JMenuItem exportItem;
|
||||
private JMenuItem generateItem;
|
||||
private JMenuItem evaluateItem;
|
||||
private JMenuItem aboutItem;
|
||||
|
||||
public MenuBar(MainFrame view) {
|
||||
this.menuBar = new JMenuBar();
|
||||
this.view = view;
|
||||
this.fileMenu = new JMenu("Datei");
|
||||
this.toolsMenu = new JMenu("Extras");
|
||||
this.aboutMenu = new JMenu("Info");
|
||||
|
||||
|
||||
this.exitItem = new JMenuItem("Exit");
|
||||
this.importItem = new JMenuItem("Import");
|
||||
this.exportItem = new JMenuItem("Export");
|
||||
this.generateItem = new JMenuItem("Generiere...");
|
||||
this.aboutItem = new JMenuItem("Über das Programm");
|
||||
|
||||
this.evaluateItem = new JMenuItem("Evaluation");
|
||||
|
||||
|
||||
fileMenu.add(exitItem);
|
||||
fileMenu.add(importItem);
|
||||
fileMenu.add(exportItem);
|
||||
|
||||
toolsMenu.add(generateItem);
|
||||
toolsMenu.add(evaluateItem);
|
||||
|
||||
aboutMenu.add(aboutItem);
|
||||
|
||||
menuBar.add(fileMenu);
|
||||
menuBar.add(toolsMenu);
|
||||
menuBar.add(aboutMenu);
|
||||
}
|
||||
|
||||
public void addActionListeners(){
|
||||
this.exitItem.addActionListener(e -> {System.exit(0);});
|
||||
this.evaluateItem.addActionListener(e -> {view.showEvauluationDialog();});
|
||||
this.importItem.addActionListener(new ImportDataListener((Presenter) view.getPresenter(), view));
|
||||
this.exportItem.addActionListener(new ExportDataListener((Presenter) view.getPresenter(), view));
|
||||
this.generateItem.addActionListener(new GenerateDataListener((Presenter) view.getPresenter()));
|
||||
this.aboutItem.addActionListener(e -> {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JDialog dialog = new JDialog();
|
||||
dialog.setSize(410,420);
|
||||
dialog.setResizable(false);
|
||||
dialog.add(new AboutPanel());
|
||||
dialog.setVisible(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public JMenuBar getMenuBar() {
|
||||
return menuBar;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package view.custom;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Source: <url>https://stackoverflow.com/questions/14892515/how-to-enforce-at-least-one-checkbox-in-a-group-is-selected</url>
|
||||
* <p>
|
||||
* A ButtonGroup for check-boxes enforcing that at least two remains selected.
|
||||
* <p>
|
||||
* When the group has exactly two buttons, deselecting the last selected one
|
||||
* automatically selects the other.
|
||||
* <p>
|
||||
* When the group has more buttons, deselection of the last selected one is denied.
|
||||
*/
|
||||
public class ButtonGroupAtLeastTwo extends ButtonGroup {
|
||||
|
||||
private final Set<ButtonModel> selected = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void setSelected(ButtonModel model, boolean b) {
|
||||
if (b && !this.selected.contains(model)) {
|
||||
select(model, true);
|
||||
} else if (!b && this.selected.contains(model)) {
|
||||
if (this.buttons.size() == 3 && this.selected.size() == 2) {
|
||||
select(model, false);
|
||||
|
||||
AbstractButton otherOne = this.buttons.get(0).getModel() == model ?
|
||||
this.buttons.get(1) : this.buttons.get(0);
|
||||
|
||||
AbstractButton otherTwo = this.buttons.get(1).getModel() == model ?
|
||||
this.buttons.get(2) : this.buttons.get(1);
|
||||
|
||||
AbstractButton otherThree = this.buttons.get(2).getModel() == model ?
|
||||
this.buttons.get(1) : this.buttons.get(2);
|
||||
|
||||
|
||||
select(otherOne.getModel(), true);
|
||||
select(otherTwo.getModel(), true);
|
||||
select(otherThree.getModel(), true);
|
||||
} else if (this.selected.size() > 2) {
|
||||
this.selected.remove(model);
|
||||
model.setSelected(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void select(ButtonModel model, boolean b) {
|
||||
if (b) {
|
||||
this.selected.add(model);
|
||||
} else {
|
||||
this.selected.remove(model);
|
||||
}
|
||||
model.setSelected(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(ButtonModel m) {
|
||||
return this.selected.contains(m);
|
||||
}
|
||||
|
||||
public void addAll(AbstractButton... buttons) {
|
||||
for (AbstractButton button : buttons) {
|
||||
add(button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(AbstractButton button) {
|
||||
if (button.isSelected()) {
|
||||
this.selected.add(button.getModel());
|
||||
}
|
||||
super.add(button);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package view.custom;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Source: <url> http://esus.com/creating-a-jtable-with-a-different-background-color-per-column/ </url>
|
||||
* <p>
|
||||
* Applied background and foreground color to single column of a JTable
|
||||
* in order to distinguish it apart from other columns.
|
||||
*/
|
||||
public class ColorColumnRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
Color bkgndColor, fgndColor;
|
||||
|
||||
public ColorColumnRenderer(Color bkgnd, Color foregnd) {
|
||||
super();
|
||||
bkgndColor = bkgnd;
|
||||
fgndColor = foregnd;
|
||||
}
|
||||
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
|
||||
boolean hasFocus, int row, int column) {
|
||||
Component cell = super.getTableCellRendererComponent
|
||||
(table, value, isSelected, hasFocus, row, column);
|
||||
|
||||
cell.setBackground(bkgndColor);
|
||||
cell.setForeground(fgndColor);
|
||||
cell.setFont(new Font("SansSerif", Font.BOLD, 12));
|
||||
this.setHorizontalAlignment(JLabel.CENTER);
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package view.listener;
|
||||
|
||||
import presenter.Presenter;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 10.09.2017.
|
||||
*/
|
||||
public class DualityVisualizerListener implements ActionListener {
|
||||
|
||||
private Presenter presenter;
|
||||
|
||||
public DualityVisualizerListener(Presenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
presenter.visualizeDualLines();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package view.listener;
|
||||
|
||||
import presenter.Presenter;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 10.09.2017.
|
||||
*/
|
||||
public class ExportDataListener implements ActionListener {
|
||||
|
||||
private Presenter presenter;
|
||||
private Container component;
|
||||
|
||||
public ExportDataListener(Presenter presenter, Container component) {
|
||||
this.presenter = presenter;
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
File file = null;
|
||||
JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
|
||||
chooser.setPreferredSize(new Dimension(800, 700));
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Value", "csv", "text"));
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
|
||||
|
||||
if (chooser.showSaveDialog(component) == JFileChooser.APPROVE_OPTION) {
|
||||
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
|
||||
file = chooser.getSelectedFile();
|
||||
String filename = file.getAbsolutePath().contains(".csv") ? file.getAbsolutePath() : file.getAbsolutePath().concat(".csv");
|
||||
File withExtension = new File(filename);
|
||||
final File input = withExtension;
|
||||
Thread t = new Thread(() -> presenter.startExport(input));
|
||||
t.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package view.listener;
|
||||
|
||||
import presenter.Presenter;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 10.09.2017.
|
||||
*/
|
||||
public class GenerateDataListener implements ActionListener {
|
||||
|
||||
private Presenter presenter;
|
||||
|
||||
public GenerateDataListener(Presenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Thread t = new Thread(() -> presenter.generateDataset());
|
||||
t.start();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package view.listener;
|
||||
|
||||
import presenter.Presenter;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 10.09.2017.
|
||||
*/
|
||||
public class ImportDataListener implements ActionListener {
|
||||
|
||||
private Presenter presenter;
|
||||
private Container component;
|
||||
|
||||
public ImportDataListener(Presenter presenter, Container component) {
|
||||
this.presenter = presenter;
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
File file = null;
|
||||
JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
|
||||
chooser.setPreferredSize(new Dimension(800, 700));
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Value", "csv", "text"));
|
||||
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
|
||||
|
||||
if (chooser.showOpenDialog(component) == JFileChooser.APPROVE_OPTION) {
|
||||
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
|
||||
file = chooser.getSelectedFile();
|
||||
final File input = file;
|
||||
Thread t = new Thread(() -> presenter.startImport(input));
|
||||
t.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package view.listener;
|
||||
|
||||
import presenter.Presenter;
|
||||
import presenter.algorithms.Algorithm;
|
||||
import presenter.algorithms.LeastMedianOfSquaresEstimator;
|
||||
import view.panels.tabs.LMSPanel;
|
||||
import view.panels.tabs.RMPanel;
|
||||
import view.panels.tabs.TSPanel;
|
||||
import view.panels.tabs.TabPanel;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 10.09.2017.
|
||||
*/
|
||||
public class StartAlgorithmListener implements ActionListener {
|
||||
|
||||
private Presenter presenter;
|
||||
private TabPanel tabPanel;
|
||||
|
||||
public StartAlgorithmListener(Presenter presenter, TabPanel tabPanel) {
|
||||
this.presenter = presenter;
|
||||
this.tabPanel = tabPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (tabPanel instanceof LMSPanel){
|
||||
if ( ((LMSPanel) tabPanel).getInput() != null) {
|
||||
Thread t = new Thread(
|
||||
() -> presenter.calculateLMS(((LMSPanel) tabPanel).getInput()));
|
||||
t.start();
|
||||
}
|
||||
} else if (tabPanel instanceof RMPanel){
|
||||
if ( ((RMPanel) tabPanel).getInput() != null) {
|
||||
Thread t = new Thread(
|
||||
() -> presenter.calculateRM(((RMPanel) tabPanel).getInput()));
|
||||
t.start();
|
||||
}
|
||||
} else if(tabPanel instanceof TSPanel){
|
||||
Thread t = new Thread(
|
||||
() -> presenter.calculateTS(""));
|
||||
t.start();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Algortihm representation Panel!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package view.panels;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 10.09.2017.
|
||||
*/
|
||||
public class AboutPanel extends JPanel {
|
||||
|
||||
private JTextArea textArea;
|
||||
private JLabel imageContainer;
|
||||
private JPanel contentPane;
|
||||
private ImageIcon image;
|
||||
|
||||
public AboutPanel(){
|
||||
super();
|
||||
this.setSize(new Dimension(410,400));
|
||||
this.setLayout(new BorderLayout());
|
||||
contentPane = new JPanel(new BorderLayout());
|
||||
this.textArea = new JTextArea();
|
||||
this.textArea.setEditable(false);
|
||||
this.textArea.setBackground(new Color(0,0,0,0));
|
||||
contentPane.add(this.textArea, BorderLayout.CENTER);
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
try {
|
||||
image = new ImageIcon(ImageIO.read(classLoader.getResource("wwu.png")).getScaledInstance(300, 87, Image.SCALE_SMOOTH));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.imageContainer = new JLabel(image);
|
||||
contentPane.add(imageContainer, BorderLayout.NORTH);
|
||||
this.add(new JPanel(), BorderLayout.NORTH);
|
||||
this.add(contentPane, BorderLayout.CENTER);
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,233 @@
|
|||
package view.panels;
|
||||
|
||||
import model.Line;
|
||||
import model.Point;
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.axis.ValueAxis;
|
||||
import org.jfree.chart.plot.PlotOrientation;
|
||||
import org.jfree.chart.plot.XYPlot;
|
||||
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
|
||||
import org.jfree.data.time.DateRange;
|
||||
import org.jfree.data.xy.XYSeries;
|
||||
import org.jfree.data.xy.XYSeriesCollection;
|
||||
import org.jfree.util.ShapeUtilities;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public class DualityPanel extends JPanel {
|
||||
|
||||
private LinkedList<Line> lines;
|
||||
private LinkedList<Point> points;
|
||||
private JFreeChart chart;
|
||||
private ChartPanel panel;
|
||||
private XYSeriesCollection dataset;
|
||||
private JScrollPane scrollPane;
|
||||
private double domainMin, domainMax;
|
||||
private double rangeMin, rangeMax;
|
||||
private ValueAxis domain;
|
||||
private ValueAxis range;
|
||||
private Double delta = 1d;
|
||||
|
||||
|
||||
private Boolean ctrlPressed = false;
|
||||
private Boolean shiftPressed = false;
|
||||
|
||||
public DualityPanel() {
|
||||
super();
|
||||
this.setPreferredSize(new Dimension(800, 800));
|
||||
this.setMinimumSize(new Dimension(800, 800));
|
||||
this.setLayout(new BorderLayout());
|
||||
}
|
||||
|
||||
public void setPrameters(LinkedList<Line> lines, LinkedList<Point> points, Double xmin, Double xmax, Double ymin, Double ymax) {
|
||||
this.lines = new LinkedList<>(lines);
|
||||
this.points = new LinkedList<>(points);
|
||||
this.domainMin = xmin;
|
||||
this.domainMax = xmax;
|
||||
this.rangeMin = ymin;
|
||||
this.rangeMax = ymax;
|
||||
}
|
||||
|
||||
public void createArrangement() {
|
||||
dataset = new XYSeriesCollection();
|
||||
|
||||
for (Line p : lines) {
|
||||
XYSeries series = new XYSeries(p.getId() + "#" + p.getX1() + "---" + p.getY1());
|
||||
series.add(p.getX1(), p.getY1());
|
||||
series.add(p.getX2(), p.getY2());
|
||||
dataset.addSeries(series);
|
||||
}
|
||||
|
||||
XYSeries intersections = new XYSeries("intersections");
|
||||
for (Point p : points) {
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
addKeyListener(this);
|
||||
addZooming(panel);
|
||||
this.setFocusable(true);
|
||||
|
||||
JTextArea info = new JTextArea();
|
||||
info.setText("Um in dem Plot hineinzuzoomen kann das Mausrad verwendett werden. \nUm sich anschließen vertikal bzw. horizontal zu bewegen kann die Kombination (Umschalt/Steuerung)\nund Mausrad verwendett werden.");
|
||||
Font font = new Font("Serif", Font.ITALIC, 12);
|
||||
info.setFont(font);
|
||||
info.setForeground(Color.DARK_GRAY);
|
||||
info.setEditable(false);
|
||||
info.setWrapStyleWord(true);
|
||||
|
||||
this.add(info, BorderLayout.SOUTH);
|
||||
this.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void addKeyListener(JComponent component) {
|
||||
component.addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
ctrlPressed = false;
|
||||
shiftPressed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.isControlDown()) {
|
||||
ctrlPressed = true;
|
||||
}
|
||||
|
||||
if (e.isShiftDown()) {
|
||||
shiftPressed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void addZooming(ChartPanel chartPanel) {
|
||||
|
||||
chartPanel.addMouseWheelListener(new MouseWheelListener() {
|
||||
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
|
||||
Double min;
|
||||
Double max;
|
||||
Double val = e.getPreciseWheelRotation() * -1;
|
||||
|
||||
if (ctrlPressed == true) {
|
||||
//System.out.println("CTRL + ZOOM");
|
||||
min = range.getLowerBound();
|
||||
max = range.getUpperBound();
|
||||
DateRange dateRangeX = move(val, min, max);
|
||||
range.setRange(dateRangeX);
|
||||
} else if (shiftPressed == true) {
|
||||
//System.out.println("SHIFT + ZOOM");
|
||||
min = domain.getLowerBound();
|
||||
max = domain.getUpperBound();
|
||||
DateRange dateRangeY = move(val, min, max);
|
||||
domain.setRange(dateRangeY);
|
||||
} else {
|
||||
Double x = Double.valueOf(e.getY());
|
||||
Double y = Double.valueOf(e.getY());
|
||||
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL)
|
||||
return;
|
||||
if (e.getWheelRotation() < 0)
|
||||
increaseZoom((ChartPanel) e.getComponent(), true, x, y);
|
||||
else
|
||||
decreaseZoom((ChartPanel) e.getComponent(), true, x, y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private DateRange move(Double val, Double min, Double max) {
|
||||
Double minimum = min;
|
||||
Double maximum = max;
|
||||
delta = Math.abs(maximum - minimum) * 0.01 * val;
|
||||
|
||||
minimum = minimum + delta;
|
||||
maximum = maximum + delta;
|
||||
|
||||
return new DateRange(minimum, maximum);
|
||||
}
|
||||
|
||||
public synchronized void increaseZoom(JComponent chart, boolean saveAction, Double x, Double y) {
|
||||
ChartPanel ch = (ChartPanel) chart;
|
||||
zoomChartAxis(ch, true, x, y);
|
||||
}
|
||||
|
||||
public synchronized void decreaseZoom(JComponent chart, boolean saveAction, Double x, Double y) {
|
||||
ChartPanel ch = (ChartPanel) chart;
|
||||
zoomChartAxis(ch, false, x, y);
|
||||
}
|
||||
|
||||
private void zoomChartAxis(ChartPanel chartP, boolean increase, Double x, Double y) {
|
||||
int width = chartP.getMaximumDrawWidth() - chartP.getMinimumDrawWidth();
|
||||
int height = chartP.getMaximumDrawHeight() - chartP.getMinimumDrawWidth();
|
||||
if (increase) {
|
||||
chartP.zoomInBoth(width / 2, height / 2);
|
||||
} else {
|
||||
chartP.zoomOutBoth(width / 2, height / 2);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (dataset != null)
|
||||
dataset.removeAllSeries();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,31 +1,30 @@
|
|||
package View.Panels;
|
||||
package view.panels;
|
||||
|
||||
import Model.Line;
|
||||
import View.MainFrame;
|
||||
import model.Line;
|
||||
import presenter.Presenter;
|
||||
import view.MainFrame;
|
||||
import view.custom.ButtonGroupAtLeastTwo;
|
||||
import view.custom.ColorColumnRenderer;
|
||||
|
||||
import View.PlotDialog;
|
||||
import View.custom.ButtonGroupAtLeastOne;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableColumn;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.LineBorder;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import java.awt.*;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import View.custom.ColorColumnRenderer;
|
||||
|
||||
/**
|
||||
* Created by
|
||||
* Armin Wolf
|
||||
* on 02.08.17.
|
||||
*/
|
||||
public class EvaluationPanel extends JPanel{
|
||||
public class EvaluationPanel extends JPanel {
|
||||
|
||||
private final MainFrame view;
|
||||
private JTable table;
|
||||
|
@ -38,11 +37,11 @@ public class EvaluationPanel extends JPanel{
|
|||
private JRadioButton evalTypeTwo; //N: Alg - 1: Data
|
||||
private ButtonGroup radiobuttonGroup;
|
||||
private ButtonGroup checkboxGroup;
|
||||
private ButtonGroupAtLeastOne checkboxAtLeastOne;
|
||||
private ButtonGroupAtLeastTwo checkboxAtLeastOne;
|
||||
|
||||
private JCheckBox lms; //1: Alg - N: Data
|
||||
private JCheckBox rm; //N: Alg - 1: Data
|
||||
private JCheckBox ts; //1: Alg - N: Data
|
||||
private JCheckBox lms; //1: Alg - N: Data
|
||||
private JCheckBox rm; //N: Alg - 1: Data
|
||||
private JCheckBox ts; //1: Alg - N: Data
|
||||
|
||||
private JPanel comp;
|
||||
private JPanel algorithmPanel;
|
||||
|
@ -57,10 +56,10 @@ public class EvaluationPanel extends JPanel{
|
|||
private DefaultTableModel model;
|
||||
private int currentRowOfTypes;
|
||||
private JPanel buttonPanel;
|
||||
private PlotDialog plotDialog;
|
||||
private String[] selections = { "Approximationsgüte","Least Median of Squares","Repeated-Median","Theil-Sen"};
|
||||
private PlotPanel plotPanel;
|
||||
private String[] selections = {"Approximationsgüte", "Least Median of Squares", "Repeated-Median", "Theil-Sen"};
|
||||
|
||||
public EvaluationPanel(MainFrame view){
|
||||
public EvaluationPanel(MainFrame view) {
|
||||
super();
|
||||
this.view = view;
|
||||
this.setLayout(new BorderLayout());
|
||||
|
@ -72,9 +71,9 @@ public class EvaluationPanel extends JPanel{
|
|||
|
||||
}
|
||||
|
||||
private void init(){
|
||||
datasetCountLabel = new JLabel("Größe des Datensatzes");
|
||||
Integer[] choice = {50,100,200,500,1000,1500};
|
||||
private void init() {
|
||||
datasetCountLabel = new JLabel("Größe des Datensatzes");
|
||||
Integer[] choice = {50, 100, 200, 500, 1000, 1500};
|
||||
datasetCountChoice = new JComboBox(choice);
|
||||
String[] datatypes = {"Punktwolke", "Gerade", "Kreis und Gerade"};
|
||||
datasetType = new JComboBox<>(datatypes);
|
||||
|
@ -88,17 +87,17 @@ public class EvaluationPanel extends JPanel{
|
|||
exportData.setEnabled(false);
|
||||
evalTypeOne = new JRadioButton("Algorithmus evaluieren");
|
||||
evalTypeTwo = new JRadioButton("Algorithmen vergleichen");
|
||||
lms = new JCheckBox ("Least Median of Squares");
|
||||
rm = new JCheckBox ("Repeated Median");
|
||||
ts = new JCheckBox ("Theil-Sen");
|
||||
lms = new JCheckBox("Least Median of Squares");
|
||||
rm = new JCheckBox("Repeated Median");
|
||||
ts = new JCheckBox("Theil-Sen");
|
||||
radiobuttonGroup = new ButtonGroup();
|
||||
checkboxGroup = new ButtonGroup();
|
||||
checkboxAtLeastOne = new ButtonGroupAtLeastOne();
|
||||
checkboxAtLeastOne = new ButtonGroupAtLeastTwo();
|
||||
buttonPanel = new JPanel(new FlowLayout());
|
||||
leftSidePanel = new JPanel(new BorderLayout());
|
||||
comp = new JPanel(new GridLayout(0,1));
|
||||
plotDialog = new PlotDialog();
|
||||
model = new DefaultTableModel(){
|
||||
comp = new JPanel(new GridLayout(0, 1));
|
||||
plotPanel = new PlotPanel();
|
||||
model = new DefaultTableModel() {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
//all cells false
|
||||
|
@ -117,7 +116,7 @@ public class EvaluationPanel extends JPanel{
|
|||
|
||||
}
|
||||
|
||||
private void addComponents(){
|
||||
private void addComponents() {
|
||||
evalTypeOne.setSelected(true);
|
||||
lms.setSelected(true);
|
||||
checkboxGroup.add(lms);
|
||||
|
@ -159,8 +158,8 @@ public class EvaluationPanel extends JPanel{
|
|||
|
||||
|
||||
//Plot
|
||||
plotDialog.createPlot(new LinkedList<>());
|
||||
plotDialog.setBorder(new TitledBorder("Plot"));
|
||||
plotPanel.createPlot(new LinkedList<>());
|
||||
plotPanel.setBorder(new TitledBorder("Plot"));
|
||||
|
||||
leftSidePanel.add(comp, BorderLayout.NORTH);
|
||||
leftSidePanel.add(scrollPane, BorderLayout.CENTER);
|
||||
|
@ -170,7 +169,7 @@ public class EvaluationPanel extends JPanel{
|
|||
splitPane.setResizeWeight(.5d);
|
||||
splitPane.setContinuousLayout(true);
|
||||
splitPane.setLeftComponent(leftSidePanel);
|
||||
splitPane.setRightComponent(plotDialog);
|
||||
splitPane.setRightComponent(plotPanel);
|
||||
|
||||
this.add(splitPane, BorderLayout.CENTER);
|
||||
|
||||
|
@ -180,12 +179,12 @@ public class EvaluationPanel extends JPanel{
|
|||
tm.setCellRenderer(new ColorColumnRenderer(Color.lightGray, Color.blue));
|
||||
}
|
||||
|
||||
private void addListener(){
|
||||
private void addListener() {
|
||||
start.addActionListener(e -> {
|
||||
int type;
|
||||
int alg;
|
||||
int n;
|
||||
if (radiobuttonGroup.isSelected(evalTypeOne.getModel())){
|
||||
if (radiobuttonGroup.isSelected(evalTypeOne.getModel())) {
|
||||
type = 0;
|
||||
} else {
|
||||
type = 1;
|
||||
|
@ -193,7 +192,7 @@ public class EvaluationPanel extends JPanel{
|
|||
alg = checkSelection();
|
||||
n = (Integer) datasetCountChoice.getSelectedItem();
|
||||
String datatyp = (String) datasetType.getSelectedItem();
|
||||
view.getPresenter().startEvaluation(type,n,alg,datatyp);
|
||||
((Presenter) view.getPresenter()).startEvaluation(type, n, alg, datatyp);
|
||||
clearTable.setEnabled(true);
|
||||
latexExport.setEnabled(true);
|
||||
exportData.setEnabled(true);
|
||||
|
@ -215,7 +214,7 @@ public class EvaluationPanel extends JPanel{
|
|||
checkboxGroup.remove(rm);
|
||||
checkboxGroup.remove(ts);
|
||||
|
||||
checkboxAtLeastOne.addAll(lms,rm,ts);
|
||||
checkboxAtLeastOne.addAll(lms, rm, ts);
|
||||
|
||||
lms.setSelected(true);
|
||||
rm.setSelected(true);
|
||||
|
@ -224,30 +223,28 @@ public class EvaluationPanel extends JPanel{
|
|||
latexExport.addActionListener(e -> {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
File file = null;
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setPreferredSize(new Dimension(800,700));
|
||||
File workingDirectory = new File(System.getProperty("user.dir"));
|
||||
chooser.setCurrentDirectory(workingDirectory);
|
||||
JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
|
||||
chooser.setPreferredSize(new Dimension(800, 700));
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("LaTeX-Datei", "tex", "text"));
|
||||
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
|
||||
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){
|
||||
if (chooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
|
||||
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
|
||||
file = chooser.getSelectedFile();
|
||||
String filename = file.getAbsolutePath().contains(".tex") ? file.getAbsolutePath() : file.getAbsolutePath().concat(".tex");
|
||||
File withExtension = new File(filename);
|
||||
final File input = withExtension;
|
||||
view.getPresenter().startResultExport(model, input);
|
||||
((Presenter) view.getPresenter()).startResultExport(model, input);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
clearTable.addActionListener(e -> {
|
||||
SwingUtilities.invokeLater(() ->{
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
int n = model.getDataVector().size();
|
||||
for (int i=0;i<n;i++){
|
||||
for (int i = 0; i < n; i++) {
|
||||
model.removeRow(0);
|
||||
currentRowOfTypes--;
|
||||
}
|
||||
|
@ -261,29 +258,29 @@ public class EvaluationPanel extends JPanel{
|
|||
|
||||
exportData.addActionListener(e -> {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JOptionPane.showMessageDialog(null, "Boooooooooooooooooooooooooooooooooooooooooooooooooooooo! :)");
|
||||
JOptionPane.showMessageDialog(this, "Boooooooooooooooooooooooooooooooooooooooooooooooooooooo! :)");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void addColumn(Object[] data, int col, boolean b){
|
||||
if (b){
|
||||
public void addColumn(Object[] data, int col, boolean b) {
|
||||
if (b) {
|
||||
addBlankRows(data.length);
|
||||
}
|
||||
for (int i=0;i<data.length;i++){
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
int row = currentRowOfTypes - data.length + i;
|
||||
model.setValueAt(data[i],row,col);
|
||||
model.setValueAt(data[i], row, col);
|
||||
}
|
||||
this.repaint();
|
||||
this.revalidate();
|
||||
}
|
||||
|
||||
public void addRow(Object[] data){
|
||||
public void addRow(Object[] data) {
|
||||
addBlankRows(1);
|
||||
for (int i=0;i<4;i++){
|
||||
model.setValueAt(data[i],currentRowOfTypes,i);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
model.setValueAt(data[i], currentRowOfTypes, i);
|
||||
}
|
||||
|
||||
currentRowOfTypes++;
|
||||
|
@ -291,63 +288,63 @@ public class EvaluationPanel extends JPanel{
|
|||
this.revalidate();
|
||||
}
|
||||
|
||||
public void drawLines(ArrayList<Double[]> alg){
|
||||
public void drawLines(ArrayList<Double[]> alg) {
|
||||
Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA};
|
||||
String[] name = {"LMS","RM", "TS"};
|
||||
String[] name = {"LMS", "RM", "TS"};
|
||||
|
||||
for (Double[] o : alg){
|
||||
Double m = o[1];
|
||||
Double b = o[1];
|
||||
int i = o[0].intValue();
|
||||
plotDialog.addLineToPlot(m,b,color[i],name[i]);
|
||||
for (Double[] o : alg) {
|
||||
Double m = o[1];
|
||||
Double b = o[1];
|
||||
int i = o[0].intValue();
|
||||
plotPanel.addLineToPlot(m, b, color[i], name[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawLines(Object[] results, int alg){
|
||||
String[] castedResults = Arrays.copyOf(results, results.length, String[].class);
|
||||
public void drawLines(Object[] results, int alg) {
|
||||
String[] castedResults = Arrays.copyOf(results, results.length, String[].class);
|
||||
Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA};
|
||||
String[] name = {"LMS","RM", "TS"};
|
||||
String[] name = {"LMS", "RM", "TS"};
|
||||
|
||||
Double m = Double.parseDouble(castedResults[0]);
|
||||
Double b = Double.parseDouble(castedResults[1]);
|
||||
plotDialog.addLineToPlot(m,b,color[alg],name[alg]);
|
||||
Double m = Double.parseDouble(castedResults[0]);
|
||||
Double b = Double.parseDouble(castedResults[1]);
|
||||
plotPanel.addLineToPlot(m, b, color[alg], name[alg]);
|
||||
}
|
||||
|
||||
public void setDualPoints(LinkedList<Line> points){
|
||||
plotDialog = new PlotDialog();
|
||||
plotDialog.setBorder(new TitledBorder("Plot"));
|
||||
splitPane.setRightComponent(plotDialog);
|
||||
plotDialog.createPlot(points);
|
||||
plotDialog.repaint();
|
||||
plotDialog.revalidate();
|
||||
public void setDualPoints(LinkedList<Line> points) {
|
||||
plotPanel = new PlotPanel();
|
||||
plotPanel.setBorder(new TitledBorder("Plot"));
|
||||
splitPane.setRightComponent(plotPanel);
|
||||
plotPanel.createPlot(points);
|
||||
plotPanel.repaint();
|
||||
plotPanel.revalidate();
|
||||
}
|
||||
|
||||
private void addBlankRows(int n){
|
||||
for (int i=0;i<n;i++){
|
||||
String[] tmp = {"","","","",};
|
||||
private void addBlankRows(int n) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
String[] tmp = {"", "", "", "",};
|
||||
model.addRow(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentRow(int val){
|
||||
public void setCurrentRow(int val) {
|
||||
this.currentRowOfTypes += val;
|
||||
}
|
||||
|
||||
|
||||
private int checkSelection(){
|
||||
if (lms.isSelected() && rm.isSelected() && ts.isSelected()){
|
||||
private int checkSelection() {
|
||||
if (lms.isSelected() && rm.isSelected() && ts.isSelected()) {
|
||||
return 6;
|
||||
} else if (!lms.isSelected() && rm.isSelected() && ts.isSelected()){
|
||||
} else if (!lms.isSelected() && rm.isSelected() && ts.isSelected()) {
|
||||
return 5;
|
||||
} else if (lms.isSelected() && !rm.isSelected() && ts.isSelected()){
|
||||
} else if (lms.isSelected() && !rm.isSelected() && ts.isSelected()) {
|
||||
return 4;
|
||||
} else if (lms.isSelected() && rm.isSelected() && !ts.isSelected()){
|
||||
} else if (lms.isSelected() && rm.isSelected() && !ts.isSelected()) {
|
||||
return 3;
|
||||
} else if (!lms.isSelected() && !rm.isSelected() && ts.isSelected()){
|
||||
} else if (!lms.isSelected() && !rm.isSelected() && ts.isSelected()) {
|
||||
return 2;
|
||||
} else if (!lms.isSelected() && rm.isSelected() && !ts.isSelected()){
|
||||
} else if (!lms.isSelected() && rm.isSelected() && !ts.isSelected()) {
|
||||
return 1;
|
||||
} else if (lms.isSelected() && !rm.isSelected() && !ts.isSelected()){
|
||||
} else if (lms.isSelected() && !rm.isSelected() && !ts.isSelected()) {
|
||||
return 0;
|
||||
} else {
|
||||
throw new IllegalStateException("Mindestens ein Algortihmus muss selektiert werden");
|
|
@ -0,0 +1,91 @@
|
|||
package view.panels;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 02.06.2017.
|
||||
*/
|
||||
public class InfoPanel extends JPanel {
|
||||
|
||||
private JTextPane output;
|
||||
private JScrollPane scrollPane;
|
||||
private StringBuilder content;
|
||||
|
||||
public InfoPanel() {
|
||||
this.setBorder(new TitledBorder("Ausgabekanal"));
|
||||
this.setLayout(new BorderLayout());
|
||||
output = new JTextPane();
|
||||
output.setEditable(false);
|
||||
output.setContentType("text/html");
|
||||
|
||||
content = new StringBuilder();
|
||||
|
||||
scrollPane = new JScrollPane(output);
|
||||
scrollPane.setWheelScrollingEnabled(true);
|
||||
this.add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void appendParagraph(String p) {
|
||||
|
||||
content.append("<p>" + p + "</p>");
|
||||
|
||||
output.setText(content.toString());
|
||||
}
|
||||
|
||||
public void appendParagraphWithHeading(String h1) {
|
||||
|
||||
content.append("<h1>" + h1 + "</h1>");
|
||||
|
||||
output.setText(content.toString());
|
||||
}
|
||||
|
||||
public void appendParagraphRed(String p) {
|
||||
|
||||
content.append("<p style=\" color:red \"><em><strong>" + p + "</strong></em></p>");
|
||||
|
||||
output.setText(content.toString());
|
||||
}
|
||||
|
||||
public void appendParagraphGreen(String p) {
|
||||
|
||||
content.append("<p style=\" color:green \"><em><strong>" + p + "</strong></em></p>");
|
||||
|
||||
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>");
|
||||
if (heading.size() > 1) {
|
||||
for (String str : heading) {
|
||||
content.append("<th style=\" border: 1px solid black; \">" + str + "</th>");
|
||||
}
|
||||
} else {
|
||||
content.append("<th style=\" border: 1px solid black;\" colspan=\"" + rows.get(0).size() + "\"; >" + heading.get(0) + "</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());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package view.panels;
|
||||
|
||||
import model.Line;
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.plot.PlotOrientation;
|
||||
import org.jfree.chart.plot.XYPlot;
|
||||
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
|
||||
import org.jfree.data.xy.XYSeries;
|
||||
import org.jfree.data.xy.XYSeriesCollection;
|
||||
import org.jfree.util.ShapeUtilities;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 29.05.2017.
|
||||
*/
|
||||
public class PlotPanel extends JPanel {
|
||||
|
||||
private JFreeChart chart;
|
||||
private ChartPanel panel;
|
||||
private XYSeriesCollection datapoints;
|
||||
private XYSeries series;
|
||||
private Double min;
|
||||
private Double max;
|
||||
private XYPlot xyPlot;
|
||||
private int seriesCount;
|
||||
|
||||
private XYLineAndShapeRenderer renderer;
|
||||
private Shape diamond;
|
||||
|
||||
public PlotPanel() {
|
||||
super();
|
||||
this.setLayout(new BorderLayout());
|
||||
seriesCount = 1;
|
||||
}
|
||||
|
||||
public void createPlot(LinkedList<Line> points) {
|
||||
if (!points.isEmpty()) {
|
||||
try {
|
||||
Thread thread = new Thread(() -> convertData(points));
|
||||
thread.start();
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//createScatterPlot
|
||||
chart = ChartFactory.createXYLineChart("",
|
||||
"X", "Y", datapoints, PlotOrientation.VERTICAL, true, true, false);
|
||||
diamond = ShapeUtilities.createDiamond(2f);
|
||||
chart.setBorderVisible(false);
|
||||
chart.setAntiAlias(true);
|
||||
chart.getPlot().setBackgroundPaint(Color.WHITE);
|
||||
chart.setBorderVisible(false);
|
||||
|
||||
|
||||
xyPlot = (XYPlot) chart.getPlot();
|
||||
xyPlot.setDomainCrosshairVisible(true);
|
||||
xyPlot.setRangeCrosshairVisible(true);
|
||||
|
||||
|
||||
renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
|
||||
renderer.setSeriesLinesVisible(0, false);
|
||||
renderer.setSeriesShapesVisible(0, true);
|
||||
renderer.setSeriesLinesVisible(1, true);
|
||||
renderer.setSeriesLinesVisible(1, true);
|
||||
renderer.setSeriesPaint(0, Color.blue);
|
||||
renderer.setSeriesShape(0, diamond);
|
||||
renderer.setBaseSeriesVisible(true);
|
||||
|
||||
|
||||
xyPlot.setDomainCrosshairVisible(true);
|
||||
xyPlot.setRangeCrosshairVisible(true);
|
||||
|
||||
panel = new ChartPanel(chart);
|
||||
panel.setMouseZoomable(false);
|
||||
this.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (datapoints != null)
|
||||
datapoints.removeAllSeries();
|
||||
}
|
||||
|
||||
public void addLineToPlot(double m, double b, Paint color, String name) {
|
||||
|
||||
XYSeries linesA = new XYSeries(name);
|
||||
linesA.add(min.doubleValue(), min * m + b);
|
||||
linesA.add(max.doubleValue(), max * m + b);
|
||||
|
||||
datapoints.addSeries(linesA);
|
||||
|
||||
renderer.setSeriesPaint(seriesCount, color);
|
||||
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
|
||||
renderer.setBaseSeriesVisible(true);
|
||||
renderer.setSeriesLinesVisible(seriesCount, true);
|
||||
seriesCount++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void addLineToPlot(double m, double b, String name) {
|
||||
|
||||
|
||||
XYSeries linesA = new XYSeries(name);
|
||||
linesA.add(min.doubleValue(), min * m + b);
|
||||
linesA.add(max.doubleValue(), max * m + b);
|
||||
|
||||
datapoints.addSeries(linesA);
|
||||
seriesCount = xyPlot.getSeriesCount();
|
||||
renderer.setSeriesPaint(seriesCount, Color.red);
|
||||
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
|
||||
renderer.setBaseSeriesVisible(true);
|
||||
renderer.setSeriesLinesVisible(seriesCount, 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().doubleValue(), p.getB().doubleValue() * (-1));
|
||||
coordinates.add(p.getM());
|
||||
|
||||
}
|
||||
this.max = series.getMaxX();
|
||||
this.min = series.getMinX();
|
||||
datapoints.addSeries(series);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package view.panels.tabs;
|
||||
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import view.panels.PlotPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 02.06.2017.
|
||||
*/
|
||||
public class LMSPanel extends TabPanel {
|
||||
|
||||
|
||||
private JLabel[] labels;
|
||||
private JTextField[] input;
|
||||
private JPanel continer;
|
||||
|
||||
private GridBagConstraints gbc;
|
||||
|
||||
public LMSPanel() {
|
||||
super();
|
||||
this.labels = new JLabel[2];
|
||||
this.input = new JTextField[2];
|
||||
|
||||
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);
|
||||
|
||||
addButton(2, getStartButton());
|
||||
|
||||
getNorthPanel().add(continer, BorderLayout.CENTER);
|
||||
this.add(getNorthPanel(), BorderLayout.NORTH);
|
||||
this.add(getCenterPanel(), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void addTextfieldAndInput(int row, String name, Double value) {
|
||||
this.labels[row] = new JLabel(name);
|
||||
this.labels[row].setFont(new Font("SansSerif", Font.PLAIN, 12));
|
||||
this.input[row] = new JTextField();
|
||||
this.input[row].setText("" + value);
|
||||
|
||||
gbc.insets = new Insets(0, 5, 0, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
continer.add(this.labels[row], gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
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);
|
||||
}
|
||||
|
||||
private void addButton(int row, JButton button) {
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
|
||||
gbc.insets = new Insets(30, 0, 5, 0);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
gbc.gridwidth = 1;
|
||||
buttonPanel.add(button);
|
||||
continer.add(buttonPanel, gbc);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String[] getInput() {
|
||||
String[] input = new String[3];
|
||||
input[0] = this.input[0].getText();
|
||||
input[1] = this.input[1].getText();
|
||||
|
||||
if (isNumeric(input[0]) && isNumeric(input[1])) {
|
||||
return input;
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(this, "Bitte geben Sie numerische Werte als Parameter an.", "Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNumeric(String str) {
|
||||
try {
|
||||
double d = Double.parseDouble(str);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package view.panels.tabs;
|
||||
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import view.panels.PlotPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 21.06.2017.
|
||||
*/
|
||||
public class RMPanel extends TabPanel {
|
||||
|
||||
private JLabel labels;
|
||||
private JTextField input;
|
||||
private JPanel continer;
|
||||
private GridBagConstraints gbc;
|
||||
|
||||
public RMPanel() {
|
||||
super();
|
||||
this.labels = new JLabel();
|
||||
|
||||
this.input = new JTextField();
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
|
||||
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, "\u00df (0 < \u00df < 1)", 0.5);
|
||||
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
gbc.insets = new Insets(30, 0, 10, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 2;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
buttonPanel.add(getStartButton());
|
||||
continer.add(buttonPanel, gbc);
|
||||
|
||||
getNorthPanel().add(continer, BorderLayout.CENTER);
|
||||
this.add(getNorthPanel(), BorderLayout.NORTH);
|
||||
this.add(getCenterPanel(), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTextfieldAndInput(int row, String name, Double value) {
|
||||
this.labels = new JLabel(name);
|
||||
this.labels.setFont(new Font("SansSerif", Font.PLAIN, 13));
|
||||
this.input = new JTextField();
|
||||
this.input.setText("" + value);
|
||||
|
||||
gbc.insets = new Insets(0, 5, 0, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
continer.add(this.labels, gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = row;
|
||||
gbc.weightx = 0.9;
|
||||
gbc.weighty = 0.05;
|
||||
gbc.insets = new Insets(0, 0, 0, 5);
|
||||
continer.add(this.input, gbc);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String getInput() {
|
||||
String input = "";
|
||||
input = this.input.getText();
|
||||
if (isNumeric(input))
|
||||
return input;
|
||||
else
|
||||
JOptionPane.showMessageDialog(this, "Bitte geben Sie numerische Werte als Parameter an.", "Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setInput(JTextField input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
|
||||
public boolean isNumeric(String str) {
|
||||
try {
|
||||
double d = Double.parseDouble(str);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package view.panels.tabs;
|
||||
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import view.panels.PlotPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 26.06.2017.
|
||||
*/
|
||||
public class TSPanel extends TabPanel {
|
||||
|
||||
|
||||
private JPanel continer;
|
||||
private GridBagConstraints gbc;
|
||||
|
||||
public TSPanel() {
|
||||
super();
|
||||
|
||||
this.continer = new JPanel();
|
||||
this.continer.setLayout(new GridBagLayout());
|
||||
|
||||
this.gbc = new GridBagConstraints();
|
||||
this.gbc.anchor = GridBagConstraints.NORTH;
|
||||
this.gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
|
||||
gbc.insets = new Insets(10, 0, 10, 0);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.weightx = 0.05;
|
||||
gbc.weighty = 0.05;
|
||||
buttonPanel.add(getStartButton());
|
||||
continer.add(buttonPanel, gbc);
|
||||
|
||||
getNorthPanel().add(continer, BorderLayout.CENTER);
|
||||
this.add(getNorthPanel(), BorderLayout.NORTH);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package view.panels.tabs;
|
||||
|
||||
import view.panels.PlotPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 10.09.2017.
|
||||
*/
|
||||
public abstract class TabPanel extends JPanel{
|
||||
|
||||
|
||||
private PlotPanel plotPanel;
|
||||
private JPanel northPanel;
|
||||
private JPanel centerPanel;
|
||||
|
||||
private JButton startButton;
|
||||
|
||||
public TabPanel() {
|
||||
super();
|
||||
this.centerPanel = new JPanel(new BorderLayout());
|
||||
this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
|
||||
|
||||
this.setLayout(new BorderLayout());
|
||||
this.northPanel = new JPanel(new BorderLayout());
|
||||
this.centerPanel = new JPanel(new BorderLayout());
|
||||
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
|
||||
this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
|
||||
|
||||
|
||||
this.add(centerPanel, BorderLayout.CENTER);
|
||||
this.add(northPanel, BorderLayout.NORTH);
|
||||
|
||||
this.startButton = new JButton("Start");
|
||||
this.startButton.setFont(new Font("Verdana", Font.PLAIN, 16));
|
||||
}
|
||||
|
||||
public void setPlotPanel(PlotPanel plotPanel) {
|
||||
this.plotPanel = plotPanel;
|
||||
if (this.centerPanel.getComponents().length > 0)
|
||||
this.centerPanel.remove(0);
|
||||
|
||||
this.centerPanel.add(plotPanel, BorderLayout.CENTER);
|
||||
this.plotPanel.setVisible(true);
|
||||
this.repaint();
|
||||
this.revalidate();
|
||||
}
|
||||
|
||||
protected void addTextfieldAndInput(int row, String name, Double value){
|
||||
//muss nicht obligatorisch implementiert werden
|
||||
}
|
||||
|
||||
public PlotPanel getPlotPanel() {
|
||||
return plotPanel;
|
||||
}
|
||||
|
||||
public JButton getStartButton() {
|
||||
return startButton;
|
||||
}
|
||||
|
||||
public void setStartButton(JButton startButton) {
|
||||
this.startButton = startButton;
|
||||
}
|
||||
|
||||
public JPanel getNorthPanel() {
|
||||
return northPanel;
|
||||
}
|
||||
|
||||
public void setNorthPanel(JPanel northPanel) {
|
||||
this.northPanel = northPanel;
|
||||
}
|
||||
|
||||
public JPanel getCenterPanel() {
|
||||
return centerPanel;
|
||||
}
|
||||
|
||||
public void setCenterPanel(JPanel centerPanel) {
|
||||
this.centerPanel = centerPanel;
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -1,99 +0,0 @@
|
|||
package Model;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import Model.DCEL.DoublyConnectedEdgeList;
|
||||
import Model.DCEL.Edge;
|
||||
import Model.DCEL.Face;
|
||||
import Model.DCEL.Node;
|
||||
import java.util.LinkedList;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class DoublyConnectedEdgeListTest {
|
||||
|
||||
private static DoublyConnectedEdgeList dcel;
|
||||
private static Node v1, v2, v3, v4, v5;
|
||||
private static Edge e1, e2, e3, e4, e5;
|
||||
private static Face f1, f2;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dcel = new DoublyConnectedEdgeList();
|
||||
|
||||
//initialisiere die TestKnoten im Graphen
|
||||
v1 = dcel.createNode(new Point(2.5, 7.5), "v1");
|
||||
v2 = dcel.createNode(new Point(2.5, 4.0), "v2");
|
||||
v3 = dcel.createNode(new Point(6.5, 3.5), "v3");
|
||||
v4 = dcel.createNode(new Point(8.5, 6.5), "v4");
|
||||
v5 = dcel.createNode(new Point(6.0, 8.0), "v5");
|
||||
|
||||
//initialisere Kanten im Graph
|
||||
e1 = dcel.createEdge(v1, v5, "e1");
|
||||
e2 = dcel.createEdge(v5, v4, "e2");
|
||||
e3 = dcel.createEdge(v4, v3, "e3");
|
||||
e4 = dcel.createEdge(v3, v2, "e4");
|
||||
e5 = dcel.createEdge(v2, v1, "e5");
|
||||
|
||||
dcel.createConnection(e1, e2);
|
||||
dcel.createConnection(e2, e3);
|
||||
dcel.createConnection(e3, e4);
|
||||
dcel.createConnection(e4, e5);
|
||||
dcel.createConnection(e5, e1);
|
||||
|
||||
//intialisiere die Flaechen
|
||||
f1 = dcel.createFace(null, e1, "f1");
|
||||
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 testNodeEdgeAccess() {
|
||||
System.out.println("Test: testNodeEdgeAccess();");
|
||||
|
||||
assertEquals(5, dcel.getConnectedEdges(v4).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDCELAccess() {
|
||||
System.out.println("Test: testDCELAccess();");
|
||||
|
||||
assertEquals(e1, e1.getTwin().getTwin());
|
||||
assertEquals(e1, e1.getPrev().getNext());
|
||||
assertEquals(e2.getID(), e1.getTwin().getPrev().getTwin().getID());
|
||||
assertEquals(e1, e1.getNext().getNext().getNext().getNext().getNext());
|
||||
assertEquals(e1.getTwin(), e1.getTwin().getNext().getNext().getNext().getNext().getNext());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
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.Point;
|
||||
import Model.Interval;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 12.06.2017.
|
||||
*/
|
||||
public class LeastMedianOfSquaresEstimatorTest {
|
||||
|
||||
private LeastMedianOfSquaresEstimator lms;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
Double[] x = {18d, 24d, 30d, 34d, 38d};
|
||||
Double[] y = {18d, 26d, 30d, 40d, 70d};
|
||||
|
||||
LinkedList<Line> lines = new LinkedList<>();
|
||||
LinkedList<Point> intersections = new LinkedList<>();
|
||||
|
||||
for (int i = 0; i < 5; 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 {
|
||||
// double[] umin = {6,3,4,1,2,5};
|
||||
// double[] umax = {3,5,2,6,1,4};
|
||||
double[] umin = {1, 2, 3, 4};
|
||||
double[] umax = {2, 3, 4, 1};
|
||||
ArrayList<Integer> a = new ArrayList<>();
|
||||
ArrayList<Integer> b = new ArrayList<>();
|
||||
|
||||
for (double d : umin) {
|
||||
a.add((int) d);
|
||||
}
|
||||
|
||||
for (double d : umax) {
|
||||
b.add((int) d);
|
||||
}
|
||||
IntersectionCounter invCounter = new IntersectionCounter();
|
||||
int ret = invCounter.run(a, b);
|
||||
assertEquals(3d, ret, 0.001);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void geEjValues() throws Exception {
|
||||
|
||||
Double[] expected = {36d, 50d, 60d, 74d, 108d};
|
||||
ArrayList<Double> actual = lms.getEjValues(1d);
|
||||
assertArrayEquals(expected, actual.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calcKMinusBracelet() throws Exception {
|
||||
|
||||
Point point = new Point(1d, 1d);
|
||||
Double[] expected = {24d, 36d, 60d};
|
||||
Double[] actual = lms.calcKMinusBracelet(point, 3);
|
||||
|
||||
assertArrayEquals(expected, actual);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upperBound() throws Exception {
|
||||
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);
|
||||
|
||||
Interval interval = new Interval(-2, 0);
|
||||
lms.lowerBound(interval);
|
||||
assertTrue(interval.getActivity());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package Presenter.ImportExport;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 21.06.2017.
|
||||
*/
|
||||
public class DataImporterTest {
|
||||
|
||||
private DataImporter importer;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
//importer = new DataImporter("C:\\Users\\Armin\\Desktop\\test.csv", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void run() throws Exception {
|
||||
//importer.run();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package model;
|
||||
|
||||
import model.DCEL.DoublyConnectedEdgeList;
|
||||
import model.DCEL.Edge;
|
||||
import model.DCEL.Face;
|
||||
import model.DCEL.Node;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 30.05.2017.
|
||||
*/
|
||||
public class DoublyConnectedEdgeListTest {
|
||||
|
||||
private static DoublyConnectedEdgeList dcel;
|
||||
private static Node v1, v2, v3, v4, v5;
|
||||
private static Edge e1, e2, e3, e4, e5;
|
||||
private static Face f1, f2;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dcel = new DoublyConnectedEdgeList();
|
||||
|
||||
//initialisiere die TestKnoten im Graphen
|
||||
v1 = dcel.createNode(new Point(2.5, 7.5), "v1");
|
||||
v2 = dcel.createNode(new Point(2.5, 4.0), "v2");
|
||||
v3 = dcel.createNode(new Point(6.5, 3.5), "v3");
|
||||
v4 = dcel.createNode(new Point(8.5, 6.5), "v4");
|
||||
v5 = dcel.createNode(new Point(6.0, 8.0), "v5");
|
||||
|
||||
//initialisere Kanten im Graph
|
||||
e1 = dcel.createEdge(v1, v5, "e1");
|
||||
e2 = dcel.createEdge(v5, v4, "e2");
|
||||
e3 = dcel.createEdge(v4, v3, "e3");
|
||||
e4 = dcel.createEdge(v3, v2, "e4");
|
||||
e5 = dcel.createEdge(v2, v1, "e5");
|
||||
|
||||
dcel.createConnection(e1, e2);
|
||||
dcel.createConnection(e2, e3);
|
||||
dcel.createConnection(e3, e4);
|
||||
dcel.createConnection(e4, e5);
|
||||
dcel.createConnection(e5, e1);
|
||||
|
||||
//intialisiere die Flaechen
|
||||
f1 = dcel.createFace(null, e1, "f1");
|
||||
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 testNodeEdgeAccess() {
|
||||
System.out.println("Test: testNodeEdgeAccess();");
|
||||
|
||||
assertEquals(5, dcel.getConnectedEdges(v4).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDCELAccess() {
|
||||
System.out.println("Test: testDCELAccess();");
|
||||
|
||||
assertEquals(e1, e1.getTwin().getTwin());
|
||||
assertEquals(e1, e1.getPrev().getNext());
|
||||
assertEquals(e2.getID(), e1.getTwin().getPrev().getTwin().getID());
|
||||
assertEquals(e1, e1.getNext().getNext().getNext().getNext().getNext());
|
||||
assertEquals(e1.getTwin(), e1.getTwin().getNext().getNext().getNext().getNext().getNext());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package presenter.algorithms;
|
||||
|
||||
|
||||
import model.Interval;
|
||||
import model.Line;
|
||||
import model.Point;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 12.06.2017.
|
||||
*/
|
||||
public class LeastMedianOfSquaresEstimatorTest {
|
||||
|
||||
private LeastMedianOfSquaresEstimator lms;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
Double[] x = {18d, 24d, 30d, 34d, 38d};
|
||||
Double[] y = {18d, 26d, 30d, 40d, 70d};
|
||||
|
||||
LinkedList<Line> lines = new LinkedList<>();
|
||||
LinkedList<Point> intersections = new LinkedList<>();
|
||||
|
||||
for (int i = 0; i < 5; 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 {
|
||||
// double[] umin = {6,3,4,1,2,5};
|
||||
// double[] umax = {3,5,2,6,1,4};
|
||||
double[] umin = {1, 2, 3, 4};
|
||||
double[] umax = {2, 3, 4, 1};
|
||||
ArrayList<Integer> a = new ArrayList<>();
|
||||
ArrayList<Integer> b = new ArrayList<>();
|
||||
|
||||
for (double d : umin) {
|
||||
a.add((int) d);
|
||||
}
|
||||
|
||||
for (double d : umax) {
|
||||
b.add((int) d);
|
||||
}
|
||||
IntersectionCounter invCounter = new IntersectionCounter();
|
||||
int ret = invCounter.run(a, b);
|
||||
assertEquals(3d, ret, 0.001);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void geEjValues() throws Exception {
|
||||
|
||||
Double[] expected = {36d, 50d, 60d, 74d, 108d};
|
||||
ArrayList<Double> actual = lms.getEjValues(1d);
|
||||
assertArrayEquals(expected, actual.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calcKMinusBracelet() throws Exception {
|
||||
|
||||
Point point = new Point(1d, 1d);
|
||||
Double[] expected = {24d, 36d, 60d};
|
||||
Double[] actual = lms.calcKMinusBracelet(point, 3);
|
||||
|
||||
assertArrayEquals(expected, actual);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upperBound() throws Exception {
|
||||
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);
|
||||
|
||||
Interval interval = new Interval(-2, 0);
|
||||
lms.lowerBound(interval);
|
||||
assertTrue(interval.getActivity());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package presenter.io;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 21.06.2017.
|
||||
*/
|
||||
public class DataImporterTest {
|
||||
|
||||
private DataImporter importer;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
//importer = new DataImporter("C:\\Users\\Armin\\Desktop\\test.csv", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void run() throws Exception {
|
||||
//importer.run();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue