Package eas.startSetup.marbBuilder.zeichenModi

Source Code of eas.startSetup.marbBuilder.zeichenModi.ArrowMaster

/*
* Datei:          ZeichenModusEA.java
* Autor(en):      Lukas König
* Java-Version:   6.0
* Erstellt (vor): 24.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.marbBuilder.zeichenModi;

import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Point;
import java.awt.Polygon;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import eas.math.geometry.Circle2D;
import eas.math.geometry.LineSegment2D;
import eas.math.geometry.Polygon2D;
import eas.math.geometry.Vector2D;
import eas.miscellaneous.StaticMethods;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.GlobaleMARBVariablen;
import eas.startSetup.GlobalVariables;
import eas.startSetup.ParCollection;
import eas.startSetup.marbBuilder.DargestellterGraph;
import eas.startSetup.marbBuilder.graph.Knoten;


/**
* Klasse zum Erzeugen von geometrischen Figuren in Pfeilform.
* <P>
* Wenn eine Objektliste zurückgegeben wird, enthält diese Polygone,
* die fertig gezeichnet werden können und folgenderma�en codierte Strings:
* Drei aufeinanderfolgende Listenelemente bezeichnen:
* 1. Als Integer-Objekt die x-Koordinate,
* 2. Als Integer-Objekt die y-Koordinate und
* 3. Als String-Objekt den auszugebenden Text.
* z. B. liste = Pol, Pol, X-Koor, Y-Koor, String, Pol, ...
*                         ^^^^^^^^^^^^^^^^^^^^^^
*                         |---String-Objekt----|
*
* @author Lukas König
*/
public class ArrowMaster implements Serializable {

    /**
     * Die Serial Version ID (generiert am 25. April 2007).
     */
    private static final long serialVersionUID = -4051109731656095692L;

    /**
     * Gibt an, wie lang die Pfeilspitze (absolut) ist.
     */
    private double pfeilSpLaenge;

    /**
     * Gibt die Pfeildicke absolut in Pixeln an.
     */
    private int pfeilDicke;

    /**
     * Der aktuelle darzustellende Graph.
     */
    private DargestellterGraph aktGraph;

    /**
     * Liste der bereits in einer Richtung dargestellten Doppelkanten.
     */
    private ArrayList<Polygon> dopp;

    /**
     * Speichert die Zuordnung der Kanten im Graphen...
     */
    private ArrayList<Polygon> urspKanten;

    /**
     * ...zu den tatsächlich berechneten Ursprungs- und Ziel-Koordinaten.
     */
    private ArrayList<Polygon> echteKant;

    /**
     * Parameter.
     */
    private ParCollection pars;
   
    /**
     * Einfacher Abschluss, also ohne Spitze.
     */
    public static final Pfeilspitze EINFACHER_ABSCHLUSS
          = ArrowMaster.erzeugeKonstanteEnden(0);
   
    /**
     * Einfache Spitze.
     */
    public static final Pfeilspitze EINFACHE_SPITZE_1
          = ArrowMaster.erzeugeKonstanteEnden(1);

    /**
     * Einfache Spitze.
     */
    public static final Pfeilspitze EINFACHE_SPITZE_2
          = ArrowMaster.erzeugeKonstanteEnden(4);

    /**
     * Einfache Spitze.
     */
    public static final Pfeilspitze EINFACHE_SPITZE_3
          = ArrowMaster.erzeugeKonstanteEnden(5);

    /**
     * Doppelspitzes Ende.
     */
    public static final Pfeilspitze DOPPELSPITZES_ENDE
          = ArrowMaster.erzeugeKonstanteEnden(2);

    /**
     * Kugeliges Ende.
     */
    public static final Pfeilspitze KUGEL_ENDE
          = ArrowMaster.erzeugeKonstanteEnden(3);

    /**
     * Kugeliges Ende.
     */
    public static final Pfeilspitze RUECK_PFEIL
          = ArrowMaster.erzeugeKonstanteEnden(6);

    /**
     * Die Liste weiterer Pfeilspitzen.
     */
    public static final LinkedList<Pfeilspitze> WEITERE_SPITZEN
        = new LinkedList<Pfeilspitze>();
   
    /**
     * Erzeugt einige vordefinierte Endentypen.
     * 0 = Gerades Ende.
     * 1 = Normale Pfeilspitze 1.
     * 2 = Doppelspitzes Ende.
     * 3 = Kugel-Ende.
     * 4 = Normale Pfeilspitze 2.
     * 5 = Normale Pfeilspitze 3.
     * 6 = Rückbezügliche Pfeilspitze.
     *
     * @param nummer  Die Nummer des Endentyps.
     *
     * @return  Eine Liste mit Punkten, die diesen Endentyp beschreiben.
     */
    private static Pfeilspitze erzeugeKonstanteEnden(final int nummer) {
        Vector2D v;
        Pfeilspitze a = null;
       
        if (nummer == 0) {
            a = new Pfeilspitze("Gerades Ende");
        }

        if (nummer == 1) {
            a = new Pfeilspitze("Pfeilspitze 1");
            v = new Vector2D(1.8, -0.7);
            a.add(v);
            v = new Vector2D(0, 5);
            a.add(v);
            v = new Vector2D(-1.8, -0.7);
            a.add(v);
        }

        if (nummer == 2) {
            a = new Pfeilspitze("Doppelspitzes Ende");
            v = new Vector2D(Vector2D.NULL_VECTOR);
            v.sub(new Vector2D(0, 0.3));
            a.add(v);
        }

        if (nummer == 3) {
            a = new Pfeilspitze(
                    eas.math.geometry.Geometry2D.bezierKurve(
                            new Vector2D(0.5, 0),
                            new Vector2D(5, 5),
                            new Vector2D(-5, 5),
                            new Vector2D(-0.5, 0),
                            0.0001),
                    "Kugelende");
        }
       
        if (nummer == 4) {
            a = new Pfeilspitze("Pfeilspitze 2");
            v = new Vector2D(1.8, 0);
            a.add(v);
            v = new Vector2D(0, 7);
            a.add(v);
            v = new Vector2D(-1.8, 0);
            a.add(v);
        }
       
        if (nummer == 5) {
            a = new Pfeilspitze("Pfeilspitze 3");
            v = new Vector2D(2.3, -1.7);
            a.add(v);
            v = new Vector2D(2.85, -1.7);
            a.add(v);
            v = new Vector2D(0, 1.1);
            a.add(v);
            v = new Vector2D(-2.85, -1.7);
            a.add(v);
            v = new Vector2D(-2.3, -1.7);
            a.add(v);
        }

        if (nummer == 6) {
            ParCollection params = GlobalVariables.getPrematureParameters();
            ArrowMaster zeichnen = new ArrowMaster(params);

            ArrayList<Double> dicken = new ArrayList<Double>();
            Polygon2D bez = new Polygon2D();

            for (double i = 0.5 * Math.PI; i <= Math.PI * 1.5; i += 0.001) {
                bez.add(new Vector2D(
                        -(Math.sin(i) * 4 - Math.sin(0.5 * Math.PI) * 4),
                        -(Math.cos(i) * 4 - Math.cos(0.5 * Math.PI) * 4)));
            }
           
            for (double i = 0; i < bez.nPoints(); i += 1) {
                dicken.add(1.0);
            }

            a = new Pfeilspitze(
                    zeichnen.segmentPfeilPol2D(
                            bez,
                            dicken,
                            ArrowMaster.EINFACHER_ABSCHLUSS,
                            ArrowMaster.EINFACHE_SPITZE_1,
                            new Vector2D(1, 1),
                            new Vector2D(0.75, 0.75)),
                            "Rückpfeil");
        }

        return a;
    }
   
    /**
     * Konstruktor, der alle Attribute mit den als Parameter übergebenen
     * Werten initialisiert.
     *
     * @param pfD       Pfeildicke (absolut in Pixeln).
     * @param pfSpL     PfeilspitzenLänge (absolut in Pixeln).
     * @param par       Die Parameter.
     */
    public ArrowMaster(final int    pfD,
                       final double pfSpL,
                       final ParCollection par) {
        this.pfeilDicke    = pfD;
        this.pfeilSpLaenge = pfSpL;
        this.aktGraph      = null;
        this.dopp          = new ArrayList<Polygon>();
        this.urspKanten    = new ArrayList<Polygon>();
        this.echteKant     = new ArrayList<Polygon>();
        this.pars          = par;
    }

    /**
     * Konstruktor, der alle Attribute mit den Werten aus der Klasse
     * Konstanten initialisiert.
     *
     * @param par  Die Parameter.
     */
    public ArrowMaster(final ParCollection par) {
        this(ConstantsZeichenModi.PFEIL_DICKE,
             ConstantsZeichenModi.PFEILSP_LAENGE,
             par);
    }

    /**
     * Gibt die Eckpunkte eines Polygons zurück, das einen Pfeil von
     * P1 (x1, y1) nach P2 (x2, y2) darstellt (in eine Richtung).
     *
     * @param xx1  X-Koordinate des Startpunkts des Pfeils.
     * @param xx2  X-Koordinate des Endpunkts des Pfeils.
     * @param yy1  Y-Koordinate des Startpunkts des Pfeils.
     * @param yy2  Y-Koordinate des Endpunkts des Pfeils.
     * @param staerke    Die Stärke des Pfeils.
     * @param gebogen  Ob der Pfeil gebogen sein darf.
     *
     * @return  Polygon in Gestalt eines Pfeils.
     */
    public Polygon pfeilEinfach(final int xx1,
                                final int yy1,
                                final int xx2,
                                final int yy2,
                                final double staerke,
                                final boolean gebogen) {
        return this.bezierPfeil(xx1, yy1, xx2, yy2, staerke, gebogen);
    }

    /**
     * Gibt die Eckpunkte eines Polygons zurück, das einen Pfeil von
     * P1 (x1, y1) nach P2 (x2, y2) darstellt (in eine Richtung).
     *
     * @param xx1        X-Koordinate des Startpunkts des Pfeils.
     * @param yy1        Y-Koordinate des Startpunkts des Pfeils.
     * @param xx2        X-Koordinate des Endpunkts des Pfeils.
     * @param yy2        Y-Koordinate des Endpunkts des Pfeils.
     * @param staerke    Die Stärke des Pfeils.
     * @param gebogen    Ob der Pfeil gebogen sein soll.
     *
     * @return  Polygon in Gestalt eines Pfeils.
     */
    public Polygon bezierPfeil(
            final int xx1,
            final int yy1,
            final int xx2,
            final int yy2,
            final double staerke,
            final boolean gebogen) {
        double bezierConst = Math.max(
                0.001,
                this.pars.getParValueDouble(eas.statistics.ConstantsStatistics.BEZIER_KONST));
       
        int x1 = xx1;
        int y1 = yy1;
        int x2 = xx2;
        int y2 = yy2;
        double letztX;
        double letztY;
        Polygon dieseKante;
        int konstVersch = (int) (ConstantsZeichenModi.PFEIL_DICKE * 2.3);
        double vektorLen;
        double x1d;
        double x2d;
        double y1d;
        double y2d;
        Polygon2D bez;
        ArrayList<Double> dick;
       
        Vector2D pk0, pk1, pk2, pk3;
       
        if (!gebogen) {
            Vector2D p1 = new Vector2D(xx1, yy1);
            Vector2D p2 = new Vector2D(xx2, yy2);
            Polygon2D a = new Polygon2D();
            a.add(p1);
            a.add(p2);
            dick = new ArrayList<Double>(2);
            dick.add(staerke * ConstantsZeichenModi.DICKEN_REG_ST 
                             + this.pfeilDicke);
            dick.add((double) this.pfeilDicke);
           
            return this.segmentPfeilPol(a,
                                     dick,
                                     DOPPELSPITZES_ENDE,
                                     EINFACHE_SPITZE_1,
                                     new Vector2D(1, 1),
                                     new Vector2D(1, 1),
                                     1,
                                     Vector2D.NULL_VECTOR);
        }
       
        if (x1 == x2 && y1 == y2) {
            letztX = x1 + ConstantsZeichenModi.KN_DURCHM / 2;
            letztY = y1 + ConstantsZeichenModi.KN_DURCHM / 2;
           
            pk0 = new Vector2D(letztX, letztY);
            pk1 = new Vector2D(letztX + 80, letztY + 40);
            pk2 = new Vector2D(letztX + 80,
                             y1 - ConstantsZeichenModi.KN_DURCHM / 2 + this.pfeilDicke / 2 - 30);
            pk3 = new Vector2D(letztX + this.pfeilSpLaenge - 2,
                             y1 - ConstantsZeichenModi.KN_DURCHM / 2 + this.pfeilDicke / 2 - 9);
           
            bez = eas.math.geometry.Geometry2D.bezierKurve(
                    pk0,
                    pk1,
                    pk2,
                    pk3,
                    bezierConst);
           
//            if (this.pars.getEinfacheDar()) {
//                dick = null;
//            } else {
            dick = new ArrayList<Double>(bez.nPoints());
            for (double i = 0; i <= bez.nPoints(); i++) {
                dick.add((bez.nPoints() - i) * staerke / bez.nPoints()
                        * ConstantsZeichenModi.DICKEN_REG_ST 
                         + this.pfeilDicke);
            }
//            }
           
            return this.segmentPfeilPol(bez,
                                     dick,
                                     DOPPELSPITZES_ENDE,
                                     EINFACHE_SPITZE_1,
                                     new Vector2D(1, 1),
                                     new Vector2D(1, 1),
                                     1,
                                     Vector2D.NULL_VECTOR);
           
        } else {
            Vector2D vv = new Vector2D(x2, y2);
            vv.sub(new Vector2D(x1, y1));
            vv.norm();
            vv.mult(35);
           
            x1 += vv.x;
            y1 += vv.y;
            x2 -= vv.x;
            y2 -= vv.y;

            // Die aktuelle Kante ist eine Doppelkante.
            if (this.aktGraph != null && this.aktGraph.enthaeltPfeil(xx2, yy2, xx1, yy1)) {
                x1d = x1;
                x2d = x2;
                y1d = y1;
                y2d = y2;
                vektorLen = Math.sqrt(Math.pow(x2d - x1d, 2)
                                    + Math.pow(y1d - y2d, 2));

                dieseKante = new Polygon();
                dieseKante.addPoint(x1, y1);
                dieseKante.addPoint(x2, y2);

                if (this.dopp.contains(dieseKante)) {
                    x1d = x1d + ((y1d - y2d) / vektorLen) * konstVersch;
                    x2d = x2d + ((y1d - y2d) / vektorLen) * konstVersch;
                    y1d = y1d + ((x2d - x1d) / vektorLen) * konstVersch;
                    y2d = y2d + ((x2d - x1d) / vektorLen) * konstVersch;
                } else {
                    x1d = x1d - ((y1d - y2d) / vektorLen) * konstVersch;
                    x2d = x2d - ((y1d - y2d) / vektorLen) * konstVersch;
                    y1d = y1d - ((x2d - x1d) / vektorLen) * konstVersch;
                    y2d = y2d - ((x2d - x1d) / vektorLen) * konstVersch;
                    this.dopp.add(dieseKante);
                }
                x1 = (int) x1d;
                x2 = (int) x2d;
                y1 = (int) y1d;
                y2 = (int) y2d;
            } else {
                Vector2D v0 = new Vector2D(x2, y2);
                v0.sub(new Vector2D(x1, y1));
                v0.ortho();
                v0.norm();
                v0.mult(12);
               
                x1 += v0.x;
                x2 += v0.x;
                y1 += v0.y;
                y2 += v0.y;
            }

            Polygon pol1 = new Polygon();
            Polygon pol2 = new Polygon();

            pol1.addPoint(xx1, yy1);
            pol1.addPoint(xx2, yy2);
            pol2.addPoint(x1, y1);
            pol2.addPoint(x2, y2);

            this.urspKanten.add(pol1);
            this.echteKant.add(pol2);

            Vector2D v = new Vector2D(x2, y2);
            double dist = new Vector2D(x1, y1).distance(new Vector2D(x2, y2));
           
            v.sub(new Vector2D(x1, y1));
            v.norm();
            v.mult(this.pfeilSpLaenge);
            Vector2D v1 = new Vector2D(x1, y1);
            Vector2D v2 = new Vector2D(x2, y2);
            v2.sub(v);
           
            Vector2D n1 = new Vector2D((x1 + x2) / 2, (y1 + y2) / 2);
            Vector2D n2 = new Vector2D((x1 + x2) / 2, (y1 + y2) / 2);
            v.ortho();
            v.norm();
            Vector2D zwisch = new Vector2D(x2, y2);
            zwisch.sub(new Vector2D(x1, y2));
           
            v.mult(Math.sqrt(Math.max(dist - 100, 0)) + 0.1);
           
           
            n1.translate(v);
            n2.translate(v);
           
            bez = eas.math.geometry.Geometry2D.bezierKurve(
                    v1,
                    n1,
                    n2,
                    v2,
                    bezierConst);
//            if (this.pars.getEinfacheDar()) {
//                dick = null;
//            } else {
            dick = new ArrayList<Double>(bez.nPoints());
            for (double i = 0; i <= bez.nPoints(); i++) {
                dick.add((bez.nPoints() - i) * staerke / bez.nPoints()
                        * ConstantsZeichenModi.DICKEN_REG_ST
                         + this.pfeilDicke);
            }
//            }

            return this.segmentPfeilPol(bez,
                                     dick,
                                     DOPPELSPITZES_ENDE,
                                     EINFACHE_SPITZE_1,
                                     new Vector2D(1, 1),
                                     new Vector2D(1, 1),
                                     1,
                                     Vector2D.NULL_VECTOR);
        }
    }
   
    /**
     * Gibt einen einfachen Knoten als quadratisches Polygon zurück.
     *
     * @param x  X-Koordinate des Knotens.
     * @param y  Y-Koordinate des Knotens.
     *
     * @return  Polygon, das den Knoten repräsentiert.
     */
    public Polygon knotenEinfach(final int x, final int y, final double bezierConst) {
//        final Polygon quadrat = new Polygon();
//        double        xQ;
//        double        yQ;
//
//        xQ = x - this.knotenDurchm / 2.0;
//        yQ = y - this.knotenDurchm / 2.0;
//        quadrat.addPoint((int) xQ, (int) yQ);
//
//        xQ = x - this.knotenDurchm / 2.0;
//        yQ = y + this.knotenDurchm / 2.0;
//        quadrat.addPoint((int) xQ, (int) yQ);
//
//        xQ = x + this.knotenDurchm / 2.0;
//        yQ = y + this.knotenDurchm / 2.0;
//        quadrat.addPoint((int) xQ, (int) yQ);
//
//        xQ = x + this.knotenDurchm / 2.0;
//        yQ = y - this.knotenDurchm / 2.0;
//        quadrat.addPoint((int) xQ, (int) yQ);

        return eas.math.geometry.Geometry2D.kreis(
                new Vector2D(x, y),
                31,
                (int) (1 / bezierConst));
    }

    /**
     * Gibt einen Graphen als Liste von Polygon-Objekten zurück,
     * die mit Java.Awt direkt gezeichnet werden können. Beschriftungen werden
     * nicht gezeichnet.
     *
     * @param g  Zu zeichnender Graph.
     *
     * @return  Liste von zu zeichnenden Objekten.
     */
    public List<Object> graph(final DargestellterGraph g) {
        final ArrayList<Object> polygonListe = new ArrayList<Object>();
        final ArrayList<Point> knotenKoord  = g.holeKnotenKoord();
        final ArrayList<Double> pfeilStaerken  = g.holePfeilStaerken();
        final ArrayList<Knoten> knotenObj    = g.holeKnotenObj();
        final ArrayList<Point> pfeilUrsp    = g.holePfeilUrspr();
        final ArrayList<Point> pfeilEnpk    = g.holePfeilEnd();
        final ArrayList<String> beschr       = g.holeBeschr();
        final ArrayList<Point> beschrKoord  = g.holeBeschrKoord();
        final ArrayList<Boolean> pfeilGebogen = g.holePfeilBiegung();
        Polygon               aktuellesPol;
        String                aktBeschr;
        Point                 aktPunktU;
        Point                 aktPunktE;
        Point                 aktPunktK;
        Point                 aktPunktB;
        final Iterator<Point> itU;
        final Iterator<Point> itE;
        final Iterator<Double> itS;
        final Iterator<Point> itK;
        final Iterator<Knoten> itKO2;
        final Iterator<Boolean> itG;
        final Iterator<String> itB;
        final Iterator<Point> itBK;
        final AusgMerkm ausgPfeile;
        AusgMerkm       ausgKnoten;
        Color                 knotenFarbe;
        Object                aktKnot;
        double bezierConst = Math.max(
                0.001,
                this.pars.getParValueDouble(eas.statistics.ConstantsStatistics.BEZIER_KONST));

        this.aktGraph = g;

        if (this.pars.getParValueBoolean(eas.statistics.ConstantsStatistics.EINFACHE_DARSTELLUNG)) {
            ausgPfeile = new AusgMerkm(Color.BLACK,
                                             Color.LIGHT_GRAY,
                                             true,
                                             true,
                                             "Calibri",
                                             Font.PLAIN,
                                             14);
        } else {
            ausgPfeile = new AusgMerkm(Color.BLACK,
                                             Color.ORANGE,
                                             true,
                                             true,
                                             "Calibri",
                                             Font.PLAIN,
                                             14);
        }

        itU = pfeilUrsp.iterator();
        itE = pfeilEnpk.iterator();
        itS = pfeilStaerken.iterator();
        itG = pfeilGebogen.iterator();
        polygonListe.add(ausgPfeile);
        while (itU.hasNext() && itE.hasNext() && itS.hasNext()) {
            aktPunktU = itU.next();
            aktPunktE = itE.next();
            aktuellesPol = this.pfeilEinfach(aktPunktU.x,
                                             aktPunktU.y,
                                             aktPunktE.x,
                                             aktPunktE.y,
                                             itS.next(),
                                             itG.next());
            polygonListe.add(aktuellesPol);
        }

        itK = knotenKoord.iterator();
        itKO2 = knotenObj.iterator();
        while (itK.hasNext() && itKO2.hasNext()) {
            aktKnot = itKO2.next();
            aktPunktK = itK.next();
            if (g.getSelektiert(aktKnot)) {
                if (this.pars.getParValueBoolean(eas.statistics.ConstantsStatistics.EINFACHE_DARSTELLUNG)) {
                    knotenFarbe = Color.LIGHT_GRAY;
                } else {
                    knotenFarbe = ConstantsZeichenModi.MARKIERT_FUELL_FARBE;
                }
            } else {
                if (this.pars.getParValueBoolean(eas.statistics.ConstantsStatistics.EINFACHE_DARSTELLUNG)) {
                    knotenFarbe = Color.white;
                } else {
                    knotenFarbe = ConstantsZeichenModi.STANDARD_FUELL_FARBE;
                }
            }
            ausgKnoten = new AusgMerkm(Color.BLACK,
                                             knotenFarbe,
                                             true,
                                             true,
                                             "Calibri",
                                             Font.PLAIN,
                                             14);
            aktuellesPol = this.knotenEinfach(aktPunktK.x, aktPunktK.y, bezierConst);
            polygonListe.add(ausgKnoten);
            polygonListe.add(aktuellesPol);
        }

        itB  = beschr.iterator();
        itBK = beschrKoord.iterator();
        while (itB.hasNext() && itBK.hasNext()) {
            int x;
            int y;
            Polygon pol;
            Polygon ass;
            int x1;
            int x2;
            int y1;
            int y2;
            int x1ass;
            int x2ass;
            int y1ass;
            int y2ass;
            aktPunktB = itBK.next();
            aktBeschr = itB.next();
            String nBeschr;
            int nBInt;

            x = aktPunktB.x;
            y = aktPunktB.y;

            ass = g.holeAssoz(aktBeschr);
            if (ass != null && ass.npoints == 0) {
                int trennInd = 0;
                while (aktBeschr.charAt(trennInd) != '-') {
                    trennInd++;
                }
                nBInt = Integer.parseInt(aktBeschr.substring(0, trennInd));
                nBeschr = aktBeschr.substring(trennInd);
                aktBeschr = eas.simulation.ConstantsSimulation.befehlName(nBInt, this.pars) + nBeschr;

                if (GlobaleMARBVariablen.GENERISCHE_ZUSTAENDE.get(nBInt) != null) {
                    aktBeschr = GlobaleMARBVariablen.GENERISCHE_ZUSTAENDE
                            .get(nBInt).stateName();
                }
               
                ass = null;
            }
            if (ass != null) {
                int i = 0;
                x1ass = ass.xpoints[0];
                x2ass = ass.xpoints[1];
                y1ass = ass.ypoints[0];
                y2ass = ass.ypoints[1];
                while (i < this.urspKanten.size()) {
                    pol = this.urspKanten.get(i);
                    x1 = pol.xpoints[0];
                    x2 = pol.xpoints[1];
                    y1 = pol.ypoints[0];
                    y2 = pol.ypoints[1];

                    if (x1ass == x1 && x2ass == x2
                        && y1ass == y1 && y2ass == y2) {
                        if (x1 != x2 || y1 != y2) {
                            pol = this.echteKant.get(i);
                            x1 = pol.xpoints[0];
                            x2 = pol.xpoints[1];
                            y1 = pol.ypoints[0];
                            y2 = pol.ypoints[1];

                            Vector2D verschOrtho = new Vector2D(x1, y1);
                            verschOrtho.sub(new Vector2D(x2, y2));
                            Vector2D verschPar = new Vector2D(verschOrtho);
                            verschPar.norm();
                            verschPar.mult(30);
                            verschOrtho.ortho();
                            verschOrtho.norm();
                            verschOrtho.mult(-10);
                            Vector2D versch = new Vector2D(verschPar);
                            versch.translate(verschOrtho);
                           
                            x = (int) (((double) x1 + (double) x2) / 2.0
                                    + versch.x);
                            y = (int) (((double) y1 + (double) y2) / 2.0
                                    + versch.y);
                        }
                    }

                    i++;
                }
            }

            polygonListe.add(new Integer(x));
            polygonListe.add(new Integer(y));
            polygonListe.add(aktBeschr);
        }

        this.aktGraph = null;
        this.dopp.clear();
        this.urspKanten.clear();
        this.echteKant.clear();

        return polygonListe;
    }
   
    /**
     * Gibt einen Pfeil als Java-Polygon zurück, der in mehreren Segmenten
     * durch die übergebenen Punkte verläuft. Diese Methode basiert auf
     * <code>segmentPfeilPol2D</code>
     *
     * @param punkte       Die Punkte, durch die der Pfeil verlaufen soll.
     * @param dicken       Die Dicken des Pfeils an den Stellen der
     *                     Verlaufspunkte.
     * @param pfeilAnfang  Die Spitze des Pfeils am Beginn.
     * @param pfeilEnde    Die Spitze des Pfeils am Ende.
     * @param anfFaktor    Multiplikativer Faktor für die Größe der Enden.
     * @param endFaktor    Multiplikativer Faktor für die Größe der Enden.
     * @param gesamtskalierung  Skalierung des gesamten Polygons.
     * @param versch       Die Verschiebung.
     *
     * @return  Der Pfeil aus mehreren Segmenten.
     */
    public Polygon segmentPfeilPol(final Polygon2D punkte,
                                   final ArrayList<Double> dicken,
                                   final Pfeilspitze pfeilAnfang,
                                   final Pfeilspitze pfeilEnde,
                                   final Vector2D    anfFaktor,
                                   final Vector2D    endFaktor,
                                   final double    gesamtskalierung,
                                   final Vector2D versch) {
       
        Polygon2D pfeilArr = this.segmentPfeilPol2D(
                punkte,
                dicken,
                pfeilAnfang,
                pfeilEnde,
                anfFaktor,
                endFaktor);
       
        return pfeilArr.toPol(gesamtskalierung, versch);
    }
   
    /**
     * Gibt einen Pfeil zurück, der in mehreren Segmenten durch die
     * übergebenen Punkte verläuft. Der Pfeil wird als Polygon2D
     * (und nicht als Java-Polygon) zurückgegeben.
     *
     * @param punkte       Die Punkte, durch die der Pfeil verlaufen soll.
     * @param dicken       Die Dicken des Pfeils an den Stellen der
     *                     Verlaufspunkte.
     * @param pfeilAnfang  Die Spitze des Pfeils am Beginn.
     * @param pfeilEnde    Die Spitze des Pfeils am Ende.
     * @param anfFaktor    Multiplikativer Faktor für die Größe der Enden.
     * @param endFaktor    Multiplikativer Faktor für die Größe der Enden.
     *
     * @return  Der Pfeil aus mehreren Segmenten.
     */
    public Polygon2D segmentPfeilPol2D(
            final Polygon2D punkte,
            final List<Double> dicken,
            final Pfeilspitze pfeilAnfang,
            final Pfeilspitze pfeilEnde,
            final Vector2D            anfFaktor,
            final Vector2D            endFaktor) {

        Vector2D aktVekX;
        Vector2D aktVekY;
        Vector2D aktVek;
        LineSegment2D p, q;
       
        if (punkte == null || punkte.nPoints() < 2) {
            throw new RuntimeException("Zu wenige Segmente für Pfeil.");
        }
       
        List<Double> dick = dicken;
       
        if (dick == null) {
            dick = new ArrayList<Double>(punkte.nPoints());
            for (int i = 0; i < punkte.nPoints(); i++) {
                dick.add((double) this.pfeilDicke);
            }
        }
       
        Polygon2D pktList1 = new Polygon2D();
        Polygon2D pktList2 = new Polygon2D();

        // Pfeilanfang.
        Vector2D normAnf = new Vector2D(punkte.get(0));
        Vector2D orthoAnf;
        normAnf.sub(punkte.get(1));
        normAnf.norm();
        orthoAnf = new Vector2D(normAnf);
        orthoAnf.ortho();
        Iterator<Vector2D> it1 = pfeilAnfang.iterator();
        Polygon2D zwisch = new Polygon2D();
       
        while (it1.hasNext()) {
            aktVek = it1.next();
            aktVekX = new Vector2D(orthoAnf);
            aktVekY = new Vector2D(normAnf);
            aktVekX.mult(aktVek.x * anfFaktor.x * dick.get(0));
            aktVekY.mult(aktVek.y * anfFaktor.y * dick.get(0));
            aktVek = new Vector2D(aktVekX);
            aktVek.translate(aktVekY);
            aktVek.translate(punkte.get(0));
            zwisch.add(aktVek);
        }
       
        for (int i = zwisch.nPoints() - 1; i >= 0; i--) {
            pktList2.add(zwisch.get(i));
        }

        Polygon2D zwischPunkte;
       
        Vector2D c1 = new Vector2D(punkte.get(1));
        Vector2D c2;
        c1.sub(punkte.get(0));
        c1.ortho();
        c1.norm();
        c1.mult(dick.get(0) / 2);
       
        Vector2D p01 = new Vector2D(punkte.get(0));
        Vector2D p02 = new Vector2D(p01);
        Vector2D p11;
        Vector2D p12;
       
        p01.translate(c1);
        p02.sub(c1);
       
        pktList1.add(p01);
        pktList2.add(p02);
       
        for (int i = 1; i < punkte.nPoints() - 1; i++) {
            zwischPunkte = eas.math.geometry.Geometry2D.schnPkte(
                    punkte.get(i - 1),
                    punkte.get(i),
                    punkte.get(i + 1),
                    dick.get(i));
           
            p = new LineSegment2D(
                    zwischPunkte.get(0),
                    zwischPunkte.get(1));
            q = new LineSegment2D(
                    pktList1.get(pktList1.nPoints() - 1),
                    pktList2.get(pktList2.nPoints() - 1));
           
            if (p.intersects(q) == null) {
                pktList1.add(zwischPunkte.get(0));
                pktList2.add(zwischPunkte.get(1));
            } else {
                StaticMethods.log(StaticMethods.LOG_WARNING,
                              "Segment konnte nicht überschneidungsfrei "
                              + "platziert werden um Pixel: " + punkte.get(i),
                              this.pars,
                              "",
                              punkte.get(i));
                pktList1.add(zwischPunkte.get(0));
                pktList2.add(zwischPunkte.get(1));
            }
        }
       
        c2 = new Vector2D(punkte.get(punkte.nPoints() - 1));
        c2.sub(punkte.get(punkte.nPoints() - 2));
        c2.ortho();
        c2.norm();
        c2.mult(dick.get(punkte.nPoints() - 1) / 2);
       
        p11 = new Vector2D(punkte.get(punkte.nPoints() - 1));
        p12 = new Vector2D(p11);
       
        p11.translate(c2);
        p12.sub(c2);
       
        pktList1.add(p11);
        pktList2.add(p12);
       
        // Pfeilspitze.
        Vector2D normEnd = new Vector2D(punkte.get(punkte.nPoints() - 1));
        Vector2D orthoEnd;
        normEnd.sub(punkte.get(punkte.nPoints() - 2));
        normEnd.norm();
        orthoEnd = new Vector2D(normEnd);
        orthoEnd.ortho();

        Iterator<Vector2D> it2 = pfeilEnde.iterator();
       
        while (it2.hasNext()) {
            aktVek = it2.next();
            aktVekX = new Vector2D(orthoEnd);
            aktVekY = new Vector2D(normEnd);
            aktVekX.mult(aktVek.x * endFaktor.x * dick.get(dick.size() - 1));
            aktVekY.mult(aktVek.y * endFaktor.y * dick.get(dick.size() - 1));
            aktVek = new Vector2D(aktVekX);
            aktVek.translate(aktVekY);
            aktVek.translate(punkte.get(punkte.nPoints() - 1));
            pktList1.add(aktVek);
        }

        for (int i = pktList2.nPoints() - 1; i >= 0; i--) {
            pktList1.add(pktList2.get(i));
        }

        return pktList1;
    }
   
    public Polygon2D segmentPfeilPol2D(
            final Polygon2D punkte,
            final List<Double> dicken) {
        return this.segmentPfeilPol2D(
                punkte,
                dicken,
                ArrowMaster.EINFACHER_ABSCHLUSS,
                ArrowMaster.EINFACHE_SPITZE_2,
                new Vector2D(1, 1),
                new Vector2D(1, 1));
    }

    /**
     * Vereinfachter Pfeilerzeuger.
     *
     * @param punkte  Die Punkte, durch die der Pfeil laufen soll.
     * @return  Das Polygon.
     */
    public Polygon2D segmentPfeilPol2D(final Polygon2D punkte) {
        return this.segmentPfeilPol2D(
                punkte,
                null,
                ArrowMaster.EINFACHER_ABSCHLUSS,
                ArrowMaster.EINFACHE_SPITZE_2,
                new Vector2D(1, 1),
                new Vector2D(1, 1));
    }

    /**
     * Markiert die Ecken des Polygons durch Kreise in der Liste der zu
     * zeichnenden Objekte.
     *
     * @param p           Das Polygon.
     * @param l           Die Liste der Objekte.
     * @param markierung  Welche Ecken markiert werden sollen.
     * @param mark        Die Ausgabemerkmale für die markierten Knoten.
     * @param unmark      Die Ausgabemerkmale für die unmarkierten Knoten.
     * @param radius      Der Radius der Kreise.
     */
    public void markiereEcken(
            final Polygon p,
            final List<Object> l,
            final List<Integer> markierung,
            final AusgMerkm mark,
            final AusgMerkm unmark,
            final double radius) {
       
        Vector2D v;
        Circle2D k;
       
        for (int i = 0; i < p.npoints; i++) {
            if (markierung.contains(i)) {
                l.add(mark);
            } else {
                l.add(unmark);
            }
            v = new Vector2D(p.xpoints[i], p.ypoints[i]);
            k = new Circle2D(v.x, v.y, radius);
            l.add(k);
        }
    }
   
    /**
     * Erzeugt einen gestrichelten Pfeil mit verschiedenen Segmenttypen.
     *
     * @param punkte           Die Punkte des Pfeils.
     * @param dicken           Die Dicken des Pfeils.
     * @param pfeilAnfang      Das Pfeilanfangspolygon.
     * @param pfeilEnde        Das Pfeilendepolygon.
     * @param anfFaktor        Der Anfangsfaktor.
     * @param endFaktor        Der Endfaktor.
     * @param farben           Eine beliebige Liste sich abwechselnder
     *                         Ausgabemerkmale. Ist hier ein Eintrag
     *                         <code>null</code>, wird kein Ausgabemerkmal
     *                         für die Segmente definiert.
     * @param strichLenFaktor  Multiplikativer Faktor für die Länge eines
     *                         Segments bezogen auf die durchschnittliche
     *                         Dicke des Pfeils.
     * @param params           Die Parameter.
     * @return  Der gestrichelte Pfeil als Menge von Segmentpolygonen.
     */
    public Pol2DMitAusgMerkm[] gestrichelterPfeil(
            final Polygon2D punkte,
            final ArrayList<Double> dicken,
            final Pfeilspitze pfeilAnfang,
            final Pfeilspitze pfeilEnde,
            final Vector2D  anfFaktor,
            final Vector2D  endFaktor,
            final AusgMerkm[] farben,
            final double strichLenFaktor,
            final ParCollection params) {

        SegSpez[] segBeschr;
        final double konstFakt = 3 * strichLenFaktor;
        double strLaeng;
        double durchDick = 0;
        double durchAbst = 0;
        double anzPunkte;
        int j;
        AusgMerkm farbe;
        Pfeilspitze anfang;
        Pfeilspitze ende;
        double mehrPunkte;
        double anzSegmente;
       
        if (dicken != null) {
            for (int i = 0; i < dicken.size(); i++) {
                durchDick += Math.abs(dicken.get(i));
            }
            durchDick /= dicken.size();
        } else {
            durchDick = ConstantsZeichenModi.PFEIL_DICKE;
        }

        for (int i = 0; i < punkte.nPoints() - 2; i++) {
            durchAbst += punkte.get(i).distance(punkte.get(i + 1));
        }
        durchAbst /= punkte.nPoints() - 1;
        strLaeng = durchDick * konstFakt;
        anzPunkte = strLaeng / durchAbst;
       
        if (anzPunkte == 0) {
            return this.gestrichelterPfeil(
                    punkte,
                    dicken,
                    pfeilAnfang,
                    pfeilEnde,
                    anfFaktor,
                    endFaktor,
                    farben,
                    strichLenFaktor + 1,
                    params);
        }
       
        segBeschr = new SegSpez[(int) (punkte.nPoints() / anzPunkte + 1)];

        anzSegmente = punkte.nPoints() / anzPunkte;
        mehrPunkte = punkte.nPoints() % anzPunkte;
        anzPunkte += mehrPunkte / ((int) anzSegmente + 1);

        StaticMethods.log(
                StaticMethods.LOG_DEBUG,
                "Segmente werden hinzugefügt:",
                this.pars);
       
        j = 0;
        for (double i = 0; i <= punkte.nPoints() - anzPunkte; i += anzPunkte) {
            farbe = farben[j % farben.length];

            anfang = ArrowMaster.EINFACHER_ABSCHLUSS;
            ende = ArrowMaster.EINFACHER_ABSCHLUSS;
            if (i == 0) {
                anfang = pfeilAnfang;

                StaticMethods.log(
                        StaticMethods.LOG_DEBUG,
                        " " + anzPunkte,
                        this.pars,
                        "plain",
                        null);
            }
            if (i + anzPunkte > punkte.nPoints() - anzPunkte) {
                ende = pfeilEnde;
                anzPunkte = punkte.nPoints() - i - 1;

                StaticMethods.log(
                        StaticMethods.LOG_DEBUG,
                        " * " + j + " + " + anzPunkte + ".",
                        this.pars,
                        "plain",
                        null);
            }

            segBeschr[j] = new SegSpez(
                    farbe,
                    (int) i,
                    (int) (i + anzPunkte),
                    anfang,
                    ende,
                    anfFaktor,
                    endFaktor);
           
            j++;
        }

        return this.erzeugePfeilsegmente(punkte, dicken, segBeschr, params);
    }
   
    /**
     * Gibt eine beliebige Menge von beliebig zusammenh�ngenden Teilsegmenten
     * eines Pfeils zurück, wobei die Ausgabemerkmale für jedes zus.
     * Teilsegment einzeln eingestellt werden können.
     *
     * @param punkte       Die Punkte, durch die der Pfeil verlaufen soll.
     * @param dicken       Die Dicken des Pfeils an den Stellen der
     *                     Verlaufspunkte.
     * @param segBeschr    Die Beschreibungen einzelner Segmente.
     * @param params       Die Parameter.
     *
     * @return  Die Teilsegmente eines Pfeil aus mehreren Segmenten.
     */
    public Pol2DMitAusgMerkm[] erzeugePfeilsegmente(
            final Polygon2D punkte,
            final ArrayList<Double> dicken,
            final SegSpez[] segBeschr,
            final ParCollection params) {
        Pol2DMitAusgMerkm[] segmente = new Pol2DMitAusgMerkm[segBeschr.length];
        Polygon2D aktPol;
        Polygon2D aktPunkte = new Polygon2D();
        ArrayList<Double> aktDicken = new ArrayList<Double>();
        ArrowMaster zeichnen = new ArrowMaster(params);
        AusgMerkm ausg;
        GradientPaint grad;
        Vector2D p1Old, p2Old, p1, p2, v1, v2, zwisch;
        Color fuell, rahmen;
       
        for (int i = 0; i < segBeschr.length; i++) {
            if (segBeschr[i] != null) {
                aktPunkte.clear();
                aktDicken.clear();
                for (int j = segBeschr[i].getBeginn();
                 j <= segBeschr[i].getEnde(); j++) {
                    aktPunkte.add(punkte.get(j));
                    if (dicken != null) {
                        aktDicken.add(dicken.get(j));
                    } else {
                        aktDicken.add((double) ConstantsZeichenModi.PFEIL_DICKE);
                    }
                 }
               
                aktPol = zeichnen.segmentPfeilPol2D(
                        aktPunkte,
                        aktDicken,
                        segBeschr[i].getPfeilAnfang(),
                        segBeschr[i].getPfeilEnde(),
                        segBeschr[i].getFaktorAnfang(),
                        segBeschr[i].getFaktorEnde());
               
                ausg = segBeschr[i].getAusg();
               
                if (ausg != null && ausg.getGradPaint() != null) {
                    p1Old = new Vector2D(
                            ausg.getGradPaint().getPoint1().getX(),
                            ausg.getGradPaint().getPoint1().getY());
                    p2Old = new Vector2D(
                            ausg.getGradPaint().getPoint2().getX(),
                            ausg.getGradPaint().getPoint2().getY());
                    v1 = new Vector2D(aktPunkte.get(aktPunkte.nPoints() - 1));
                    v1.sub(aktPunkte.get(0));
                    v2 = new Vector2D(v1);
                    v2.ortho();
                   
                    p1 = new Vector2D(v1);
                    p1.mult(p1Old.y);
                    zwisch = new Vector2D(v2);
                    zwisch.mult(p1Old.x);
                    p1.translate(zwisch);
                    p1.translate(aktPunkte.get(0));
                   
                    p2 = new Vector2D(v1);
                    p2.mult(p2Old.y);
                    zwisch = new Vector2D(v2);
                    zwisch.mult(p2Old.x);
                    p2.translate(zwisch);
                    p2.translate(aktPunkte.get(0));
                   
                    grad = new GradientPaint(
                            (float) p1.x,
                            (float) p1.y,
                            ausg.getGradPaint().getColor1(),
                            (float) p2.x,
                            (float) p2.y,
                            ausg.getGradPaint().getColor2());
                   
                    fuell = ausg.getFuellFarbe();
                    rahmen = ausg.getRahmenFarbe();
                   
                    ausg = new AusgMerkm(
                            grad,
                            ausg.holeRahmenDrucken(),
                            ausg.holeFuellungDrucken());
                   
                    ausg.setFuellFarbe(fuell);
                    ausg.setRahmenFarbe(rahmen);
                }
                segmente[i] = new Pol2DMitAusgMerkm(
                        aktPol,
                        ausg);
            }
        }
       
        return segmente;
    }
   
    /**
     * @return  Alle Pfeilspitzen.
     */
    public static ArrayList<Pfeilspitze> getSpitzen() {
        ArrayList<Pfeilspitze> spitzen = new ArrayList<Pfeilspitze>(7);
       
        spitzen.add(ArrowMaster.DOPPELSPITZES_ENDE);
        spitzen.add(ArrowMaster.EINFACHE_SPITZE_1);
        spitzen.add(ArrowMaster.EINFACHE_SPITZE_2);
        spitzen.add(ArrowMaster.EINFACHE_SPITZE_3);
        spitzen.add(ArrowMaster.EINFACHER_ABSCHLUSS);
        spitzen.add(ArrowMaster.KUGEL_ENDE);
        spitzen.add(ArrowMaster.RUECK_PFEIL);
        spitzen.addAll(ArrowMaster.WEITERE_SPITZEN);
       
        return spitzen;
    }
   
//    /**
//     * Main-Methode.
//     *
//     * @param args  Argumente.
//     */
//    public static void main(final String[] args) {
//        ParCollection params = new ParCollection(args);
//        params.ergaenze();
//        PfeilMaster zeichnen = new PfeilMaster(params);
//        List<Object> l = new ArrayList<Object>();
//        Polygon2D bez2 = new Polygon2D();
//
//        bez2 = Geometry2D.bezierKurve(
//                new Vector2D(0, 0),
//                new Vector2D(50, 0),
//                new Vector2D(50, -20),
//                new Vector2D(100, -20),
//                0.0001);
//       
//        bez2 = bez2.normalisiere(params);
//
//        Polygon2D seg = zeichnen.segmentPfeilPol2D(
//                bez2,
//                null,
//                PfeilMaster.DOPPELSPITZES_ENDE,
//                PfeilMaster.EINFACHE_SPITZE_1,
//                new Vector2D(1, 1),
//                new Vector2D(1, 1));
//
//        l.add(seg.toPol(5, Vector2D.NULL_VECTOR));
//        l.add(0, new AusgMerkm(Color.black, Color.yellow, true, true));
//        params.setStdPfad(
//          "C:\\Eig");
//       
//        Geometry2D.saveObjectsToFile(l, "luke", "png", params);
//    }
}
TOP

Related Classes of eas.startSetup.marbBuilder.zeichenModi.ArrowMaster

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.