278 lines
6.8 KiB
Java
278 lines
6.8 KiB
Java
package de.wwwu.awolf.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;
|
|
|
|
/**
|
|
* Konstruktor
|
|
*
|
|
* @param m Steigung
|
|
* @param b y-Achsenabschnitt
|
|
* @param id 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;
|
|
}
|
|
|
|
/**
|
|
* Konstruktor
|
|
*
|
|
* @param m Steigung
|
|
* @param b y-Achsenabschnitt
|
|
*/
|
|
public Line(double m, double b) {
|
|
this.m = m;
|
|
this.b = b;
|
|
|
|
this.x1 = calculateX1(MIN);
|
|
this.y1 = calculateY1(MIN);
|
|
this.x2 = calculateX2(MAX * 0.5);
|
|
this.y2 = calculateY2(MAX * 0.5);
|
|
}
|
|
|
|
private Double calculateX1(Double min) {
|
|
return (double) min;
|
|
}
|
|
|
|
private Double calculateY1(Double min) {
|
|
return (min * m) + b;
|
|
}
|
|
|
|
private Double calculateX2(Double max) {
|
|
return (double) max;
|
|
}
|
|
|
|
private Double calculateY2(Double max) {
|
|
return (max * m) + b;
|
|
}
|
|
|
|
/**
|
|
* Konstruktor
|
|
*
|
|
* @param x1 x-Koordiante des Startpunkts
|
|
* @param x2 x-Koordinate des Endpunkts
|
|
* @param y1 y-Koordinate des Startpunkts
|
|
* @param y2 y-Koordinate des Endpunkts
|
|
*/
|
|
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);
|
|
|
|
}
|
|
|
|
/**
|
|
* @return Steigung der Gerade
|
|
*/
|
|
public Double getM() {
|
|
return m;
|
|
}
|
|
|
|
/**
|
|
* @param m Steigung der Gerade
|
|
*/
|
|
public void setM(double m) {
|
|
this.m = m;
|
|
}
|
|
|
|
/**
|
|
* @return y-Achsenabschnitt der Gerade
|
|
*/
|
|
public Double getB() {
|
|
return b;
|
|
}
|
|
|
|
/**
|
|
* @param b y-Achsenabschnitt der Gerade
|
|
*/
|
|
public void setB(double b) {
|
|
this.b = b;
|
|
}
|
|
|
|
/**
|
|
* @return id der Gerade
|
|
*/
|
|
public String getId() {
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* @param id id der Gerade
|
|
*/
|
|
public void setId(String id) {
|
|
this.id = id;
|
|
}
|
|
|
|
/**
|
|
* @return x-Koordiante des Startpunkts
|
|
*/
|
|
public Double getX1() {
|
|
return x1;
|
|
}
|
|
|
|
/**
|
|
* @return x-Koordiante des Endpunkts
|
|
*/
|
|
public Double getX2() {
|
|
return x2;
|
|
}
|
|
|
|
/**
|
|
* @return y-Koordiante des Startpunkts
|
|
*/
|
|
public Double getY1() {
|
|
return y1;
|
|
}
|
|
|
|
/**
|
|
* @return y-Koordiante des Endpunkts
|
|
*/
|
|
public Double getY2() {
|
|
return y2;
|
|
}
|
|
|
|
/**
|
|
* Setzt die Koordianten des Segments. Aus dem Segment wird eine Gerade berechnet.
|
|
*
|
|
* @param x1 x-Koordiante des Startpunkts
|
|
* @param y1 y-Koordiante des Endpunkts
|
|
* @param x2 x-Koordinate des Startpunkts
|
|
* @param y2 y-Koordinte des Endpunkts
|
|
*/
|
|
public void setEndPoints(double x1, double y1, double x2, 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);
|
|
}
|
|
|
|
/**
|
|
* Vergleich einzelner Geradern
|
|
*
|
|
* @param obj zu vergleichende Gerade
|
|
* @return <code>true</code> falls die Geraden Gleich sind
|
|
*/
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if (obj instanceof Line) {
|
|
Line other = (Line) obj;
|
|
return other.getM().equals(this.getM()) && other.getB().equals(this.getB());
|
|
} else {
|
|
return super.equals(obj);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return super.hashCode() + this.getM().hashCode() + this.getB().hashCode();
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Line m: " + this.getM() + ", b: " + this.getB();
|
|
}
|
|
|
|
|
|
public Point intersect(Line line) {
|
|
double x = (line.b - this.b) / (this.m - line.m);
|
|
double y = this.m * x + this.b;
|
|
|
|
return new Point(x, y);
|
|
}
|
|
|
|
// Given three colinear points p, q, r, the function checks if
|
|
// point q lies on line segment 'pr'
|
|
public boolean onSegment(Point p, Point q, Point r) {
|
|
if (q.getX() <= Math.max(p.getX(), r.getX()) && q.getX() >= Math.min(p.getX(), r.getX()) &&
|
|
q.getY() <= Math.max(p.getY(), r.getY()) && q.getY() >= Math.min(p.getY(), r.getY()))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
// To find orientation of ordered triplet (p, q, r).
|
|
// The function returns following values
|
|
// 0 --> p, q and r are colinear
|
|
// 1 --> Clockwise
|
|
// 2 --> Counterclockwise
|
|
public int orientation(Point p, Point q, Point r) {
|
|
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
|
|
// for details of below formula.
|
|
double val = (q.getY() - p.getY()) * (r.getX() - q.getX()) -
|
|
(q.getX() - p.getX()) * (r.getY() - q.getY());
|
|
|
|
if (val == 0) return 0; // colinear
|
|
|
|
return (val > 0) ? 1 : 2; // clock or counterclock wise
|
|
}
|
|
|
|
// The main function that returns true if line segment 'p1q1'
|
|
// and 'p2q2' intersect.
|
|
// Line A: y = mx + b -->
|
|
public boolean doIntersect(Line line, double lower, double upper) {
|
|
//this
|
|
Point p1 = new Point(calculateX1(lower), calculateY1(lower));
|
|
Point q1 = new Point(calculateX2(upper), calculateY2(upper));
|
|
Point p2 = new Point(line.calculateX1(lower), line.calculateY1(lower));
|
|
Point q2 = new Point(line.calculateX2(upper), line.calculateY2(upper));
|
|
// Find the four orientations needed for general and
|
|
// special cases
|
|
int o1 = orientation(p1, q1, p2);
|
|
int o2 = orientation(p1, q1, q2);
|
|
int o3 = orientation(p2, q2, p1);
|
|
int o4 = orientation(p2, q2, q1);
|
|
|
|
// General case
|
|
if (o1 != o2 && o3 != o4)
|
|
return true;
|
|
|
|
// Special Cases
|
|
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
|
|
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
|
|
|
|
// p1, q1 and q2 are colinear and q2 lies on segment p1q1
|
|
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
|
|
|
|
// p2, q2 and p1 are colinear and p1 lies on segment p2q2
|
|
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
|
|
|
|
// p2, q2 and q1 are colinear and q1 lies on segment p2q2
|
|
if (o4 == 0 && onSegment(p2, q1, q2)) return true;
|
|
|
|
return false; // Doesn't fall in any of the above cases
|
|
}
|
|
}
|