package Baustelle.physical;
/**
*
*/
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import Baustelle.graphical.KranSymbol;
//import KranSymbol;
//import Material;
/**
* Die Kranklasse stellt die Kräne auf der Baustelle dar.
* <p>Die Funktionen der Kräne sind
* <ul>
* <li> Auslegerdrehen in beide Richtungen
* <li> Krane bewegen vor und zurück auf einer Schiene
* <li> Katze bewegen vor und zurück am Ausleger
* <li> Material entladen
* <li> Material abladen
* <li> Kranhaken heben und senken
* </ul>
* <p>Der Kran kann feststehend oder beweglich sein, der Benutzer muss alle benötigten Daten dem Kran geben, z.B:
* Auslegerlänge,Kranhöhe und die Koordinaten der Kranschiene.
* @author Ulf Wagner
* @author Ali Ismail
*
*/
public class Kran extends Baugeraet {
private double x0,y0,x1,y1;
private String KranCode;
private double x ,y ;
private double auslegerwinkel;
private double katzeLocation=1;
private double katzeXLocation;
private double katzeYLocation;
private double drehenGeschwindigkeit;
private double katzeGeschwindigkeit;
private double baseGeschwindigkeit;
private double hakenGeschwindigkeit;
private double maxTragfaehigkeit;
private double minTragfaehigkeit;
private double aktuellTragfaehigkeit;
private double aktuellLast;
private double baseBreite;
private double baseLocation;
private double baseBewegenLaenge;
private double ausLegerlaenge;
private double kranHohe;
private double hakenHohe;
private Runnable runnable;
private boolean krandrehen=false;
private boolean katzebewegt=false;
private boolean basebewegt=false;
private boolean hakenbewegt=false;
protected ArrayList<Material> materialListe = new ArrayList<Material>();
/**
* Konstruktor für den Kran
* @param kranCode Krancode ?
*/
public Kran(String kranCode) {
this.x=0;
this.y=0;
this.x0=0;
this.x1=0;
this.y0=0;
this.y1=0;
this.baseBewegenLaenge=0;
this.baseLocation=0;
this.katzeXLocation=0;
this.katzeYLocation=0;
this.katzeLocation=0;
this.baseBreite=3;
this.ausLegerlaenge=30;
this.KranCode=kranCode;
}
/**
* Konstruktor für den Kran
*/
public Kran(){
this.x=0;
this.y=0;
this.x0=0;
this.x1=0;
this.y0=0;
this.y1=0;
this.baseBewegenLaenge=0;
this.baseLocation=0;
this.katzeXLocation=0;
this.katzeYLocation=0;
this.katzeLocation=0;
this.baseBreite=3;
this.ausLegerlaenge=30;
this.KranCode="";
}
/**
* Konstruktor für den Kran
* @param x x-Koordinate für den neuen Kran
* @param y y-Koordinate für den neuen Kran
* @param fussbreite die Fussbreite
* @param auslegerLaenge die Auslegerlänge
* <p>Ausgangswerte :
* <ul>
* <li>(x0,y0)=(x1,y1)=(x,y)
* <li>katzeXLocation=x
* <li>katzeYLocation=y
* <li>katzeLocation=0
* <li>drehenGeschwindigkeit=0
* <li>katzeGeschwindigkeit=0
* <li>baseGeschwindigkeit=0
* <li>minTragfaehigkeit=0
* <li>maxTragfaehigkeit=0
* </ul>
*/
public Kran(double x,double y,double fussbreite, double auslegerLaenge){
this.x=x;
this.y=y;
this.x0=x;
this.x1=x;
this.y0=y;
this.y1=y;
this.baseBewegenLaenge=0;
this.baseLocation=0;
this.katzeXLocation=x;
this.katzeYLocation=y;
this.katzeLocation=0;
this.baseBreite=fussbreite;
this.ausLegerlaenge=auslegerLaenge;
this.KranCode="";
}
/**
* setzt die Sichtbarkeit des Kranes
*/
public void setVisible(boolean visible) {
if (visible) {
if (!isVisible()){
go = new KranSymbol();
meldeAn(go);
benachrichtige();
super.setVisible(visible);
}
}
else {
if (isVisible()){
meldeAb(this.go);
benachrichtige();
super.setVisible(visible);
}
}
}
/**
* gibt die aktuelle x-Koordinate zurück
* @return x
*/
public double getX() {
return x;
}
/**
* Setzt die x-Koordinate
* @param x neue x-Koordinate
*/
public void setX(double x) {
this.x = x;
benachrichtige();
}
/**
* gibt die aktuelle y-Koordinate zurück
* @return y
*/
public double getY() {
return y;
}
/**
*Setzt die y-Koordinate
* @param y neue y-Koordinate
*/
public void setY(double y) {
this.y = y;
benachrichtige();
}
/**
* gibt die aktuelle x-Koordinate des Anfangs der Schiene zurück
* @return x0
*/
public double getX0() {
return x0;
}
/**
* setzt die x-Koordinate des Anfangs der Schiene
* @param x0 neue x-Koordinate
*/
public void setX0(double x0) {
this.x0 = x0;
benachrichtige();
}
/**
* gibt die aktuelle y-Koordinate des Anfangs der Schiene zurück
* @return y0
*/
public double getY0() {
return y0;
}
/**
* setzt die y-Koordinate des Anfangs der Schiene
* @param y0 neue y-Koordinate
*/
public void setY0(double y0) {
this.y0 = y0;
benachrichtige();
}
/**
* gibt die aktuelle x-Koordinate des Endes der Schiene zurück
* @return x1
*/
public double getX1() {
return x1;
}
/**
* setzt die x-Koordinate des Endes der Schiene
* @param x1 neue x-Koordinate
*/
public void setX1(double x1) {
this.x1 = x1;
benachrichtige();
}
/**
* gibt die aktuelle y-Koordinate des Endes der Schiene zurück
* @return the y1
*/
public double getY1() {
return y1;
}
/**
* setzt die y-Koordinate des Endes der Schiene
* @param y1 neue y-Koordinate
*/
public void setY1(double y1) {
this.y1 = y1;
benachrichtige();
}
/**
* Gibt den Winkel zwischen Kranschiene und x-Achse zurück
* @return double
*/
public double getBaseLineWinkel(){
return this.getDegree(x1-x0,y1-y0);
}
/**
* Gibt den Winkel des Auslegers zurück
* @return Auslegerwinkel
*/
public double getAuslegerwinkel() {
return auslegerwinkel;
}
/**
* Setzt den neuen Auslegerwinkel
* @param auslegerwinkel neuer Auslegerwinkel
*/
public void setAuslegerwinkel(double auslegerwinkel) {
this.auslegerwinkel = auslegerwinkel;
benachrichtige();
}
/**
* Gibt die Breite des Kranfußes zurück
* @return Fußbreite
*/
public double getbaseBreite() {
return baseBreite;
}
/**
* Setzt die neue Fußbreite
* @param breite neue Fußbreite
*/
public void setbaseBreite(double breite) {
this.baseBreite = breite;
benachrichtige();
}
/**
* Gibt die aktuelle Hakenhöhe zurück
* @return Hakenhöhe
*/
public double getHakenHohe() {
return hakenHohe;
}
/**
* Setzt die neue Hakenhöhe
* @param hakenHohe neue Hakenhöhe
*/
public void setHakenHohe(double hakenHohe) {
this.hakenHohe = hakenHohe;
}
/**
* Gibt die aktuelle Länge des Auslegers zurück
* @return Auslegerlänge
*/
public double getAusLegerlaenge() {
return ausLegerlaenge;
}
/**
* Setzt die neue Auslegerlänge
* @param ausLegerlaenge neue Auslegerlänge
*/
public void setAusLegerlaenge(double ausLegerlaenge) {
this.ausLegerlaenge = ausLegerlaenge;
benachrichtige();
}
/**
* Dreht den Kranausleger mit der akteullen Drehgeschwindigkeit
* <p>Postive Winkel dreht den Ausleger entgegengesetzt des Uhrzeigers
* @param winkel Drehwinkel (Grad)
* @throws Exception
*/
public synchronized void drehen(double winkel) throws Exception {
if (this.drehenGeschwindigkeit <= 0)
throw new Exception ("Fehler beim Drehen des Auslegers : drehenGeschwindigkeit <= 0");
double s=(Math.abs(winkel)*Math.PI/180)/this.drehenGeschwindigkeit;
final double s1 = s*1000;
final double winkel1=winkel;
final double zeitFaktor= this.getZeitFaktor();
krandrehen=true;
double fahreZeit=0;
double startZeit = System.currentTimeMillis();
double lastZeit=startZeit;
double deltaS;
double auslegerwinkel0=auslegerwinkel;
double aktuellezeitFaktor=zeitFaktor;
while ( s1 > fahreZeit ) {
deltaS = aktuellezeitFaktor*(System.currentTimeMillis() - lastZeit);
if (aktuellezeitFaktor != getZeitFaktor()) {
aktuellezeitFaktor=getZeitFaktor();
}
lastZeit=System.currentTimeMillis();
fahreZeit=fahreZeit+deltaS;
auslegerwinkel=auslegerwinkel+winkel1*(deltaS/(double)s1) ;
benachrichtige();
}
krandrehen=false;
auslegerwinkel=auslegerwinkel0+winkel1;
katzeXLocation=x+ausLegerlaenge*Math.cos(auslegerwinkel*Math.PI/180)*katzeLocation;
katzeYLocation=y+ausLegerlaenge*Math.sin(auslegerwinkel*Math.PI/180)*katzeLocation;
benachrichtige();
}
/**
* Diese Methode bewegt den Kran, dreht den Kranausleger und bewegt die Katze gleichzeitig von der akteullen Lage zur (katzeX,katzeY) Koordinate.
* <p> Der Kran bewegt sich nur, wenn die neue Lage (katzeX,katzeY) nicht erreichbar vom Ausgangspunkt ist.
* <p> Wenn der Kran ohne Last ist, bewegt sich der Kran auf der Schiene bis zu einem Punkt, wo die neue Lage erreichbar ist
* <p> Wenn der Kran beladen ist, bewegt sich der Kran nur bis zu einer erreichbaren Stelle
* @param katzeX x-Koordinate der neuen Lage
* @param katzeY y-Hoordinate der neuen Lage
* @throws Exception
*/
public void setKatzeXYLocation(double katzeX ,double katzeY) throws Exception {
double neuKatzeLocation;
double xBase,yBase;
double newBaseLocation;
double drehenAngle;
double abstand;
double d,xx,yy;
double A = katzeX - x0;
double B = katzeY - y0;
double C = x1 - x0;
double D = y1 - y0;
double dot = A * C + B * D;
double len_sq = C * C + D * D;
double param = dot / len_sq;
xBase=x;
yBase=y;
double kranBaseAngel=getDegree((x1-x0),(y1-y0));
if(param < 0)
{
xx = x0;
yy = y0;
}
else if(param > 1)
{
xx = x1;
yy = y1;
}
else
{
xx = x0 + param * C;
yy = y0 + param * D;
}
d=Math.sqrt(Math.pow(xx-katzeX, 2)+Math.pow(yy-katzeY, 2));
if (d > this.ausLegerlaenge )
throw new Exception("ungültiger neuer Ort der Katze");
if (this.aktuellLast > this.maxTragfaehigkeit)
throw new Exception("Die aktuellLast > maxTragfaehigkeit");
neuKatzeLocation=Math.sqrt( Math.pow((katzeY-y), 2)+Math.pow((katzeX-x), 2))/this.ausLegerlaenge;
double baseOffset=0;
if ( (neuKatzeLocation > 1 || neuKatzeLocation <= 0 ) && this.aktuellLast > 0) {
double xr=0;
if(this.aktuellLast > this.minTragfaehigkeit )
{xr=this.ausLegerlaenge*((this.aktuellLast-this.minTragfaehigkeit)/(this.maxTragfaehigkeit-this.minTragfaehigkeit));}
neuKatzeLocation=(this.ausLegerlaenge-xr)/this.ausLegerlaenge;
double Base_katze_dis=Math.sqrt(Math.pow(katzeX-xx,2)+Math.pow(katzeY-yy,2));
baseOffset=Math.sqrt(Math.pow(this.ausLegerlaenge-xr,2)-Math.pow(Base_katze_dis,2));
if (x > xx) {
xBase=xx+baseOffset*Math.cos(Math.toRadians(kranBaseAngel));
yBase=yy+baseOffset*Math.sin(Math.toRadians(kranBaseAngel));
}
else {
xBase=xx-baseOffset*Math.cos(Math.toRadians(kranBaseAngel));
yBase=yy-baseOffset*Math.sin(Math.toRadians(kranBaseAngel));
}
newBaseLocation=Math.sqrt(Math.pow(xBase-x0, 2)+Math.pow(yBase-y0, 2))/Math.sqrt(Math.pow(x1-x0, 2)+Math.pow(y1-y0, 2));
abstand=(newBaseLocation-baseLocation)*Math.sqrt(Math.pow(x1-x0, 2)+Math.pow(y1-y0, 2));
System.out.println("Kran Umzug :" + abstand);
this.kranUmzug(abstand);
}
if ( (neuKatzeLocation > 1 || neuKatzeLocation <= 0 ) ){
neuKatzeLocation=Math.sqrt( Math.pow((katzeY-yy), 2)+Math.pow((katzeX-xx), 2))/this.ausLegerlaenge;
if (AktuellTragfaehigkeit(neuKatzeLocation) < this.aktuellLast)
throw new Exception ("Die Tragfähigkeit für den neuen Ort der Katze ist geringer als die aktuelle Last ");
newBaseLocation=Math.sqrt(Math.pow(xx-x0, 2)+Math.pow(yy-y0, 2))/Math.sqrt(Math.pow(x1-x0, 2)+Math.pow(y1-y0, 2));
abstand=(newBaseLocation-baseLocation)*Math.sqrt(Math.pow(x1-x0, 2)+Math.pow(y1-y0, 2));
this.kranUmzug(abstand);
xBase=xx;
yBase=yy;
}
if (AktuellTragfaehigkeit(neuKatzeLocation) < this.aktuellLast)
throw new Exception ("Die Tragfähigkeit für den neuen Ort der Katze ist geringer als die aktuelle Last ");
abstand=(neuKatzeLocation-this.katzeLocation)*this.ausLegerlaenge;
katzeXLocation=x+ausLegerlaenge*Math.cos(auslegerwinkel*Math.PI/180)*katzeLocation;
katzeYLocation=y+ausLegerlaenge*Math.sin(auslegerwinkel*Math.PI/180)*katzeLocation;
double alpha=getDegree((katzeX-xBase),(katzeY-yBase));
drehenAngle=alpha-auslegerwinkel;
if (alpha-auslegerwinkel > 180)
drehenAngle=-(360 -(alpha-auslegerwinkel));
try {
this.drehen(drehenAngle);
this.katzeUmzug(abstand);
} catch (InterruptedException e) {
e.printStackTrace();
}
benachrichtige();
}
/**
* Bewegt den Kran vor- und zurück auf der Kranschiene
* @param Abstand
* @throws Exception
*/
public void kranUmzug(double abstand) throws Exception{
baseBewegenLaenge=Math.sqrt( Math.pow((y1-y0), 2)+Math.pow((x1-x0), 2));
if (this.baseGeschwindigkeit <= 0 && baseBewegenLaenge > 0 )
throw new Exception ("kranUmzug Fehler : baseGeschwindigkeit <= 0");
final double finalKranocation=((baseLocation*baseBewegenLaenge)+abstand)/baseBewegenLaenge ;
if (baseBewegenLaenge== 0)
throw new Exception ("Dieser Kran kann nicht bewegt werden, setzen Sie bitte (x0,y0) (x1,y1) und baseLocation.");
if (finalKranocation > 1 || finalKranocation <0 )
throw new Exception ("ungültiger Kranumzug");
if (this.baseGeschwindigkeit <= 0)
throw new Exception ("Kranumzug Fehler : kranGeschwindigkeit <= 0 ");
double s=Math.abs(abstand)/this.baseGeschwindigkeit;
final double s1 = s*1000;
final double abstand1=abstand;
final double zeitFaktor=this.getZeitFaktor();
basebewegt=true;
double umzugZeit=0;
double startZeit = System.currentTimeMillis();
double lastZeit=startZeit;
double deltaS;
double aktuellezeitFaktor=zeitFaktor;
while ( s1 > umzugZeit ) {
deltaS = aktuellezeitFaktor*(System.currentTimeMillis() - lastZeit);
lastZeit=System.currentTimeMillis();
if (aktuellezeitFaktor != getZeitFaktor()) {
deltaS=getZeitFaktor()/aktuellezeitFaktor;
umzugZeit=umzugZeit*(getZeitFaktor()/aktuellezeitFaktor);
aktuellezeitFaktor=getZeitFaktor();
}
umzugZeit=umzugZeit+deltaS;
baseLocation=baseLocation +(abstand1/baseBewegenLaenge)*(deltaS/(double)s1);
if(baseLocation <1 && baseLocation > 0)
setBaseLocation(baseLocation);
}
baseLocation=finalKranocation ;
x=x0+baseLocation*(x1-x0);
y=y0+baseLocation*(y1-y0);
benachrichtige();
basebewegt=false;
}
}