# Zeichnen von Generalpath (Shape)



## elli (21. Aug 2011)

Hallo,
habe eine Frage zu einem Generalpath der aus der Umrisslinie eines Shape erzeugt wird - also

```
Generalpath gp = new Generalpath (Shape s);
```
Der Shape besteht aus einem Kreis Segment, von dem ein Dreieck abgezogen wurde ( wie ein Kuchenstück ohne die Spitze).
Ich würde nun gerne nur einzelne Bereiche der Umrisslinie zeichnen, nämlich die Runde Seite und eine
angrenzende Seite.
Geht das mit dem Generalpath? Kommt man irgendwie an die einzelnen Punkte des Pfades ran (also an die Eckpunkte, nicht jeden einzelnen Punkt der Umrisslinie) bzw. an die einzelnen Segmente zwischen den Eckpunkten??


----------



## Marco13 (21. Aug 2011)

Hmja, man könnte mit einem PathIterator da langlaufen, aber es könnte schwierig sein, die richtigen Segmente zu erkennen... Vermutlich wäre es deutlich einfacher und sauberer, wenn die zu zeichnenden Segmente noch einzeln vorliegen, d.h. dass man genau DIE als ein Shape bzw. einen Path2D hat... (Irgendwie muss dieses Shape ja auch entstanden sein!?)


----------



## Harry Kane (21. Aug 2011)

ich würde die Methode mit dem PathIterator vorziehen. Da die sichtbare Umrandung einer Shape aus nur 3 Segmenttypen besteht (Linie, quadratische und kubische Kurve), und es zu jedem Segmenttyp eine passende Shape-Implementierung gibt, kann man mit wenig Aufwand am PathIterator langwandern, den Segmenttyp feststellen, und aus den Koordinaten eine entsprechende Shape erzeugen. Im unten angehängten Beispiel wurden die erzeugten Segment-Shapes in eine ArrayList gepackt und separat mit verschiedenen Farben gezeichnet. In existierendem Code könnte man sich eine Hilfsmethode definieren, die aus einem übergegebenen Shape eine Liste von Shapes macht, die die Umrandungssegmente definieren.


```
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.QuadCurve2D;
import java.util.Arrays;
import java.util.ArrayList;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class PathIteratorExtractor extends JComponent{
    private Dimension preferredSize = new Dimension(200,200);  
    ArrayList<Shape> shapes = new ArrayList<Shape>();
    
    public static void main(String[] args){
        JFrame frame = new JFrame("Path Iterator In Action");
        frame.getContentPane().add(new PathIteratorExtractor());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
    public PathIteratorExtractor(){
        Shape s = new Ellipse2D.Double(5, 5, 100, 100);
        PathIterator pi = s.getPathIterator(null);
        shapes.clear();
        double[] coords = new double[6];
        int result = -1;
        double[] nextOrigin = new double[2];
        double[] lastMoveTo = new double[2];
        while(!pi.isDone()){
            result = pi.currentSegment(coords);
            switch(result){
                case PathIterator.SEG_MOVETO:
                    System.out.println("MoveTo " + Arrays.toString(new double[]{coords[0], coords[1]}));
                    nextOrigin[0] = coords[0];
                    nextOrigin[1] = coords[1];
                    lastMoveTo[0] = coords[0];
                    lastMoveTo[1] = coords[1];
                    break;
                case PathIterator.SEG_CLOSE:
                    System.out.println("Line back to " + Arrays.toString(new double[]{lastMoveTo[0], lastMoveTo[1]}));
                    shapes.add(new Line2D.Double(nextOrigin[0], nextOrigin[1], lastMoveTo[0], lastMoveTo[1]));
                    nextOrigin[0] = lastMoveTo[0];
                    nextOrigin[1] = lastMoveTo[1];
                    break;
                case PathIterator.SEG_LINETO:
                    System.out.println("LineTo " + Arrays.toString(new double[]{coords[0], coords[1]}));
                    shapes.add(new Line2D.Double(nextOrigin[0], nextOrigin[1], coords[0], coords[1]));
                    nextOrigin[0] = coords[0];
                    nextOrigin[1] = coords[1];
                    break;
                case PathIterator.SEG_QUADTO:
                    System.out.println("QuadTo " + Arrays.toString(new double[]{coords[0], coords[1], coords[2], coords[3]}));
                    shapes.add(new QuadCurve2D.Double(nextOrigin[0], nextOrigin[1], coords[0], coords[1], coords[2], coords[3]));
                    nextOrigin[0] = coords[2];
                    nextOrigin[1] = coords[3];
                    break;
                case PathIterator.SEG_CUBICTO:
                    System.out.println("CubicTo " + Arrays.toString(new double[]{coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]}));
                    shapes.add(new CubicCurve2D.Double(nextOrigin[0], nextOrigin[1], coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]));
                    nextOrigin[0] = coords[4];
                    nextOrigin[1] = coords[5];
                    break;
            }
            pi.next();
        }
    }
    public void paintComponent(Graphics g){  
        Graphics2D g2 = (Graphics2D)g;
        Color[] colors = new Color[]{Color.RED, Color.GREEN, Color.ORANGE, Color.BLUE, Color.WHITE, Color.BLACK};
        for(int i = 0; i < shapes.size(); i++){
            g2.setPaint(colors[i]);
            g2.draw(shapes.get(i));
        }     
    }  
    public Dimension getPreferredSize(){  
          return preferredSize;  
    }  
}
```


----------



## xehpuk (22. Aug 2011)

Marco13 hat gesagt.:


> Vermutlich wäre es deutlich einfacher und sauberer, wenn die zu zeichnenden Segmente noch einzeln vorliegen, d.h. dass man genau DIE als ein Shape bzw. einen Path2D hat... (Irgendwie muss dieses Shape ja auch entstanden sein!?)


Mal kurz die Verbindung schaffen: http://www.java-forum.org/awt-swing-swt/122978-zeichnen-sonderformen.html

Direkt weiterhelfen kann ich jedoch nicht.


----------



## killersponge (23. Aug 2011)

hey sag mal kannst du nicht einfach die eckpunkte errechnen und dan ein polygon draus machen??

du bräuchtest den radius des urspünglichen kreises also des ganzen kuchen
den winkel des stücks im bogenmaß und die länge der abgeschnittenen kanten

dan ein bisschen sinus hier und cosinus da und bum haste die eckpunkte

dann gibts ja bei den standart zeichen methoden dese drawPolygon oder so ähnlich^^

und fertig^^


----------

