Package eas.startSetup.arrowGUI

Source Code of eas.startSetup.arrowGUI.ZeichFen

/*
* Datei:          ZeichFen.java
* Autor(en):      Lukas König
* Java-Version:   6.0
* Erstellt (vor): 14.11.2008
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
*   author or licensor (but not in any way that suggests that they endorse
*   you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
*   distribute the resulting work only under the same or a similar license to
*   this one.
*
* + Detailed license conditions (Germany):
*   http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
*   http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/

package eas.startSetup.arrowGUI;

import eas.math.geometry.Circle2D;
import eas.math.geometry.Geometry2D;
import eas.math.geometry.Polygon2D;
import eas.math.geometry.Vector2D;
import eas.miscellaneous.StaticMethods;
import eas.startSetup.ParCollection;
import eas.startSetup.marbBuilder.zeichenModi.AusgMerkm;
import eas.startSetup.marbBuilder.zeichenModi.ArrowMaster;
import eas.startSetup.marbBuilder.zeichenModi.Pfeilspitze;
import eas.startSetup.marbBuilder.zeichenModi.Pol2DMitAusgMerkm;
import eas.startSetup.marbBuilder.zeichenModi.SegSpez;
import eas.statistics.logging.AbstractMsg;
import eas.statistics.logging.MsgError;
import eas.statistics.logging.MsgWarning;

import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;


/**
* Applet zur Visualisierung eines Graphen.
*
* @author Lukas König.
*/
public class ZeichFen extends Frame implements MouseWheelListener {

    /**
     * Am 14.09.06 generiert.
     */
    private static final long serialVersionUID = -4078048087117840970L;

    /**
     * Objekt, das die Polygone (u. �.) zur Darstellung eines Graphen erzeugt.
     */
    private ArrowMaster zeichenArt;

    /**
     * Die benutzerdefinierten Segmentbeschreibungen.
     */
    private LinkedList<SegSpez> userSegs;
   
    /**
     * Der Name des von <code>this</code> dargestellten Graphen.
     */
    private String robName;

    /**
     * Die Dicken.
     */
    private ArrayList<Double> dicken = new ArrayList<Double>();

    /**
     * Der Anfang des Pfeils.
     */
    private Pfeilspitze anfang;
   
    /**
     * Das Ende des Pfeils.
     */
    private Pfeilspitze ende;

    /**
     * Multiplikativer Faktor für die Größe des Pfeilanfangs.
     */
    private double anfFakt;
   
    /**
     * Multiplikativer Faktor für die Größe des Pfeilendes.
     */
    private double endFakt;
   
    /**
     * Die Parameter.
     */
    private ParCollection pars;
   
    /**
     * Die ID.
     */
    private int id;
   
    /**
     * Das Pfeilpolygon.
     */
    private Polygon2D pfeilPol;
   
    /**
     * Ob die Eckpunkte markiert werden sollen.
     */
    private boolean markiereEcken = true;
   
    /**
     * Ob der Grundpfeil gezeichnet werden soll.
     */
    private boolean zeichneGrundPfeil = true;
   
    /**
     * @return Returns the id.
     */
    public int getId() {
        return this.id;
    }

    /**
     * Der angeklickte Punkt.
     */
    private Vector2D vekClick;
   
    /**
     * Die aktuelle Dicke.
     */
    private double aktDicke;
   
    /**
     * Der erste markierte Knoten.
     */
    private Integer mark1;
   
    /**
     * Der zweite markierte Knoten.
     */
    private Integer mark2;

    /**
     * Die Segmentbeschreibungen.
     */
    private SegSpez[] segBeschr;
   
    /**
     * Erste Ecke.
     */
    private Vector2D ersteEcke;

    /**
     * Zweite Ecke.
     */
    private Vector2D zweiteEcke;

    /**
     * beliebig Große Liste von markierten Knoten.
     */
    private LinkedList<Integer> markierte;
   
    /**
     * Die Stufe des zuletzt aufgetretenen Fehlers.
     */
    private int fehlerStufe = 0;

    /**
     * Die Skalierung im Verhältnis zur Normskalierung der Zeichenfl�che.
     */
    private double skalierung;
   
    /**
     * Die Verschiebung der Grafik.
     */
    private Vector2D verschiebung;
   
    /**
     * Größe der Strichelung.
     */
    private double gestrichelt;
   
    /**
     * Das Elternpfeilcontroller-Fenster.
     */
    private PfeilController elternMaster;
   
    /**
     * Die Ausgabemerkmale des gestrichelten Pfeils.
     */
    private AusgMerkm[] gestricheltMerkm;
   
    /**
     * Ob der Punkt im PfeilPol enthalten ist.
     *
     * @param vek  Der Punkt.
     *
     * @return  null oder Zeiger auf das enthaltene Objekt.
     */
    private Vector2D containsPoint(final Vector2D vek) {
        final double epsilon = 5 / this.skalierung;
       
        for (Vector2D v : this.pfeilPol) {
            if (v.distance(vek) <= epsilon) {
                return v;
            }
        }

        return null;
    }
   
    /**
     * Implementierung eines überschriebenen Konstruktors. Die Graphen werden
     * von der Festplatte geladen.
     *
     * @param fenstertitel  Der als Titel anzuzeigende String.
     * @param graphNam      Der Name des aktuellen Graphen.
     *                      Visualisierung gehört.
     * @param params        Der Parametersatz.
     * @param ident         Die Identit�tsnummer.
     * @param vater         Der Pfeilmastervater.
     */
    public ZeichFen(
            final String fenstertitel,
            final ParCollection params,
            final PfeilController vater) {

        super(fenstertitel);
      
        this.gestrichelt = 0;
        this.ende = ArrowMaster.KUGEL_ENDE;
        this.anfang = ArrowMaster.EINFACHE_SPITZE_1;
        this.anfFakt = 1;
        this.endFakt = 1;
      
        this.gestricheltMerkm = new AusgMerkm[2];
        this.gestricheltMerkm[0] = new AusgMerkm(
                Color.black,
                Color.blue,
                true,
                true);
        this.gestricheltMerkm[1] = new AusgMerkm(
                Color.black,
                Color.yellow,
                true,
                true);
       
        this.elternMaster = vater;
        this.elternMaster.setzeSegmentFarben(this.gestricheltMerkm);
       
        this.skalierung = 1;
        this.verschiebung = new Vector2D(Vector2D.NULL_VECTOR);
       
        this.markierte = new LinkedList<Integer>();
        this.userSegs = new LinkedList<SegSpez>();
        this.setSize(750, 700);
       
        this.aktDicke = eas.startSetup.marbBuilder.zeichenModi.ConstantsZeichenModi.PFEIL_DICKE;
        this.pfeilPol = new Polygon2D();
        this.pars = params;
        this.zeichenArt = new ArrowMaster(this.pars);
        this.segBeschr = new SegSpez[1000];
       
        this.addMouseWheelListener(this);
       
        this.addComponentListener(new ComponentListener() {
            @Override
            public void componentHidden(final ComponentEvent e) {

            }

            @Override
            public void componentMoved(final ComponentEvent e) {

            }

            @Override
            public void componentResized(final ComponentEvent e) {
                ZeichFen.this.neuZeichnen();
            }

            @Override
            public void componentShown(final ComponentEvent e) {
               
            }
        }
        );

        this.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(final MouseEvent event) {
                Vector2D vek = new Vector2D(
                        (event.getX() - verschiebung.x) / skalierung,
                        (event.getY() - verschiebung.y) / skalierung);
                Vector2D neu;

                if (ZeichFen.this.vekClick != null) {
                    for (int i = 0; i < ZeichFen.this.pfeilPol.nPoints(); i++) {
                        if (ZeichFen.this.markierte.contains(i)) {
                           
                            neu = new Vector2D(ZeichFen.this.pfeilPol.get(i));
                            neu.translate(vek);
                            neu.sub(ZeichFen.this.ersteEcke);
                           
                            ZeichFen.this.pfeilPol.set(i, neu);
                        }
                    }
                   
                    ZeichFen.this.vekClick
                        = ZeichFen.this.containsPoint(vek);

                    ZeichFen.this.ersteEcke = vek;
                   
                    ZeichFen.this.neuZeichnen();
                } else {
                    ZeichFen.this.zweiteEcke
                        = new Vector2D(
                                (event.getX() - verschiebung.x) / skalierung,
                                (event.getY() - verschiebung.y) / skalierung);
                   
                    ZeichFen.this.neuZeichnen();
                }
            }
        });

        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(final MouseEvent event) {
                Vector2D vek = new Vector2D(
                        (event.getX() - verschiebung.x) / skalierung,
                        (event.getY() - verschiebung.y) / skalierung);
               
                ZeichFen.this.ersteEcke = new Vector2D(vek);
               
                ZeichFen.this.vekClick
                    = ZeichFen.this.containsPoint(vek);
               
                ZeichFen.this.mark1 = ZeichFen.this.mark2;
                ZeichFen.this.mark2 = ZeichFen.this.pfeilPol.realIndexOf(
                        ZeichFen.this.vekClick);
               
                if (ZeichFen.this.mark1 != null
                        && ZeichFen.this.mark1 < 0) {
                    ZeichFen.this.mark1 = null;
                }
                if (ZeichFen.this.mark2 != null
                        && ZeichFen.this.mark2 < 0) {
                    ZeichFen.this.mark2 = null;
                }
               
                if (ZeichFen.this.mark1 != null
                        && !ZeichFen.this.markierte.contains(
                                ZeichFen.this.mark1)) {
                    ZeichFen.this.markierte.add(ZeichFen.this.mark1);
                }
                if (ZeichFen.this.mark2 != null
                        && !ZeichFen.this.markierte.contains(
                                ZeichFen.this.mark2)) {
                    ZeichFen.this.markierte.add(ZeichFen.this.mark2);
                }
            }
           
            @Override
            public void mouseClicked(final MouseEvent event) {
                Vector2D vek = new Vector2D(
                        (event.getX() - verschiebung.x) / skalierung,
                        (event.getY() - verschiebung.y) / skalierung);

                if (event.getButton() == 3) {
                    skaliere();
                    zentriere();
                    return;
                }
               
                if (ZeichFen.this.containsPoint(vek) == null
                        && (ZeichFen.this.mark1 != null
                        || ZeichFen.this.mark2 != null
                        || ZeichFen.this.markierte.size() > 0)) {
                    ZeichFen.this.markierte.clear();
                    ZeichFen.this.mark1 = null;
                    ZeichFen.this.mark2 = null;
                } else {
                    if (ZeichFen.this.vekClick == null
                            && event.getClickCount() >= 2) {
                        ZeichFen.this.pfeilPol.add(new Vector2D(vek));
                        ZeichFen.this.dicken.add(ZeichFen.this.aktDicke);
                    }
                }
            }
           
            @Override
            public void mouseReleased(final MouseEvent event) {
                if (ZeichFen.this.ersteEcke != null
                        && ZeichFen.this.zweiteEcke != null) {

                    ZeichFen.this.mark1 = null;
                    ZeichFen.this.mark2 = null;
                   
                    ZeichFen.this.markierte.clear();
                   
                    for (Vector2D v : ZeichFen.this.pfeilPol) {
                        if (v.isWithinRectangle(
                                ZeichFen.this.ersteEcke,
                                ZeichFen.this.zweiteEcke)) {
                           
                            ZeichFen.this.markierte.add(
                                    ZeichFen.this.pfeilPol.realIndexOf(v));
                        }
                    }
                }

                Collections.sort(ZeichFen.this.markierte, new IntComp());

                if (ZeichFen.this.markierte.size() > 0) {
                    if (ZeichFen.this.mark1 == null) {
                        ZeichFen.this.mark1 = ZeichFen.this.markierte.get(0);
                    }
                   
                    if (ZeichFen.this.mark2 == null) {
                        ZeichFen.this.mark2 = ZeichFen.this.markierte.get(
                                ZeichFen.this.markierte.size() - 1);
                    }
                }

                ZeichFen.this.ersteEcke = null;
                ZeichFen.this.zweiteEcke = null;
                ZeichFen.this.neuZeichnen();
            }
        });

        this.addKeyListener(new KeyListener() {

            /**
             * Die Key-Typed-Methode.
             */
            @Override
            public void keyTyped(final KeyEvent e) {
                // throw new RuntimeException("Taste wurde gedrückt.");
            }

            /**
             * Die Key-Released-Methode.
             */
            @Override
            public void keyReleased(final KeyEvent e) {
                // throw new RuntimeException("Taste wurde losgelassen.");
            }

            /**
             * Die Key-Pressed-Methode.
             */
            @Override
            public void keyPressed(final KeyEvent e) {
                ZeichFen.this.printPolygonCode();

                if (e.getKeyCode() == java.awt.event.KeyEvent.VK_C) {
                    if (e.isControlDown()) {
                        StaticMethods.log(
                                StaticMethods.LOG_DEBUG,
                                "STRG-C",
                                ZeichFen.this.pars);
                    }
                }

                if (e.getKeyCode() == java.awt.event.KeyEvent.VK_V) {
                    if (e.isControlDown()) {
                        StaticMethods.log(
                                StaticMethods.LOG_DEBUG,
                                "STRG-V",
                                ZeichFen.this.pars);
                    }
                }

                if (e.getKeyCode() == java.awt.event.KeyEvent.VK_A) {
                    if (e.isControlDown()) {
                        ZeichFen.this.markiereAlle();
                        ZeichFen.this.neuZeichnen();
                    }
                }

                if (e.getKeyChar() == KeyEvent.VK_DELETE) {
                    ZeichFen.this.deleteMark();
                    ZeichFen.this.neuZeichnen();
                }
            }
        });
    }
   
    /**
     * Markiert alle Knoten.
     */
    public void markiereAlle() {
        for (int i = 0; i < this.pfeilPol.nPoints(); i++) {
            this.markierte.add(i);
        }
       
        Collections.sort(this.markierte, new IntComp());
       
        if (this.markierte.size() > 0) {
            this.mark1 = this.markierte.get(0);
            this.mark2 = this.markierte.get(this.markierte.size() - 1);
        }
    }
   
    /**
     * löscht alle markierten Knoten.
     */
    public void deleteMark() {
        for (int i : this.markierte) {
            this.pfeilPol.remove(i);
           
            for (int j = 0; j < this.markierte.size(); j++) {
                if (this.markierte.get(j) >= i) {
                    this.markierte.set(j, this.markierte.get(j) - 1);
                }
            }
        }
       
        this.mark1 = null;
        this.mark2 = null;
        this.markierte.clear();
       
        if (this.pfeilPol.nPoints() <= 1) {
            this.loescheSegs();
        } else {
            for (SegSpez s : this.segBeschr) {
                if (s != null && s.getBeginn() >= this.pfeilPol.nPoints()) {
                    s.setBeginn(this.pfeilPol.nPoints() - 1);
                }
                if (s != null && s.getEnde() >= this.pfeilPol.nPoints()) {
                    s.setEnde(this.pfeilPol.nPoints() - 1);
                }
            }
        }
    }
   
    /**
     * Normalisieren.
     */
    public void normalisiere() {
        this.pfeilPol = this.pfeilPol.normalize(this.pars);
        if (this.dicken.size() < this.pfeilPol.nPoints()) {
            this.dicken.add(this.dicken.get(this.dicken.size() - 1));
        }
    }
   
    /**
     * Zeichnet den Graphen neu mit Löschen des Bildschirms.
     */
    public void neuZeichnen() {
        this.fehlerStufe = 0;
        this.repaint();
    }

    /**
     * Zeichnet den Graphen neu mit Löschen des Bildschirms.
     *
     * @param fehler  Die Fehlerstufe.
     */
    public void neuZeichnen(final int fehler) {
        this.fehlerStufe = fehler;
        this.repaint();
    }

    /**
     * Setzt einen String, aber berücksichtigt das Kontrollzeichen '\n'.
     *
     * @param g
     *            Das Grafikobjekt.
     * @param s
     *            Der String.
     * @param x
     *            X-Koordinate.
     * @param y
     *            Y-Koordinate.
     */
    public void setzeString(final Graphics g, final String s, final int x,
            final int y) {

        int returnPos;
        String schreibe;
        String rest;
        Font font;

        if (s.length() > 0) {
            font = g.getFont();
            g.setFont(new Font("Monospaced", Font.BOLD, font.getSize()));

            returnPos = s.indexOf("\n");
            if (returnPos < 0) {
                returnPos = s.length() - 1;
            } else if (returnPos >= s.length()) {
                returnPos = s.length() - 1;
            }
            schreibe = s.substring(0, returnPos);
            rest = s.substring(returnPos + 1, s.length());

            g.drawString(schreibe, x, y);

            this.setzeString(g, rest, x, y + 14);
            g.setFont(font);
        }
    }

    /**
     * löscht alle aktuellen Segmente.
     */
    private void loescheSegs() {
        for (int i = 0; i < this.segBeschr.length; i++) {
            this.segBeschr[i] = null;
        }
    }
   
    /**
     * fügt eine Liste von Segmentbeschreibungen hinzu.
     *
     * @param segs  Die Segmentbeschreibungen.
     */
    private void addAllSegs(final List<SegSpez> segs) {
        for (SegSpez s : segs) {
            this.addSeg(s, true);
            if (s.getBeginn() != 0) {
                s.setPfeilAnfang(ArrowMaster.EINFACHER_ABSCHLUSS);
            } else {
                s.setPfeilAnfang(this.ende);
            }
            if (s.getEnde() != this.pfeilPol.nPoints() - 1) {
                s.setPfeilEnde(ArrowMaster.EINFACHER_ABSCHLUSS);
            } else {
                s.setPfeilEnde(this.anfang);
            }
        }
    }
   
    /**
     * fügt eine Segmentbeschreibung hinzu.
     *
     * @param neu     Die neue Segmentbeschreibung.
     * @param hinten  Ob das Segment hinten (oder vorne) eingefügt werden soll.
     */
    private void addSeg(
            final SegSpez neu,
            final boolean hinten) {
        int i = 0;
       
        while (this.segBeschr[i] != null) {
            i++;
        }

        if (!hinten) {
            while (i > 0) {
                this.segBeschr[i] = this.segBeschr[i - 1];
                i--;
            }
        }

        this.segBeschr[i] = neu;
    }
   
    /**
     * Gibt eine Ampel als Kreise zurück.
     *
     * @param stufe      0 = gr�n, 1 = gelb, 2 = rot.
     * @param linksOben  Die Koordinaten der Mitte des oberen Lichts.
     * @param radius     Der Radius.
     *
     * @return  Die Ampel als zeichenbare Liste.
     */
    final ArrayList<Object> ampel(
            final int stufe,
            final Vector2D linksOben,
            final double radius) {
       
        ArrayList<Object> liste = new ArrayList<Object>(6);
        AusgMerkm ausgGRUENAktiv = new AusgMerkm(
                Color.black, Color.green, true, true);
        AusgMerkm ausgGELBAktiv = new AusgMerkm(
                Color.black, Color.yellow, true, true);
        AusgMerkm ausgROTAktiv = new AusgMerkm(
                Color.black, Color.red, true, true);
        AusgMerkm ausgGRUENPassiv = new AusgMerkm(
                Color.black, new Color(200, 200, 200), true, true);
        AusgMerkm ausgGELBPassiv = new AusgMerkm(
                Color.black, new Color(200, 200, 200), true, true);
        AusgMerkm ausgROTPassiv = new AusgMerkm(
                Color.black, new Color(200, 200, 200), true, true);
        Polygon2D quad = new Polygon2D();
        Vector2D xSub = new Vector2D(radius * 1.5, 0);
        Vector2D ySub = new Vector2D(0, radius * 1.5);
        Vector2D zwisch;
        zwisch = new Vector2D(linksOben);
        zwisch.sub(xSub);
        zwisch.sub(ySub);
        quad.add(zwisch);

        zwisch = new Vector2D(linksOben.x, linksOben.y + radius * 4 + radius);
        zwisch.sub(xSub);
        zwisch.translate(ySub);
        quad.add(zwisch);

        zwisch = new Vector2D(linksOben.x, linksOben.y + radius * 4 + radius);
        zwisch.translate(xSub);
        zwisch.translate(ySub);
        quad.add(zwisch);

        zwisch = new Vector2D(linksOben.x, linksOben.y);
        zwisch.translate(xSub);
        zwisch.sub(ySub);
        quad.add(zwisch);
       
        AusgMerkm zwAusg = new AusgMerkm(Color.black, Color.black, true, true);
        liste.add(zwAusg);
        liste.add(quad.toPol(1, Vector2D.NULL_VECTOR));
       
        Circle2D k1 = new Circle2D(
                linksOben.x,
                linksOben.y,
                radius);
        Circle2D k2 = new Circle2D(
                linksOben.x,
                linksOben.y + radius * 2 + radius / 2,
                radius);
        Circle2D k3 = new Circle2D(
                linksOben.x,
                linksOben.y + radius * 4 + radius,
                radius);
       
        if (stufe == 2) {
            liste.add(ausgROTAktiv);
        } else {
            liste.add(ausgROTPassiv);
        }
        liste.add(k1);

        if (stufe == 1) {
            liste.add(ausgGELBAktiv);
        } else {
            liste.add(ausgGELBPassiv);
        }
        liste.add(k2);

        if (stufe == 0) {
            liste.add(ausgGRUENAktiv);
        } else {
            liste.add(ausgGRUENPassiv);
        }
        liste.add(k3);

        return liste;
    }
   
    /**
     * Verschiebt das Polygon um den angegebenen Vektor. Dabei werden alle
     * Punkte des Polygons tatsächlich (und nicht nur relativ zur Zeichenfl�che
     * versetzt.
     *
     * @param vek  Der Verschiebevektor.
     */
    public void verschiebe(final Vector2D vek) {
        this.pfeilPol.translate(vek);
    }
   
    /**
     * Gibt Kreise zurück, deren Mittelpunkte den Ortsvektoren der übergebenen
     * Nachrichten entsprechen. Falls Nachrichten ohne Ortsvektor als Zusatz
     * existieren, werden sie ignoriert.
     *
     * @param liste  Die Nachrichtenliste.
     * @return  Die Markierungskreise.
     */
    private LinkedList<Circle2D> fehlerQuellen(final List<AbstractMsg> liste) {
        LinkedList<Circle2D> kreise = new LinkedList<Circle2D>();
        final double radius = 10;
        Vector2D zwisch;
       
        for (AbstractMsg m : liste) {
            if (m.getZusatz() != null
                    && m.getZusatz().getClass().equals(Vector2D.class)) {
               
                zwisch = new Vector2D((Vector2D) m.getZusatz());
                zwisch.mult(skalierung);
                zwisch.translate(verschiebung);
                kreise.add(new Circle2D(zwisch, radius));
            }
        }
       
        return kreise;
    }
   
    /**
     * Erzeugt ein Polygon aus dem aktuellen Pfeil, das direkt als Spitze
     * verwendet werden kann.
     *
     * @return  Das Grundpolygon, das unabhängig von den Userpolygonen ist.
     */
    public Polygon2D getGrundPolSpitze() {
        if (this.pfeilPol.nPoints() <= 0) {
            return null;
        }
       
        Vector2D versch = new Vector2D(this.pfeilPol.get(0));
        versch.mult(-1);
       
        Vector2D anfWin = new Vector2D(this.pfeilPol.get(1));
        anfWin.sub(this.pfeilPol.get(0));
        double winkel = Math.atan(anfWin.x / anfWin.y);
       
        Polygon2D p = (new ArrowMaster(this.pars)).segmentPfeilPol2D(
                this.pfeilPol,
                this.dicken,
                ArrowMaster.EINFACHER_ABSCHLUSS,
                this.anfang,
                new Vector2D(this.anfFakt, this.anfFakt),
                new Vector2D(1, 1));
       
        p.translate(versch);
       
        p.scale(
                Vector2D.NULL_VECTOR,
                new Vector2D(1 / this.dicken.get(0), 1 / this.dicken.get(0)));
       
        p.rotate(Vector2D.NULL_VECTOR, winkel);
       
        return p;
    }
   
    /**
     * Erzeugt die zu zeichnenden Objekte, also die Teilsegmente des Pfeils
     * Farbangaben, etc.
     *
     * @param skal    Die Skalierung.
     * @param versch  Die Verschiebung.
     *
     * @return  Die zu zeichnenden Objekte.
     */
    public List<Object> erzeugeZeichenObjekte(
            final double skal,
            final Vector2D versch) {
        List<Object> liste = new ArrayList<Object>();
        Pol2DMitAusgMerkm[] segs;
       
        AusgMerkm ausg = new AusgMerkm(
                Color.black,
                Color.white,
                true,
                true);

        this.loescheSegs();
        this.addAllSegs(this.userSegs);
       
        if (this.pfeilPol.nPoints() > 1 && this.zeichneGrundPfeil) {
            SegSpez segNeu = new SegSpez(
                    ausg,
                    0,
                    this.pfeilPol.nPoints() - 1,
                    this.ende,
                    this.anfang,
                    new Vector2D(this.anfFakt, this.anfFakt),
                    new Vector2D(this.endFakt, this.endFakt));
           
            this.addSeg(segNeu, false);
        }

        if (this.gestrichelt <= 0) {
            segs = this.zeichenArt.erzeugePfeilsegmente(
                    this.pfeilPol,
                    this.dicken,
                    this.segBeschr,
                    this.pars);
        } else {
            segs = this.zeichenArt.gestrichelterPfeil(
                    this.pfeilPol,
                    this.dicken,
                    this.ende,
                    this.anfang,
                    new Vector2D(this.anfFakt, this.anfFakt),
                    new Vector2D(this.endFakt, this.endFakt),
                    this.gestricheltMerkm,
                    this.gestrichelt,
                    this.pars);
        }
       
        liste = Geometry2D.erzeugeObjList(
                segs,
                skal,
                versch);

        return liste;
    }
   
    /**
     * Zeichenmethode.
     *
     * @param g  Das Grafikobjekt.
     */
    @Override
    public void paint(final Graphics g) {
        long zeit = System.currentTimeMillis();
        List<Object> liste = new LinkedList<Object>();

        try {
            liste = this.erzeugeZeichenObjekte(
                    this.skalierung,
                    this.verschiebung);

            if (this.markiereEcken) {
                AusgMerkm unmark1 = new AusgMerkm(
                        Color.black,
                        Color.white,
                        true,
                        true);
                AusgMerkm unmark2 = new AusgMerkm(
                        Color.black,
                        Color.white,
                        false,
                        false);
                AusgMerkm m1 = new AusgMerkm(
                        Color.black,
                        Color.red,
                        true,
                        true);
                AusgMerkm m2 = new AusgMerkm(
                        Color.black,
                        Color.yellow,
                        true,
                        true);
               
                ArrayList<Integer> markierung
                    = new ArrayList<Integer>(this.markierte.size());
               
                for (int i : this.markierte) {
                    markierung.add(i);
                }
               
                this.zeichenArt.markiereEcken(
                        this.pfeilPol.toPol(
                                this.skalierung,
                                this.verschiebung),
                        liste,
                        markierung,
                        m2,
                        unmark1,
                        4);
               
                markierung.clear();
               
                markierung.add(this.mark1);
                markierung.add(this.mark2);

                this.zeichenArt.markiereEcken(
                        this.pfeilPol.toPol(
                                this.skalierung,
                                this.verschiebung),
                        liste,
                        markierung,
                        m1,
                        unmark2,
                        4);
            }
           
            if (this.ersteEcke != null && this.zweiteEcke != null) {
                Polygon2D quad = new Polygon2D();
               
                quad.add(new Vector2D(this.ersteEcke));
                quad.add(new Vector2D(this.ersteEcke.x, this.zweiteEcke.y));
                quad.add(new Vector2D(this.zweiteEcke));
                quad.add(new Vector2D(this.zweiteEcke.x, this.ersteEcke.y));
               
                liste.add(new AusgMerkm(
                        Color.lightGray,
                        Color.black,
                        true,
                        false));
                liste.add(quad.toPol(this.skalierung, this.verschiebung));
            }
           
            LinkedList<AbstractMsg> msgsError
                = this.pars.getMsgs(
                    (new MsgError(null, 0, null)).getType(),
                    zeit,
                    Long.MAX_VALUE);

            LinkedList<AbstractMsg> msgsWarning
                = this.pars.getMsgs(
                    (new MsgWarning(null, 0, null)).getType(),
                    zeit,
                    Long.MAX_VALUE);

            if (this.fehlerStufe == 2 || !msgsError.isEmpty()) {
                liste.addAll(this.ampel(2, new Vector2D(50, 50), 7));
            } else if (this.fehlerStufe == 1 || !msgsWarning.isEmpty()) {
                liste.addAll(this.ampel(1, new Vector2D(50, 50), 7));
            } else {
                liste.addAll(this.ampel(0, new Vector2D(50, 50), 7));
            }
           
            liste.add(new AusgMerkm(
                    Color.black,
                    Color.red,
                    true,
                    true));
            liste.addAll(this.fehlerQuellen(msgsError));
            liste.addAll(this.fehlerQuellen(msgsWarning));

            liste.add(new AusgMerkm(
                    Color.black,
                    Color.black,
                    true,
                    true,
                    "",
                    1,
                    20));
            liste.add(new Integer(50 - 14));
            liste.add(new Integer(130));
            liste.add("" + this.pfeilPol.nPoints());

            liste.add(new Integer(50 + 20));
            liste.add(new Integer(50));
            liste.add(
                    ""
                    + Math.round(this.skalierung * 100)
                    + " %");

            Geometry2D.maleObjListe(g, liste);
            this.elternMaster.setzeSegmentFarben(this.gestricheltMerkm);
           
        } catch (final Exception e) {
            liste.addAll(this.ampel(2, new Vector2D(50, 50), 7));
            Geometry2D.maleObjListe(g, liste);
            StaticMethods.log(
                    StaticMethods.LOG_ERROR,
                    "Fehler beim Zeichnen des Pfeils: ",
                    this.pars);
            StaticMethods.log(
                    StaticMethods.LOG_ERROR,
                    e.toString(),
                    this.pars,
                    "plain",
                    null);
            throw new RuntimeException("Fehler beim Zeichnen des Pfeils");
        }
    }
   
    /**
     * Ersetzt den Teil zwischen den beiden markierten Punkten durch
     * ein Beziersegment.
     *
     * @param bezKonst  Die Bezierkonstante.
     */
    public void bezier(final double bezKonst) {
        double bezK = bezKonst;
        Polygon2D bez;
        Vector2D v1, v2, v3, v4;
        ArrayList<Integer> mark = new ArrayList<Integer>(4);
       
        if (bezK > 1) {
            bezK = eas.startSetup.marbBuilder.zeichenModi.ConstantsZeichenModi.BEZ_NORMAL;
        }
       
        if (this.mark1 != null
                && this.mark2 != null
                && !this.mark1.equals(this.mark2)
                && this.markierte.size() == 4) {
           
            mark.addAll(this.markierte);
               
            Collections.sort(this.markierte, new IntComp());

            v1 = this.pfeilPol.get(mark.get(0));
            v2 = this.pfeilPol.get(mark.get(1));
            v3 = this.pfeilPol.get(mark.get(2));
            v4 = this.pfeilPol.get(mark.get(3));

            bez = Geometry2D.bezierKurve(v1, v2, v3, v4, bezK);
           
            Polygon2D polNeu = new Polygon2D();
            ArrayList<Double> dickenNeu = new ArrayList<Double>();
            boolean platziert = false;
           
            for (int i = 0; i < this.pfeilPol.nPoints(); i++) {
                if (!this.between(mark.get(0), mark.get(3), i)) {
                    polNeu.add(this.pfeilPol.get(i));
                    dickenNeu.add(this.dicken.get(i));
                } else if (!platziert) {
                    for (int n = 0; n < bez.nPoints(); n++) {
                        polNeu.add(bez.get(n));
                        dickenNeu.add(this.dicken.get(i));
                    }
                    platziert = true;
                }
            }
           
            this.mark1 = null;
            this.mark2 = null;
            this.markierte.clear();
           
            this.dicken = dickenNeu;
            this.pfeilPol = polNeu;
        } else if (this.markierte.size() > 4) {
            LinkedList<Integer> marks = new LinkedList<Integer>();
            for (int i = 0; i < markierte.size() - 4; i++) {
                this.mark1 = markierte.get(i);
                this.mark2 = markierte.get(i + 1);

                marks.clear();
                marks.addAll(this.markierte);
                this.markierte.clear();
                this.markierte.add(marks.get(i));
                this.markierte.add(marks.get(i + 1));
                this.markierte.add(marks.get(i + 2));
                this.markierte.add(marks.get(i + 3));
               
                this.bezier(bezKonst);
               
                this.markierte.clear();
                this.markierte.addAll(marks);
            }
        }
    }
   
    /**
     * Ob der letzte Parameter zwischen dem ersten und dem zweiten Parameter
     * liegt.
     *
     * @param z1  Die erste Grenzzahl.
     * @param z2  Die zweite Grenzzahl.
     * @param z   Die zu testende Zahl.
     *
     * @return  Ob die zu testende Zahl zwischen der ersten und zweiten
     *          Grenzzahl liegt.
     */
    private boolean between(final double z1, final double z2, final double z) {
        return (z >= z1 && z <= z2) || (z <= z1 && z >= z2);
    }
   
    /**
     * fügt eine Ausg-Spez hinzu.
     *
     * @param aktSeg  Die Ausg-Spez.
     */
    public void setzeAktSegAusg(final AusgMerkm aktSeg) {
        int m1, m2;
        Pfeilspitze polAnfang = this.anfang;
        Pfeilspitze polEnde = this.ende;
       
        if (this.mark1 == null || this.mark2 == null) {
            return;
        }
       
        if (this.mark1 < this.mark2) {
            m1 = this.mark1;
            m2 = this.mark2;
        } else if (this.mark1 > this.mark2) {
            m1 = this.mark2;
            m2 = this.mark1;
        } else {
            return;
        }
       
        if (m1 != 0) {
            polEnde = ArrowMaster.EINFACHER_ABSCHLUSS;
        }

        if (m2 != this.pfeilPol.nPoints() - 1) {
            polAnfang = ArrowMaster.EINFACHER_ABSCHLUSS;
        }

        SegSpez neu = new SegSpez(
                aktSeg,
                m1,
                m2,
                polEnde,
                polAnfang,
                new Vector2D(this.anfFakt, this.anfFakt),
                new Vector2D(this.endFakt, this.endFakt));
       
        this.addSeg(neu, true);
        this.userSegs.add(neu);
    }

    /**
     * @return Returns the graphName.
     */
    public String getGraphName() {
        return this.robName;
    }

    /**
     * Speichert die Darstellung des aktuellen Automaten in eine PNG-Datei.
     *
     * @param datNam  Der Name der Datei (ohne Erweiterung).
     * @param modus   Der Modus (jpg, png, bmp, ...)
     * @param skal    Die Skalierung der Grafik.
     */
    public void savePNG(
            final String datNam,
            final String modus,
            final double skal) {
        Geometry2D.saveObjectsToFile(
                this.erzeugeZeichenObjekte(skal, Vector2D.NULL_VECTOR),
                datNam,
                modus,
                this.pars);
    }

    /**
     * @return Returns the markiereEcken.
     */
    public boolean isMarkiereEcken() {
        return this.markiereEcken;
    }

    /**
     * @param markEck The markiereEcken to set.
     */
    public void setMarkiereEcken(final boolean markEck) {
        this.markiereEcken = markEck;
    }

    /**
     * @return Returns the aktDicke.
     */
    public double getAktDicke() {
        return this.aktDicke;
    }

    /**
     * @param aktDick The aktDicke to set.
     */
    public void setAktDicke(final double aktDick) {
        int j = 0;
       
        for (int i : this.markierte) {
            this.dicken.set(i, aktDick);
            j++;
        }
       
        if (j == 0) {
            this.aktDicke = aktDick;
        }
    }

    /**
     * @return Returns the zeichneGrundPfeil.
     */
    public boolean isZeichneGrundPfeil() {
        return this.zeichneGrundPfeil;
    }

    /**
     * @param grPfeil The zeichneGrundPfeil to set.
     */
    public void setZeichneGrundPfeil(final boolean grPfeil) {
        this.zeichneGrundPfeil = grPfeil;
    }

    /**
     * @return Returns the markierte.
     */
    public LinkedList<Integer> getMarkierte() {
        return this.markierte;
    }

    /**
     * Skaliert die Grafik auf Maximalgröße relativ zum Zeichenfenster.
     */
    public void skaliere() {
        double xF = this.getWidth();
        double yF = this.getHeight();
        List<Object> objekte = this.erzeugeZeichenObjekte(
                1,
                Vector2D.NULL_VECTOR);
       
        Vector2D pLO
            = new Vector2D(Geometry2D.rahmen(objekte).get(0));
        Vector2D pRU
            = new Vector2D(Geometry2D.rahmen(objekte).get(1));
       
        this.skalierung =
            Math.min(xF / (pRU.x - pLO.x), yF / (pRU.y - pLO.y));
        this.skalierung /= 1.2;
    }

    /**
     * Zentriert zur Mitte des Fensters.
     */
    public void zentriere() {
        double xF = this.getWidth();
        double yF = this.getHeight();
        this.zentriere(new Vector2D(xF / 2, yF / 2));
    }
   
    /**
     * Zentriert die Grafik relativ zu einer angegebenen Mitte.
     *
     * @param mitte  Das Zentrum.
     */
    public void zentriere(final Vector2D mitte) {
        List<Object> objekte = this.erzeugeZeichenObjekte(
                1,
                Vector2D.NULL_VECTOR);
       
        Vector2D pLO = new Vector2D(Geometry2D.rahmen(objekte).get(0));
        Vector2D pRU = new Vector2D(Geometry2D.rahmen(objekte).get(1));
       
        Vector2D neuVersch = new Vector2D(mitte);
        Vector2D zwisch = new Vector2D(pLO);
        zwisch.translate(new Vector2D((pRU.x - pLO.x) / 2, (pRU.y - pLO.y) / 2));
        zwisch.mult(skalierung);
        neuVersch.sub(zwisch);
        this.verschiebung = neuVersch;
    }
   
    /**
     * Wenn das Mausrad bewegt wurde.
     *
     * @param e  Das zugehörige Event.
     */
    @Override
    public void mouseWheelMoved(final MouseWheelEvent e) {
        final double konstSkal = 1.2;
        final double maxZoom = 100;
        final double minZoom = 0.01;
        double xF = this.getWidth();
        double yF = this.getHeight();
        final Vector2D mittVek = new Vector2D(xF / 2, yF / 2);
        final Vector2D mouse = new Vector2D(e.getPoint());
        mouse.sub(mittVek); // TODO
       
        if (e.getWheelRotation() > 0) {
            this.skalierung /= konstSkal * Math.abs(e.getWheelRotation());
        } else {
            this.skalierung *= konstSkal * Math.abs(e.getWheelRotation());
        }
       
        if (this.skalierung > maxZoom) {
            this.skalierung = maxZoom;
        }
        if (this.skalierung < minZoom) {
            this.skalierung = minZoom;
        }

        this.zentriere(mittVek);
       
        this.neuZeichnen();
    }

    /**
     * @return Returns the anfang.
     */
    public Pfeilspitze getAnfang() {
        return this.anfang;
    }

    /**
     * @return Returns the ende.
     */
    public Pfeilspitze getEnde() {
        return this.ende;
    }

    /**
     * @param anf The anfang to set.
     */
    public void setAnfang(final String anf) {
        for (Pfeilspitze s : ArrowMaster.getSpitzen()) {
            if (s.toString().equals(anf)) {
                this.anfang = s;
            }
        }
    }

    /**
     * @param end The ende to set.
     */
    public void setEnde(final String end) {
        for (Pfeilspitze s : ArrowMaster.getSpitzen()) {
            if (s.toString().equals(end)) {
                this.ende = s;
            }
        }
    }
   
    /**
     * @param dick  Setzt die Dicken.
     */
    public void setDicken(final ArrayList<Double> dick) {
        this.dicken = dick;
    }
   
    /**
     * @return  Die Dicken.
     */
    public ArrayList<Double> getDicken() {
        return this.dicken;
    }

    /**
     * @return Returns the pfeilPol.
     */
    public Polygon2D getPfeilPol() {
        return this.pfeilPol;
    }

    /**
     * @param aF The anfFakt to set.
     */
    public void setAnfFakt(final double aF) {
        this.anfFakt = aF;
    }

    /**
     * @param eF The endFakt to set.
     */
    public void setEndFakt(final double eF) {
        this.endFakt = eF;
    }
   
    /**
     * Gestrichelten Pfeil erzeugen.
     *
     * @param laenge  Die Länge der Strichelung
     */
    public void gestrichelt(final double laenge) {
        if (this.gestrichelt <= 0) {
            this.gestrichelt = laenge;
        } else {
            this.gestrichelt = 0;
        }
    }

    /**
     * @return Returns the mark1.
     */
    public Integer getMark1() {
        return this.mark1;
    }

    /**
     * @return Returns the mark2.
     */
    public Integer getMark2() {
        return this.mark2;
    }
   
    public void printPolygonCode() {
        StaticMethods.log(StaticMethods.LOG_INFO, "\n\n// Auto-generated polygon code by Arrow Master (" + this.pfeilPol.size() + " points).", this.pars, "plain", null);
        StaticMethods.log(StaticMethods.LOG_INFO, "\nPolygon2D pol = new Polygon2D();", this.pars, "plain", null);
       
        for (Vector2D point : this.pfeilPol) {
            StaticMethods.log(StaticMethods.LOG_INFO, "\npol.add(new Vector2D(" + point.x +  ", " + point.y + "));", this.pars, "plain", null);
        }
    }
}
TOP

Related Classes of eas.startSetup.arrowGUI.ZeichFen

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.