/*
* Datei: DargestellterGraph.java
* Autor(en): Lukas K�nig
* Java-Version: 1.4
* Erstellt (vor): 19.09.2006
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/
package fmg.fmg8.graphVis;
import fmg.fmg8.graphVis.graph.Knoten;
import java.awt.Point;
import java.awt.Polygon;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Klasse zur Speicherung eines geometrisches Objekt, das sich aus
* Knotenpunkten, Pfeilen und Beschriftungen, denen jeweils Koordinaten
* zugeordnet sind, zusammensetzt.
*
* @author Lukas K�nig.
*/
public class DargestellterGraph implements Serializable {
/**
* Die Serial Version ID (generiert am 25. April 2007).
*/
private static final long serialVersionUID = 3550176063237357036L;
/**
* Koordinaten der Knotenpunkte.
*/
private ArrayList<Point> knotenpunktKoord;
/**
* Ein ausgezeichneter Knoten.
*/
private int selektiert;
/**
* Objekte, die dem entsprechenden Knotenpunkt zugeordnet sind.
*/
private ArrayList<Knoten> knotenpunktObjekte;
/**
* Koordinaten aller Punkte, die Anfangspunkt eines Pfeils sind.
* Dazu geh�rt ein entsprechender Endpunkt.
*/
private ArrayList<Point> pfeilUrspruenge;
/**
* Koordinaten aller Punkte, die Endpunkt eines Pfeils sind (hier ist ggf.
* eine Spitze zu zeichnen). Dazu geh�rt ein entsprechender Anfangspunkt.
*/
private ArrayList<Point> pfeilEndpunkte;
/**
* Die St�rke eines Pfeils.
*/
private ArrayList<Double> staerken;
/**
* Ob der Pfeil gebogen sein soll.
*/
private ArrayList<Boolean> gebogen;
/**
* Liste von Strings, die in der Grafik platziert werden. Dazu geh�rt eine
* Koordinate.
*/
private ArrayList<String> beschriftungen;
/**
* Koordinaten der linken untere Ecke eines Strings. Dazu geh�rt ein
* String.
*/
private ArrayList<Point> beschrKoordinaten;
/**
* Assoziationen der Beschriftungen zu Kanten (oder Knoten?).
*/
private ArrayList<Polygon> beschrAssoz;
/**
* Konstruktor, der alle Attribute initialisiert.
*/
public DargestellterGraph() {
this.beschriftungen = new ArrayList<String>();
this.beschrKoordinaten = new ArrayList<Point>();
this.knotenpunktKoord = new ArrayList<Point>();
this.knotenpunktObjekte = new ArrayList<Knoten>();
this.pfeilEndpunkte = new ArrayList<Point>();
this.pfeilUrspruenge = new ArrayList<Point>();
this.beschrAssoz = new ArrayList<Polygon>();
this.staerken = new ArrayList<Double>();
this.gebogen = new ArrayList<Boolean>();
this.selektiert = -1;
}
/**
* Gibt die Liste der Knotenkoordinaten zur�ck.
*
* @return Die Liste der Knotenkoordinaten.
*/
public ArrayList<Point> holeKnotenKoord() {
return this.knotenpunktKoord;
}
/**
* Gibt die Liste der Knotenobjekte zur�ck.
*
* @return Die Liste der Knotenobjekte.
*/
public ArrayList<Knoten> holeKnotenObj() {
return this.knotenpunktObjekte;
}
/**
* Gibt die Liste der Pfeilursprungskoordinaten zur�ck.
*
* @return Die Liste der Pfeilursprungskoordinaten.
*/
public ArrayList<Point> holePfeilUrspr() {
return this.pfeilUrspruenge;
}
/**
* Gibt die Liste der Pfeilendkoordinaten zur�ck.
*
* @return Die Liste der Pfeilendkoordinaten.
*/
public ArrayList<Point> holePfeilEnd() {
return this.pfeilEndpunkte;
}
/**
* Gibt die Liste der Pfeilst�rken zur�ck.
*
* @return Die Liste der Pfeilst�rken.
*/
public ArrayList<Double> holePfeilStaerken() {
return this.staerken;
}
/**
* Gibt die Liste der Pfeilbiegungen zur�ck.
*
* @return Die Liste der Pfeilbiegungen.
*/
public ArrayList<Boolean> holePfeilBiegung() {
return this.gebogen;
}
/**
* Gibt die Liste der Beschriftungen zur�ck.
*
* @return Die Liste der Beschriftungen.
*/
public ArrayList<String> holeBeschr() {
return this.beschriftungen;
}
/**
* Gibt zur�ck, welches Objekt mit der Beschriftung assoziiert ist.
*
* @param beschr String der Beschriftung.
*
* @return Assoziation, die zu der Beschriftung geh�rt. Falls es keine
* gibt, wird <code>null</code> zur�ckgegeben.
*/
public Polygon holeAssoz(final String beschr) {
int i = 0;
while (i < this.beschriftungen.size()) {
if (this.beschriftungen.get(i) == beschr) {
return this.beschrAssoz.get(i);
}
i++;
}
return null;
}
/**
* Gibt die Liste der Beschriftungskoordinaten zur�ck.
*
* @return Die Liste der Beschriftungskoordinaten.
*/
public ArrayList<Point> holeBeschrKoord() {
return this.beschrKoordinaten;
}
// /**
// * F�gt der Liste der Knotenkoordinaten einen neuen Punkt hinzu und
// * assoziiert in der Liste der Knotenobjekte <code>obj</code> damit.
// *
// * @param x X-Koordinate des neuen Knotenpunktes.
// * @param y Y-Koordinate des neuen Knotenpunktes.
// * @param obj Das Objekt, welches zu diesen Koordinaten geh�rt.
// */
// public void hinzuKnoten(final int x,
// final int y,
// final Object obj) {
// final Point p = new Point(x, y);
// this.knotenpunktKoord.add(p);
// this.knotenpunktObjekte.add(obj);
// }
/**
* F�gt der Liste der Knotenkoordinaten einen neuen Punkt hinzu und
* assoziiert in der Liste der Knotenobjekte <code>obj</code> damit.
*
* @param x X-Koordinate des neuen Knotenpunktes.
* @param y Y-Koordinate des neuen Knotenpunktes.
* @param obj Das Objekt, welches zu diesen Koordinaten geh�rt.
* @param sel Gibt an, ob der Knoten selektiert ist.
*/
public void hinzuKnoten(final int x,
final int y,
final Knoten obj,
final boolean sel) {
final Point p = new Point(x, y);
this.knotenpunktKoord.add(p);
this.knotenpunktObjekte.add(obj);
if (sel) {
this.selektiert = this.knotenpunktKoord.size() - 1;
}
}
/**
* F�gt einen neuen Pfeil hinzu, das hei�t es wird ein neuer Pfeilursprung
* und ein neues Pfeilende in die entsprechenden Listen eingef�gt.
*
* @param x1 X-Koordinate des Anfangspunktes.
* @param y1 Y-Koordinate des Anfangspunktes.
* @param x2 X-Koordinate des Endpunktes.
* @param y2 Y-Koordinate des Endpunktes.
* @param staerke Die St�rke des Pfeils.
* @param gebogenerPfeil Ob der Pfeil gebogen sein soll / darf.
*/
public void hinzuPfeil(final int x1, final int y1,
final int x2, final int y2,
final double staerke,
final boolean gebogenerPfeil) {
final Point p1 = new Point(x1, y1);
final Point p2 = new Point(x2, y2);
this.pfeilUrspruenge.add(p1);
this.pfeilEndpunkte.add(p2);
this.staerken.add(staerke);
this.gebogen.add(gebogenerPfeil);
}
/**
* F�gt eine Beschriftung hinzu, das hei�t es wird eine neue Beschriftung
* und ein Koordinatenpunkt in die entsprechenden Listen eingef�gt.
*
* @param x Linke untere X-Koordinate des Strings.
* @param y Linke untere Y-Koordinate des Strings.
* @param s Darzustellender String.
*/
public void hinzuBeschr(final int x, final int y, final String s) {
// final Point p = new Point(x, y);
//
// this.beschriftungen.add(s);
// this.beschrKoordinaten.add(p);
this.hinzuBeschr(x, y, s, null);
}
/**
* F�gt eine Beschriftung hinzu, das hei�t es wird eine neue Beschriftung
* und ein Koordinatenpunkt in die entsprechenden Listen eingef�gt.
* Die Beschriftung wird zus�tzlich mit einer Kante assoziiert.
*
* @param x Linke untere X-Koordinate des Strings.
* @param y Linke untere Y-Koordinate des Strings.
* @param s Darzustellender String.
* @param p Polygon aus 2 Punkten; der erste stellt den Anfangspunkt,
* der zweite den Endpunkt der Kante dar.
*/
public void hinzuBeschr(final int x,
final int y,
final String s,
final Polygon p) {
final Point pt = new Point(x, y);
this.beschriftungen.add(s);
this.beschrKoordinaten.add(pt);
this.beschrAssoz.add(p);
}
/**
* Gibt eine Liste aller Knoten zur�ck (das sind die Knotenobjekte selbst,
* im Unterschied dazu wird in der Methode holeUmPkt eine Liste der
* Koordinaten aller Knoten erzeugt), die sich in einem Rechteck der
* Seitenl�nge <code>2 * radius</code> um <code>x</code> und <code>y</code>
* befinden UND den minimalen Abstand zu <code>x</code> und <code>y</code>
* haben. Der Abstand ist dabei definiert durch den Satz des Pythagoras.
*
* @param x X-Koordinate des Mittelpunkts des Rechtecks.
* @param y Y-Koordinate des Mittelpunkts des Rechtecks.
* @param radius Gr��e des Rechtecks, aus welchem alle Punkte
* zur�ckgegeben werden sollen.
*
* @return Die Knoten innerhalb des oben beschriebenen Rechtecks.
*/
public ArrayList<Knoten> holeUmObj(final int x,
final int y,
final double radius) {
final ArrayList<Knoten> knotenListe = new ArrayList<Knoten>();
final ArrayList<Point> koordListe = new ArrayList<Point>();
final ArrayList<Knoten> endListe = new ArrayList<Knoten>();
Point aktPunkt;
Knoten aktObj;
Iterator<Point> itKoord;
Iterator<Knoten> itObj;
double minAbs = Double.MAX_VALUE;
double aktAbs;
final double dX = (double) x;
final double dY = (double) y;
double dXAkt;
double dYAkt;
// Erzeuge Liste der Knoten in Rechteck
itKoord = this.knotenpunktKoord.iterator();
itObj = this.knotenpunktObjekte.iterator();
while (itKoord.hasNext() && itObj.hasNext()) {
aktPunkt = (Point) itKoord.next();
aktObj = itObj.next();
if (Math.abs(aktPunkt.x - x) <= radius
&& Math.abs(aktPunkt.y - y) <= radius) {
dXAkt = (double) aktPunkt.x;
dYAkt = (double) aktPunkt.y;
aktAbs = Math.sqrt(Math.pow(dX - dXAkt, 2)
+ Math.pow(dY - dYAkt, 2));
if (aktAbs < minAbs) {
minAbs = aktAbs;
knotenListe.add(aktObj);
koordListe.add(aktPunkt);
}
}
}
// Erzeuge Liste der Knoten mit minimalem Abstand zum angeg. Punkt.
itKoord = koordListe.iterator();
itObj = knotenListe.iterator();
while (itKoord.hasNext() && itObj.hasNext()) {
aktPunkt = (Point) itKoord.next();
aktObj = itObj.next();
dXAkt = (double) aktPunkt.x;
dYAkt = (double) aktPunkt.y;
aktAbs = Math.sqrt(Math.pow(dX - dXAkt, 2)
+ Math.pow(dY - dYAkt, 2));
if (aktAbs <= minAbs) {
endListe.add(aktObj);
}
}
return endListe;
}
/**
* Gibt eine Liste aller Punkte zur�ck, die sich in einem Rechteck der
* Seitenl�nge <code>2 * radius</code> um <code>x</code> und <code>y</code>
* befinden.
*
* @param x X-Koordinate des Mittelpunkts des Rechtecks.
* @param y Y-Koordinate des Mittelpunkts des Rechtecks.
* @param radius Gr��e des Rechtecks, aus welchem alle Punkte
* zur�ckgegeben werden sollen.
*
* @return Die Punkte innerhalb des oben beschriebenen Rechtecks.
*/
public ArrayList<Point> holeUmPkt(final int x,
final int y,
final double radius) {
final ArrayList<Point> knotenListe = new ArrayList<Point>();
Point aktPunkt;
final Iterator<Point> itKoord;
itKoord = this.knotenpunktKoord.iterator();
while (itKoord.hasNext()) {
aktPunkt = (Point) itKoord.next();
if (Math.abs(aktPunkt.x - x) <= radius
&& Math.abs(aktPunkt.y - y) <= radius) {
knotenListe.add(aktPunkt);
}
}
return knotenListe;
}
/**
* Gibt zur�ck, ob sich p innerhalb des Rechtecks mit den Eckpunkten
* (x1, y1), (x2, y2) befindet.
*
* @param p Zu untersuchender Punkt.
* @param x1 X-Koordinate des ersten Ecks.
* @param y1 Y-Koordinate des ersten Ecks.
* @param x2 X-Koordinate des zweiten Ecks.
* @param y2 Y-Koordinate des zweiten Ecks.
*
* @return True genau dann, wenn p innerhalb des Rechtecks ist.
*/
private boolean inRechteck(final Point p,
final int x1,
final int y1,
final int x2,
final int y2) {
return ((p.x >= x1 && p.x <= x2) || (p.x <= x1 && p.x >= x2))
&& ((p.y >= y1 && p.y <= y2) || (p.y <= y1 && p.y >= y2));
}
/**
* Gibt eine Liste aller Knoten zur�ck, die sich in dem Rechteck, das
* durch die vier Parameter angegeben ist, befinden.
*
* @param x1 X-Koordinate des ersten Ecks des Rechtecks.
* @param y1 Y-Koordinate des ersten Ecks des Rechtecks.
* @param x2 X-Koordinate des zweiten Ecks des Rechtecks.
* @param y2 Y-Koordinate des zweiten Ecks des Rechtecks.
*
* @return Die Knoten innerhalb des oben beschriebenen Rechtecks.
*/
public ArrayList<Knoten> holeRechteck(final int x1,
final int y1,
final int x2,
final int y2) {
final ArrayList<Knoten> knotenListe = new ArrayList<Knoten>();
Point aktPunkt;
Knoten aktObj;
final Iterator<Point> itKoord;
final Iterator<Knoten> itObj;
itKoord = this.knotenpunktKoord.iterator();
itObj = this.knotenpunktObjekte.iterator();
while (itKoord.hasNext() && itObj.hasNext()) {
aktPunkt = (Point) itKoord.next();
aktObj = itObj.next();
if (this.inRechteck(aktPunkt, x1, y1, x2, y2)) {
knotenListe.add(aktObj);
}
}
return knotenListe;
}
/**
* Gibt zur�ck, ob das Objekt selektiert ist.
*
* @param obj Das zu untersuchende Objekt.
*
* @return Ob das Objekt selektiert ist.
*/
public boolean getSelektiert(final Object obj) {
return this.selektiert == this.knotenpunktObjekte.indexOf(obj);
}
/**
* Gibt zur�ck, ob ein Pfeil von (x1, y1) nach (x2, y2) vorhanden ist.
*
* @param x1 Ursprungs-X-Koordinate.
* @param y1 Ursprungs-Y-Koordinate.
* @param x2 Ziel-X-Koordinate.
* @param y2 Ziel-Y-Koordinate.
*
* @return <code>true</code>, gdw. ein Pfeil von Ursprung nach Ziel
* vorhanden ist.
*/
public boolean enthaeltPfeil(final int x1,
final int y1,
final int x2,
final int y2) {
Point p1 = new Point(x1, y1);
Point p2 = new Point(x2, y2);
int i = 0;
while (i < this.pfeilUrspruenge.size()) {
if (p1.equals(this.pfeilUrspruenge.get(i))) {
if (p2.equals(this.pfeilEndpunkte.get(i))) {
return true;
}
}
i++;
}
return false;
}
}