double schrittY;
double dicke = 2;
ArrowMaster master = new ArrowMaster(params);
LinkedList<Object> zeichenObjekte = new LinkedList<Object>();
AusgMerkm[] merkmale = new AusgMerkm[2];
merkmale[0] = new AusgMerkm(Color.black, Color.black, true, true);
merkmale[1] = new AusgMerkm(Color.white, Color.white, false, false);
Polygon2D rahmen = new Polygon2D();
Polygon2D balkenOben = new Polygon2D();
Polygon2D balkenUnten = new Polygon2D();
Polygon2D durchschnitt;
double strichweiteX = 25;
int glAbst = 50; // TODO: Gleitender Durchschnitt.
if (werte == null || werte.size() == 0) {
return null;
}
// Maxima suchen:
for (ArrayList<Double> liste : werte) {
if (maxX < 0) {
maxX = liste.size();
}
if (maxX != liste.size()) {
throw new RuntimeException("Listen haben ungleiche Länge.");
}
for (double d : liste) {
if (d > maxY) {
maxY = d;
}
if (d < minY) {
minY = d;
}
}
}
// Falls Fitnesswerte alle auf einer Konstanten liegen:
if (Math.abs(maxY - minY) < 0.0000001) {
maxY = minY + 0.0000001;
}
rahmen.add(new Vector2D(0, 0));
rahmen.add(new Vector2D(0, hoehe));
rahmen.add(new Vector2D(breite, hoehe));
rahmen.add(new Vector2D(breite, 0));
balkenOben.add(new Vector2D(0, -1));
balkenOben.add(new Vector2D(breite, -1));
balkenOben.add(new Vector2D(breite, -60));
balkenOben.add(new Vector2D(0, -60));
balkenUnten.add(new Vector2D(0, hoehe + 1));
balkenUnten.add(new Vector2D(breite, hoehe + 1));
balkenUnten.add(new Vector2D(breite, hoehe + 60));
balkenUnten.add(new Vector2D(0, hoehe + 60));
schrittX = breite / maxX;
schrittY = hoehe / (maxY - minY);
// Nulllinie:
ArrayList<Double> dicken = new ArrayList<Double>(
(int) Math.round(maxX) + 1);
zeichenObjekte.add(
new AusgMerkm(Color.black, Color.black, true, true));
Polygon2D nulllinie = new Polygon2D();
nulllinie.add(new Vector2D(0, hoehe - (0 - minY) * schrittY));
nulllinie.add(new Vector2D(breite, hoehe - (0 - minY) * schrittY));
Polygon nullPol = master.segmentPfeilPol(
nulllinie,
null,
ArrowMaster.EINFACHER_ABSCHLUSS,
ArrowMaster.EINFACHER_ABSCHLUSS,
new Vector2D(1, 1),
new Vector2D(1, 1),
1,
Vector2D.NULL_VECTOR);
// Einzelne Werte.
zeichenObjekte.add(
new AusgMerkm(Color.LIGHT_GRAY, Color.LIGHT_GRAY, true, true));
for (ArrayList<Double> liste : werte) {
Polygon2D pol = new Polygon2D();
dicken = new ArrayList<Double>(liste.size() + 1);
// Pol2DMitAusgMerkm[] gestrichelt;
double x = 0;
for (double d : liste) {
pol.add(new Vector2D(x, hoehe - (d - minY) * schrittY));
x += schrittX;
}
// pol = pol.normalisiere();
for (int i = 0; i < pol.nPoints(); i++) {
dicken.add(dicke);
}
// gestrichelt = master.gestrichelterPfeil(
// pol,
// dicken,
// PfeilMaster.EINFACHER_ABSCHLUSS,
// PfeilMaster.EINFACHER_ABSCHLUSS,
// new Vektor2D(1, 1),
// new Vektor2D(1, 1),
// merkmale,
// 10000,
// params);
pol = master.segmentPfeilPol2D(
pol,
dicken,
ArrowMaster.EINFACHER_ABSCHLUSS,
ArrowMaster.EINFACHER_ABSCHLUSS,
new Vector2D(1, 1),
new Vector2D(1, 1));
zeichenObjekte.add(pol.toPol());
// for (Pol2DMitAusgMerkm pa : gestrichelt) {
// if (pa != null) {
// zeichenObjekte.add(pa.getAusg());
// zeichenObjekte.add(pa.getPol().toPol());
// }
// }
}
// Durchschnittslinie:
double maxDurch = Double.MIN_VALUE;
double maxGleit = Double.MIN_VALUE;
zeichenObjekte.add(
new AusgMerkm(
Color.black,
new Color(185, 0, 0),
true,
true));
durchschnitt = new Polygon2D();
dicken = new ArrayList<Double>(
(int) Math.round(maxX) + 1);
double x = 0;
for (int i = 0; i < maxX; i++) {
double durchWert = 0;
for (ArrayList<Double> liste : werte) {
durchWert += liste.get(i);
}
durchWert /= werte.size();
if (maxDurch < durchWert) {
maxDurch = durchWert;
}
durchschnitt.add(new Vector2D(x, hoehe - (durchWert - minY) * schrittY));
x += schrittX;
}
// durchschnitt = durchschnitt.normalisiere();
for (int i = 0; i < durchschnitt.nPoints(); i++) {
dicken.add(dicke * 2);
}
Polygon durchPol = master.segmentPfeilPol(
durchschnitt,
dicken,
ArrowMaster.EINFACHER_ABSCHLUSS,
ArrowMaster.EINFACHER_ABSCHLUSS,
new Vector2D(1, 1),
new Vector2D(1, 1),
1,
Vector2D.NULL_VECTOR);
zeichenObjekte.add(durchPol);
// Gleitender Durchschnitt.
ArrayList<Double> durch = new ArrayList<Double>(werte.get(0).size());
ArrayList<Double> dickenGleit = new ArrayList<Double>(durch.size());
for (int i = 0; i < maxX; i++) { // Durchschnitt.
double durchWert = 0;
for (ArrayList<Double> liste : werte) {
durchWert += liste.get(i);
}
durch.add(durchWert / werte.size());
}
ArrayList<Double> gleit = MiscMath.glDurchSchn(durch, glAbst);
// Maximum suchen.
for (double d : gleit) {
if (d > maxGleit) {
maxGleit = d;
}
}
Polygon2D gleitPol = new Polygon2D();
x = schrittX * glAbst;
for (double glWert : gleit) {
gleitPol.add(new Vector2D(x, hoehe - (glWert - minY) * schrittY));
dickenGleit.add(dicke * 4);
x += schrittX;
}
Polygon gleitP = master.segmentPfeilPol(
gleitPol,
dickenGleit,
ArrowMaster.EINFACHER_ABSCHLUSS,
ArrowMaster.EINFACHER_ABSCHLUSS,
new Vector2D(1, 1),
new Vector2D(1, 1),
1,
Vector2D.NULL_VECTOR);
zeichenObjekte.add(
new AusgMerkm(Color.white, Color.black, true, true));
zeichenObjekte.add(gleitP);
// Umrisse und Linien:
zeichenObjekte.add(
new AusgMerkm(Color.white, Color.white, true, true));
zeichenObjekte.add(balkenOben.toPol());
zeichenObjekte.add(balkenUnten.toPol());
zeichenObjekte.add(
new AusgMerkm(Color.black, Color.white, true, false));
zeichenObjekte.add(rahmen.toPol());
zeichenObjekte.add(nullPol);
// Beschriftungen:
if (beschriftungen != null) {
Polygon2D strichPol2D;
Polygon strichPol;
zeichenObjekte.add(new AusgMerkm(
Color.black,
Color.black,
true,
true,
"",
0,
20));
for (double d = 0; d < maxX; d += strichweiteX) {
strichPol2D = new Polygon2D();
dicken = new ArrayList<Double>(2);
strichPol2D.add(new Vector2D(d * schrittX, hoehe - 5));
strichPol2D.add(new Vector2D(d * schrittX, hoehe + 5));
dicken.add(dicke);
dicken.add(dicke);
strichPol = master.segmentPfeilPol(
strichPol2D,
dicken,
ArrowMaster.EINFACHER_ABSCHLUSS,
ArrowMaster.EINFACHER_ABSCHLUSS,
new Vector2D(1, 1),
new Vector2D(1, 1),
1,
Vector2D.NULL_VECTOR);
zeichenObjekte.add((int) (d * schrittX));
zeichenObjekte.add((int) (hoehe + 25));
zeichenObjekte.add(
beschriftungen.get((int) (d)));
zeichenObjekte.add(strichPol);
}
zeichenObjekte.add(0);
zeichenObjekte.add(-10);
zeichenObjekte.add("" + maxY);
// überschrift:
zeichenObjekte.add(0);
zeichenObjekte.add(-40);
zeichenObjekte.add(
ueberschrift
+ " (MaxDurch: "
+ maxDurch
+ " / MaxGleit: "
+ maxGleit
+ ")");
}
// Güte (muss zuletzt kommen!):
if (gueteTest.guteGuete(gleit)) {
zeichenObjekte.add(new AusgMerkm(
Color.red,
Color.red,
true,
true,
"",