Package fmg.fmg8.graphVis.zeichenModi

Source Code of fmg.fmg8.graphVis.zeichenModi.Geometrie2D

/*
* Datei:            Geometrie2D.java
* Autor(en):        Lukas K�nig
* Java-Version:     6.0
* Letzte Aenderung: 23.12.2008
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/

package fmg.fmg8.graphVis.zeichenModi;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;

import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.statistik.Parametersatz;
import fmg.fmg8.umgebung2D.Vektor2D;


/**
* Kollektion allgemeiner geometrischer Methoden f�r den 2-dimensionalen
* Raum.
*
* @author Lukas K�nig
*/
public class Geometrie2D {

    /**
     * Berechnet eine Bezierkurve im Polygon (p1, p2, p3, p4). Der Abstand der
     * Punkte wird durch <code>step</code> (0..1) gesteuert.
     *
     * @param p0    Punkt.
     * @param p1    Punkt.
     * @param p2    Punkt.
     * @param p3    Punkt.
     * @param step  Schrittgr��e.
     *
     * @return  Die Punkte der Bezierkurve.
     */
    public static Polygon2D bezierKurve(
            final Vektor2D p0,
            final Vektor2D p1,
            final Vektor2D p2,
            final Vektor2D p3,
            final double step) {
       Polygon2D kurve = new Polygon2D((int) (1 / step) + 1);
       Vektor2D punkt;
       Vektor2D dreiP0 = (new Vektor2D(p0));
       Vektor2D dreiP1 = (new Vektor2D(p1));
       Vektor2D dreiP2 = (new Vektor2D(p2));
       Vektor2D sechsP1 = (new Vektor2D(p1));
       dreiP0.mult(3);
       dreiP1.mult(3);
       dreiP2.mult(3);
       sechsP1.mult(6);
       Vektor2D punkt2, punkt3;
       double tQuad, tKub;

       for (double t = 0; t <= 1; t += step) {
           tQuad = t * t;
           tKub = t * tQuad;
          
           punkt = new Vektor2D(dreiP1);
           punkt.sub(p0);
           punkt.sub(dreiP2);
           punkt.add(p3);
           punkt.mult(tKub);
          
           punkt2 = new Vektor2D(dreiP0);
           punkt2.sub(sechsP1);
           punkt2.add(dreiP2);
           punkt2.mult(tQuad);
          
           punkt3 = new Vektor2D(dreiP1);
           punkt3.sub(dreiP0);
           punkt3.mult(t);
          
           punkt.add(punkt2);
           punkt.add(punkt3);
           punkt.add(p0);
          
           kurve.add(punkt);
       }
      
       return kurve;
    }
   
    /**
     * Gibt ein Kreis-Polygon zur�ck.
     *
     * @param mitte   Der Mittelpunkt.
     * @param radius  Der Radius.
     * @param anzahl  Die Schrittzahl.
     *
     * @return  Das Kreispolygon.
     */
    public static Polygon kreis(final Vektor2D mitte,
                          final double radius,
                          final long anzahl) {
        double schritt = 2 * Math.PI / anzahl;
        Polygon kreis = new Polygon();
        double winkel;
        double x;
        double y;
       
        for (winkel = 0; winkel <= 2 * Math.PI; winkel += schritt) {
            x = mitte.x + radius * Math.sin(winkel);
            y = mitte.y + radius * Math.cos(winkel);

            kreis.addPoint((int) x, (int) y);
        }
       
        return kreis;
    }

    /**
     * Zeichnet eine Menge von Polygonen und (entsprechend der Vereinbarung
     * im Interface ZeichenKit codierten) Strings, die als Liste �bergeben
     * werden.
     *
     * @param g         Das Grafikobjekt, in das gezeichnet werden soll.
     * @param polListe  Die Liste der Polygone.
     * @param params    Die Parameter.
     */
    public static void maleObjListe(
            final Graphics     g,
            final List<Object> polListe,
            final Parametersatz params) {
        Iterator<Object> it;
        Object           obj;
        int              x;
        int              y;
        String           str;
        AusgMerkm  ausgabe;
        Kreis2D          kreis;
        boolean          fuellungDrucken = Konstanten.STANDARD_FUELL_DRUCKEN;
        boolean          rahmenDrucken   = Konstanten.STANDARD_RAHMEN_DRUCKEN;
        Color            fuellungFarbe   = Konstanten.STANDARD_FUELL_FARBE;
        Color            rahmenFarbe     = Konstanten.STANDARD_RAHMEN_FARBE;
        String           schriftart;
        int              schriftstil;
        int              schriftgroesse;
        GradientPaint    gp = null;
       
        Graphics2D g2 = (Graphics2D) g;
        BasicStroke s1 = new BasicStroke(BasicStroke.JOIN_MITER);
        BasicStroke s2 = new BasicStroke(BasicStroke.CAP_BUTT);
       
        if (params.getEinfacheDar()) {
            g2.setStroke(s2);
        } else {
            g2.setStroke(s1);
        }

        it = polListe.iterator();
        while (it.hasNext()) {
            obj = it.next();
            if (obj.getClass().equals(Polygon.class)) {
                if (fuellungDrucken) {
                    if (gp == null) {
                        g2.setColor(fuellungFarbe);
                    } else {
                        g2.setPaint(gp);
                    }
                   
                    g2.fillPolygon((Polygon) obj);
                }
                if (rahmenDrucken) {
                    g2.setColor(rahmenFarbe);
                    g2.drawPolygon((Polygon) obj);
                }
            } else if (obj.getClass().equals(Kreis2D.class)) {
                kreis = (Kreis2D) obj;
                if (fuellungDrucken) {
                    if (gp == null) {
                        g2.setColor(fuellungFarbe);
                    } else {
                        g2.setPaint(gp);
                    }
                    g2.fillOval(
                            (int) (kreis.holeMitte().x - kreis.holeRadius()),
                            (int) (kreis.holeMitte().y - kreis.holeRadius()),
                            (int) (kreis.holeRadius() * 2),
                            (int) (kreis.holeRadius() * 2));
                }
                if (rahmenDrucken) {
                    g2.setColor(rahmenFarbe);
                    g2.drawOval(
                            (int) (kreis.holeMitte().x - kreis.holeRadius()),
                            (int) (kreis.holeMitte().y - kreis.holeRadius()),
                            (int) (kreis.holeRadius() * 2),
                            (int) (kreis.holeRadius() * 2));
                }
            } else if (obj.getClass().equals(AusgMerkm.class)) {
                ausgabe         = (AusgMerkm) obj;
                fuellungDrucken = ausgabe.holeFuellungDrucken();
                rahmenDrucken   = ausgabe.holeRahmenDrucken();
                fuellungFarbe   = ausgabe.getFuellFarbe();
                rahmenFarbe     = ausgabe.getRahmenFarbe();
                schriftart      = ausgabe.getFontName();
                schriftstil     = ausgabe.getFontStyle();
                schriftgroesse  = ausgabe.getFontSize();
                g2.setFont(new Font(schriftart, schriftstil, schriftgroesse));
               
                gp = ausgabe.getGradPaint();
            } else {
                x   = ((Integer) obj).intValue();
                obj = it.next();
                y   = ((Integer) obj).intValue();
                obj = it.next();
                str = (String) obj;
                g2.setColor(rahmenFarbe);
                g2.drawString(str, x, y);
            }
        }

        // R�cksetzen der Vordergrundfarbe.
        g2.setColor(Konstanten.STANDARD_RAHMEN_FARBE);
    }


    /**
     * Gibt die St�tzpunkte einer Kurve zur�ck, die eine Ann�herung an eine
     * Kurve aus beliebig vielen Einzelst�cken aus Bezierkurven dritten Grades
     * ist.
     *
     * @param p       Die St�tzpunkte der Bezierkurven.
     * @param v       Die Vektoren an den inneren St�tzpunkten.
     * @param k       Die Multiplikatoren f�r die inneren Vektoren.
     * @param step    Die Schrittweite bei der Bezierberechnung..
     * @param params  Die Parameter.
     *
     * @return  Die Kurve aus Beziersegmenten.
     */
    public static Polygon2D multiBezier(
            final Polygon2D p,
            final Polygon2D v,
            final ArrayList<Double> k,
            final double step,
            final Parametersatz params) {
        Polygon2D kurve
          = new Polygon2D((int) ((p.size() - 1) / (step + 1)));
        Polygon2D bezier;
        Vektor2D v1, v2;
       
        if (p.size() < 2 || p.size() != v.size() || v.size() != k.size() + 2) {
            SonstMeth.log(SonstMeth.LOG_ERROR,
                          "Falsche Angaben bei Aufruf von multiBezier",
                          params);
        }
       
        v1 = new Vektor2D(v.get(0));
        v2 = new Vektor2D(p.get(1));
        v1.add(p.get(0));
        v2.sub(v.get(1));
       
        bezier = fmg.fmg8.graphVis.zeichenModi.Geometrie2D.bezierKurve(
                p.get(0), v1, v2, p.get(1), step);
        kurve.addAll(bezier);
       
        for (int i = 1; i < p.size() - 1; i++) {
            v1 = new Vektor2D(v.get(i));
            v2 = new Vektor2D(p.get(i + 1));
            v1.mult(k.get(i - 1));
            v1.add(p.get(i));
            v2.sub(v.get(i + 1));
            bezier = fmg.fmg8.graphVis.zeichenModi.Geometrie2D.bezierKurve(
                    p.get(i), v1, v2, p.get(i + 1), step);
            kurve.addAll(bezier);
        }
       
        return kurve;
    }
   
    /**
     * Ermittelt einen umschlie�enden Rahmen um alle Objekte in der Liste.
     *
     * @param objekte  Die Objekte.
     *                  
     * @return         Die linke obere und rechte untere Koordinate des
     *                 Rahmens.
     */
    public static Polygon2D rahmen(final List<Object> objekte) {
        Vektor2D maxPkt = new Vektor2D(Double.NEGATIVE_INFINITY,
                                   Double.NEGATIVE_INFINITY);
        Vektor2D minPkt = new Vektor2D(Double.POSITIVE_INFINITY,
                                   Double.POSITIVE_INFINITY);
        Vektor2D zwischMax = new Vektor2D(Vektor2D.NULL_VEKTOR);
        Vektor2D zwischMin = new Vektor2D(Vektor2D.NULL_VEKTOR);
        Polygon2D rahmen = new Polygon2D(2);
        int stringPos = 0;
        int stringX = 0;
        int stringY = 0;
       
        for (Object o : objekte) {
            if (o.getClass().equals(Polygon.class)) {
                Polygon p = (Polygon) o;
                zwischMax.x = p.getBounds().getMaxX();
                zwischMax.y = p.getBounds().getMaxY();
                zwischMin.x = p.getBounds().getMinX();
                zwischMin.y = p.getBounds().getMinY();
            } else if (o.getClass().equals(Kreis2D.class)) {
                Kreis2D k = (Kreis2D) o;
                zwischMax = new Vektor2D(k.holeMitte());
                zwischMin = new Vektor2D(k.holeMitte());
                zwischMax.add(new Vektor2D(k.holeRadius(), k.holeRadius()));
                zwischMin.sub(new Vektor2D(k.holeRadius(), k.holeRadius()));
            } else if (o.getClass().equals(Integer.class)) {
                if (stringPos == 0) {
                    stringX = (Integer) o;
                    stringPos++;
                } else {
                    stringY = (Integer) o;
                    stringPos = 0;
                }
            } else if (o.getClass().equals(String.class)) {
                String s = (String) o;
                double stringHeight = 10;
                double stringWidth = s.length() * 6;
                zwischMin = new Vektor2D(stringX, stringY - stringHeight);
                zwischMax = new Vektor2D(stringX + stringWidth, stringY);
            } else {
                zwischMax = new Vektor2D(maxPkt);
                zwischMin = new Vektor2D(minPkt);
            }

            if (zwischMax.x > maxPkt.x) {
                maxPkt.x = zwischMax.x;
            }
            if (zwischMax.y > maxPkt.y) {
                maxPkt.y = zwischMax.y;
            }
            if (zwischMin.x < minPkt.x) {
                minPkt.x = zwischMin.x;
            }
            if (zwischMin.y < minPkt.y) {
                minPkt.y = zwischMin.y;
            }
        }
       
        rahmen.add(minPkt);
        rahmen.add(maxPkt);
       
        return rahmen;
    }

    /**
     * Erzeugt eine ausgabef�hige Objektliste aus einer Liste von Polygonen
     * mit zugeh�rigen Ausgabemerkmalen.
     *
     * @param polAusg     Die Polygone mit Ausgabemerkmalen.
     * @param skalierung  Die Skalierung.
     * @param versch      Die Verschiebung.
     *
     * @return  Die ausgabef�hige Objektliste.
     */
    public static List<Object> erzeugeObjList(
            final Pol2DMitAusgMerkm[] polAusg,
            final double skalierung,
            final Vektor2D versch) {
        List<Object> oL = new ArrayList<Object>(2 * polAusg.length);
        AusgMerkm aktAusg;
        Polygon2D aktPol;
        Point2D p1;
        Point2D p2;
        GradientPaint grad;
        Color fuell, rahmen;
       
        for (int i = 0; i < polAusg.length; i++) {
            if (polAusg[i] != null) {
                aktAusg = polAusg[i].getAusg();
                aktPol = polAusg[i].getPol();
               
                if (aktAusg != null) {
                    if (aktAusg.getGradPaint() != null) {
                        p1 = aktAusg.getGradPaint().getPoint1();
                        p2 = aktAusg.getGradPaint().getPoint2();
   
                        grad = new GradientPaint(
                                (int) (p1.getX() * skalierung),
                                (int) (p1.getY() * skalierung),
                                aktAusg.getGradPaint().getColor1(),
                                (int) (p2.getX() * skalierung),
                                (int) (p2.getY() * skalierung),
                                aktAusg.getGradPaint().getColor2());
                       
                        fuell = aktAusg.getFuellFarbe();
                        rahmen = aktAusg.getRahmenFarbe();
                       
                        aktAusg = new AusgMerkm(
                                grad,
                                aktAusg.holeRahmenDrucken(),
                                aktAusg.holeFuellungDrucken());
                       
                        aktAusg.setFuellFarbe(fuell);
                        aktAusg.setRahmenFarbe(rahmen);
                    }
                   
                    oL.add(aktAusg);
                }
               
                oL.add(aktPol.toPol(skalierung, versch));
            }
        }
       
        return oL;
    }
   
   /**
    * Speichert eine Liste von Grafikobjekten als JPG-Image ab.
    * Die Liste kann Objekte folgenden Typs enthalten:<BR>
    * - Polygon (wird direkt gezeichnet mit den aktuellen Einstellungen
    *   f�r Hintergrund-, Vordergrundfarbe und Rahmeneigenschaften),<BR>
    * - Kreisklasse (zeichnet wie oben direkt einen Kreis),<BR>
    * - Ausgabemerkmale (setzt Farben, Rahmeneigenschaften usw. f�r alle
    *   NACHFOLGENDEN Objekte) und<BR>
    * - aufeinanderfolgend zwei Integer-Objekte x und y und ein String-Objekt
    *   (wird als String gezeichnet, wobei die linke untere Ecke an den
    *   Koordinaten (x / y) ist).
    *
    * @param oL         Zu speichernde Liste von Objekten.
    * @param filename   Dateiname (ohne Erweiterung) unter dem das Bild
    *                   abgelegt werden soll.
    * @param modus      Der Speichermodus ("jpg", "png", etc.)
    * @param params     Die Parameter.
    **/
    public static void saveObjectsToFile(
            final List<Object> oL,
            final String filename,
            final String modus,
            final Parametersatz params) {
        boolean vorhanden = false;
        String datNam;

        if (filename.substring(filename.length() - 4).toLowerCase()
                .equals("." + modus.toLowerCase())) {
            datNam = params.getStdPfad()
                + File.separator
                + filename;
        } else {
            datNam = params.getStdPfad()
                + File.separator
                + filename
                + "." + modus;
        }
       
        for (int i = 0; i < ImageIO.getWriterFormatNames().length; i++) {
            if (modus.equals(ImageIO.getWriterFormatNames()[i])) {
                vorhanden = true;
            }
        }

        if (!vorhanden) {
            SonstMeth.log(SonstMeth.LOG_ERROR,
                    "Grafikmodus nicht vorhanden: " + modus,
                    params);
            SonstMeth.log(SonstMeth.LOG_ERROR,
                    "Grafik nicht gespeichert: " + datNam,
                    params);
            return;
        }
       
        Polygon2D rahmen = fmg.fmg8.graphVis.zeichenModi.Geometrie2D.rahmen(oL);
        Vektor2D rahmenMin = rahmen.get(0);
        Vektor2D rahmenMax = rahmen.get(1);
        rahmenMin.sub(new Vektor2D(10, 10));
        rahmenMax.add(new Vektor2D(10, 10));

        double breite = rahmenMax.x - rahmenMin.x;
        double hoehe = rahmenMax.y - rahmenMin.y;
       
        if (breite <= 0) {
            breite = 1;
        }
       
        if (hoehe <= 0) {
            hoehe = 1;
        }
       
        BufferedImage buffImg = new BufferedImage(
                (int) breite,
                (int) hoehe,
                BufferedImage.TYPE_INT_RGB);
       
        Graphics2D g2 = (Graphics2D) buffImg.getGraphics();
       
        g2.translate(-rahmenMin.x, -rahmenMin.y);
       
        g2.setStroke(new BasicStroke(BasicStroke.JOIN_MITER));
        g2.setColor(Color.white);
        g2.fillRect((int) rahmenMin.x,
                    (int) rahmenMin.y,
                    (int) (rahmenMax.x - rahmenMin.x),
                    (int) (rahmenMax.y - rahmenMin.y));

        fmg.fmg8.graphVis.zeichenModi.Geometrie2D.maleObjListe(g2, oL, params);
       
        try {
            ImageIO.write(buffImg, modus, new File(datNam));
        } catch (final Exception e) {
            SonstMeth.log(SonstMeth.LOG_ERROR,
                          "Datei konnte nicht gespeichert werden: "
                               + datNam,
                               params);
            return;
        }
       
        SonstMeth.log(SonstMeth.LOG_INFO,
                "Graphik gespeichert in: "
                     + datNam,
                     params);
    }

    /**
     * Speichert ein Polygon als Grafik ab.
     *
     * @param p          Zu speicherndes Polygon.
     * @param filename   Dateiname (ohne oder mit Erweiterung) unter dem das
     *                   Bild abgelegt werden soll.
     * @param modus      Der Speichermodus ("jpg", "png", etc.)
     * @param params     Die Parameter.
     */
     public static void saveSinglePolygonToFile(
             final Polygon p,
             final String filename,
             final String modus,
             final Parametersatz params) {
         ArrayList<Object> oL = new ArrayList<Object>(1);
         oL.add(p);
         fmg.fmg8.graphVis.zeichenModi.Geometrie2D.saveObjectsToFile(
                 oL,
                 filename,
                 modus,
                 params);
     }
    
     /**
      * Berechnet jeweils auf beiden Seiten einer Kurve aus zwei
      * Streckensegmenten Schnittpunkte der vier die Kurve im Abstand "dicke"
      * umh�llenden, zu den Teilstrecken parallelen Geraden.
      *
      * @param p1     Der erste Punkt.
      * @param p2     Der zweite Punkt.
      * @param p3     Der dritte Punkt.
      * @param dicke  Die Dicke des Pfeils an der Stelle.
      *
      * @return  Die beiden Schnittpunkte.
      */
     public static Polygon2D schnPkte(
             final Vektor2D p1,
             final Vektor2D p2,
             final Vektor2D p3,
             final double dicke) {
        
         Polygon2D pkte = new Polygon2D(2);
        
         Vektor2D v1 = new Vektor2D(p2.x - p1.x, p2.y - p1.y);
         Vektor2D v2 = new Vektor2D(p3.x - p2.x, p3.y - p2.y);
         Vektor2D c1 = new Vektor2D(v1.y, -v1.x);
         Vektor2D c2 = new Vektor2D(v2.y, -v2.x);
         Vektor2D p11;
         Vektor2D p12;
         Vektor2D p01;
         Vektor2D p02;
         Gerade2D g1, h1, g2, h2;
        
         c1.mult(dicke / (c1.laenge() * 2));
         c2.mult(dicke / (c2.laenge() * 2));
        
         p11 = new Vektor2D(p1);
         p12 = new Vektor2D(p3);
         p01 = new Vektor2D(p1);
         p02 = new Vektor2D(p3);
        
         p11.add(c1);
         p12.add(c2);
         p01.sub(c1);
         p02.sub(c2);
        
         v1.laengeFestlegen(p1.distanz(p2));
         v2.laengeFestlegen(p2.distanz(p3));
        
         g1 = new Gerade2D(p11, v1);
         h1 = new Gerade2D(p12, v2);
         g2 = new Gerade2D(p01, v1);
         h2 = new Gerade2D(p02, v2);
        
         pkte.add(g1.schnPktSpezial(h1));
         pkte.add(g2.schnPktSpezial(h2));
        
         return pkte;
     }
}
TOP

Related Classes of fmg.fmg8.graphVis.zeichenModi.Geometrie2D

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.