2D-Grafik Linie hat Löcher

jappel

Mitglied
Hi das ist mein erster Post hier.. ich arbeite seit 2 Tagen daran und komme nicht weiter.

Ich bin dabei ein 2-dim lineares dgl system grafisch darzustellen. Das dgl system wird numerisch / inkrementweise berechnet und als 2 linien dargestellt. Bei einer sehr grossen steigung werden nicht alle Punkte dargestellt bzw einige ausgelassen.. Die Linie wird mit "Line2D.Double" dargestellt und das Applet ist runnable d.h. bei jedem durchlauf wird ein inkrement berechnet und als fortlaufende linie dargstellt. gesteuert wird das mit thread.sleep..

ich freue mich über jeden Hinweis.

gute nacht
 

Dit_

Bekanntes Mitglied
Hi, versuch mal Antialiasing zu aktivieren


Java:
public void paintComponent(Graphics gr) {
    Graphics2D gr2d = (Graphics2D)gr;
    //...

    gr2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON);
}
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Beschreib' mal genauer. Wie wird der Inkrement zur Linie hinzugefügt, und wie wird die Linie gezeichnet? Das 'sleep' steht hoffentlich nicht in der paint-Methode... und... wenn du irgendwo ein "getGraphics" stehen hast, liegt's im Zeifelsfall DAran ;)
 

jappel

Mitglied
Danke für die "Renderinghints" - hat es vielleicht etwas besser gemacht aber das Problem bleibt..

Hier ist der Codeaufbau:

Java:
public class Test extends JApplet implements Runnable, ChangeListener{
	

.....
     
// Hier werden dem drawing_panel werte übergeben   
   
     public void run() {
         while (true){
        	 eulers=euler(lasteulers,n);
        	 drawing_panel.setValues(n*h,n*(+1)*h,lasteulers,eulers); 
        	 lasteulers=eulers;
        	 n=n+1;
             try {
                 Thread.sleep((long)1/100);
             } catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
     }

}

//und hier ist das JPanel

public class DrawingPanel extends JPanel {

	boolean clrPanel=true;

	double xend, xstart;
	
	double[] lastEuler=new double[2];
	double[] newEuler=new double[2];
	


   DrawingPanel () {

       setBackground (Color.WHITE);
  
   } 
   
   public void update(Graphics g){
	   
	   paintComponent(g);
	   
   }
   
   

   public void setValues(double x0, double x1, double[] lastE, double[] newE ){
	   xstart=x0;
	   xend=x1;
	   lastEuler=lastE;
	   newEuler=newE;
	   
	   repaint();

   
   }
  
   

   public void paintComponent(Graphics g)   {
    // Paint background
    

   // Set current drawing color
  
    Graphics2D g2 = (Graphics2D) g;
    
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
    	      RenderingHints.VALUE_ANTIALIAS_ON);

    g2.setStroke(new BasicStroke(2));
    

   
   
   





    g2.setColor(Color.blue);
    g2.draw(new Line2D.Double(xstart, Math.atan(-lastEuler[0])*getHeight()/4,xend,  Math.atan(-newEuler[0])*getHeight()/4));       
    g2.setColor(Color.red);
    g2.draw(new Line2D.Double(xstart, Math.atan(-lastEuler[1])*getHeight()/4,xend,  Math.atan(-newEuler[1])*getHeight()/4));
    

   
   	}
   }
 

Marco13

Top Contributor
Ja, der Zeichenablauf stimmt so nicht ganz. (BTW: (long)1/100 ist 0, ganzzahlige division und so...)

Eigentlich müßte es
Code:
public void paintComponent(Graphics g)   {
    [b]super.paintComponent(g);[/b]
heißen, und dann würde er immer nur das letzte Stück anzeigen. In der paintComponent muss IMMER ALLES gezeichnet werden. Dass es im Moment "teilweise" funktioniert ist eher ein zufälliges Artefakt.

Aber sooo viel muß man da vermutlich gar nicht ändern. Wenn in dem DrawingPanel ein Linienzug gezeichnet werden soll, könnte man dort einen
private Path2D.Double path = new Path2D.Double();
reinlegen. Den kann man mit path.moveTo(x,y) an eine Bestimmte Starposition setzen, und mit path.lineTo(x,y) dann Liniensegmente anhängen, vom letzten Endpunkt ausgehend (die lineTo würdest du dann in deiner "setValues"-Methode aufrufen).

In der paintComponent würde dann nur stehen
g.draw(path);

Natürlich sollte man das ganze verallgemeinern: Man sollte dort eine List<Path2D.Double> reinlegen (die bei dir im Moment 2 Elemente enthalten würde), und die setValues würde dann eher
public void appendPointToPath(int pathIndex, double x, double y)
oder so heißen, damit man "beliebig viele" Paths damit zeichnen kann (die Zahl '2' existiert nicht). Aber das liegt dann ganz bei dir.
 

jappel

Mitglied
Danke - das hört sich vernünftig an. Ich werde das mal so versuchen. Allerdings bin ich nicht sehr zuversichtlich, da ich in einem vorigen Anlauf statt des DrawingPanels einen Canvas benutzt hatte und da hatte ich die paint() methode benutzt und das gleiche problem gehabt (bei der paint(g) methode stellt sich das problem mit "super.paint.." garnicht oder?). Trotzdem setze ich deinen vorschlag mal um.. danke und vg
 

Marco13

Top Contributor
Doch, sicher, auch bei Canvas sollte man in paint erst super.paint aufrufen (auch wenn sie AFAIK nichts macht). Aber Canvas ist AWT, das sollte man in Swing nicht verwenden. Unabhängig davon: Das hat auf das Problem an sich keinen direkten Einfluß...
 

jappel

Mitglied
Hi ich habe deinen vorschlag so umgesetzt wie ich ihn verstanden habe und kriege jetzt einen outofbounds error..

was ich gemacht ist: in Test.java die run() methode leicht angepasst:

Java:
public void run() {
         while (true){
             drawing_panel.setValues((n+1)*h,euler(lasteulers,n));
             lasteulers=eulers;
             n=n+1;
             try {
                 Thread.sleep((long)1/100);
             } catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
     }

und die drawing_panel klasse sieht jetzt so aus:

Java:
public class DrawingPanel extends JPanel {

    double xend, xstart;
   
    double[] lastEuler=new double[2];
    double[] newEuler=new double[2];
    private Path2D.Double path = new Path2D.Double(Path2D.WIND_EVEN_ODD,5000);
   


   DrawingPanel () {

       setBackground (Color.WHITE);
       path.moveTo(1,1);
   }
  
  
   public void setValues(double x1, double[] newE ){
    
       path.lineTo(x1,newE[0]);
       repaint();

   }
 
  

   public void paintComponent(Graphics g)   {

	super.paintComponent(g);
 
    Graphics2D g2 = (Graphics2D) g;

      g2.draw(path);

       }
   }

und kriege den folgenden Fehler:


Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 10000
at java.awt.geom.Path2D$Double$CopyIterator.currentSegment(Path2D.java:1653)
at sun.java2d.pisces.PiscesRenderingEngine$NormalizingPathIterator.currentSegment(PiscesRenderingEngine.java:393)
at sun.java2d.pipe.RenderingEngine.feedConsumer(RenderingEngine.java:282)
at sun.java2d.pisces.PiscesRenderingEngine.pathTo(PiscesRenderingEngine.java:474)
at sun.java2d.pisces.PiscesRenderingEngine.strokeTo(PiscesRenderingEngine.java:353)
at sun.java2d.pisces.PiscesRenderingEngine.strokeTo(PiscesRenderingEngine.java:164)
at sun.java2d.pisces.PiscesRenderingEngine.getAATileGenerator(PiscesRenderingEngine.java:552)
at sun.java2d.pipe.AAShapePipe.renderPath(AAShapePipe.java:93)
at sun.java2d.pipe.AAShapePipe.draw(AAShapePipe.java:61)
at sun.java2d.pipe.ValidatePipe.draw(ValidatePipe.java:154)
at sun.java2d.SunGraphics2D.draw(SunGraphics2D.java:2392)
at DrawingPanel.paintComponent(DrawingPanel.java:65)

wobei at DrawingPanel.paintComponent(DrawingPanel.java:65) gerade der g2.draw(path) Befehl ist..

woran liegt das?? danke und vg
 

Marco13

Top Contributor
Ah, ja, sorry: Das hinzufügen macht ja ein eigener thread. Damit kann es passieren, dass ein Punkt hinzugefügt wird während der Pfad gezeichnet wird. Das muss man vermeiden. Da gibt's zwei einfache Möglichkeiten (und vermutlich noch einige "geschicktere" aber vielleicht auch kompliziertere) : Entweder, man legt das addValue immer mit SwingUtilities auf den EDT, oder man synchronisiert auf den Path. Letzteres ist schon sehr pragmatisch, könnte hier aber OK sein:
Code:
synchronized (path)
{
   path.lineTo(x1,newE[0]);
}

und

synchronized (path)
{
   g2.draw(path);
}
 

jappel

Mitglied
Vielen Dank Marco!!! Eine Linie wird schon mal fehlerfrei - lückenlos - dargestellt! Jetzt muss ich nur noch die zweite Linie mit der Liste hinbekommen..
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M JavaFX Diagonale Linie nicht ausgegeben/angezeigt AWT, Swing, JavaFX & SWT 1
G Linie mit der Maus auswählen AWT, Swing, JavaFX & SWT 5
G JavaFX Line Chart mit Farbverlauf/Gradient in Linie AWT, Swing, JavaFX & SWT 1
L 2D-Grafik Linie von Kreis zu Kreis AWT, Swing, JavaFX & SWT 3
J 2D-Grafik Linie wird nach Mausklick nicht am richtigen Ort gezeichnet AWT, Swing, JavaFX & SWT 11
K JavaFX Linie immer in der Mitte der Szene halten AWT, Swing, JavaFX & SWT 12
L JavaFX Horizontale Linie zur Scene binding AWT, Swing, JavaFX & SWT 3
3 2D-Grafik BasicStroke dash pattern - Linie zu lang!? AWT, Swing, JavaFX & SWT 1
I Text zur Linie zeichnen AWT, Swing, JavaFX & SWT 1
I Pfeil zeichnen am Ende einer Linie AWT, Swing, JavaFX & SWT 1
javampir Kubische Interpolation einer Linie AWT, Swing, JavaFX & SWT 5
C AWT Horizontale Linie in einem Panel AWT, Swing, JavaFX & SWT 12
B Linie zwischen 2 Elementen AWT, Swing, JavaFX & SWT 5
propra Auf einem JPanel gezeichnete Linie auswählen AWT, Swing, JavaFX & SWT 3
Gossi 2D-Grafik Linie erweitern? AWT, Swing, JavaFX & SWT 10
V Linie mit Länge und Bogenmaß AWT, Swing, JavaFX & SWT 3
P 2D-Grafik Neue Farbe für einen Teilbereich einer Linie? AWT, Swing, JavaFX & SWT 8
K 2D-Grafik Linie verschwindet beim Zeichnen AWT, Swing, JavaFX & SWT 10
I Schrift und Farbe formatieren, und zwar pro Linie... AWT, Swing, JavaFX & SWT 4
C Swing JTable: Horizontale Linie bei einzelnen Zellen ausblenden AWT, Swing, JavaFX & SWT 5
G SWT Linie unter transparentes Canvas zeichnen AWT, Swing, JavaFX & SWT 4
B SWT Linie soll in Abhängigkeit der aktuellen Uhrzeit gezeichnet werden AWT, Swing, JavaFX & SWT 16
M Labels in ScrollPane mit Linie verbinden AWT, Swing, JavaFX & SWT 2
R JPanel - zeichnen in skalierten Bereich - Linie (X-Achse) nicht sichtbar AWT, Swing, JavaFX & SWT 11
J Swing - ich sehe keine Linie, andere schon AWT, Swing, JavaFX & SWT 6
S JXTaskPane und gepunktete Linie AWT, Swing, JavaFX & SWT 2
G SWT Linie AWT, Swing, JavaFX & SWT 13
F Rahmen mit gestrichelter Linie zeichnen AWT, Swing, JavaFX & SWT 4
G Linie nach Höhe einer Zahl zeichnen? AWT, Swing, JavaFX & SWT 3
M Linie zwischen JComponents AWT, Swing, JavaFX & SWT 5
T Linie langsam zeichnen AWT, Swing, JavaFX & SWT 3
L Linie mit drawLine auf JPanel AWT, Swing, JavaFX & SWT 7
A gezeichnete Linie verschwindet, wenn ich JMenuBar öffne AWT, Swing, JavaFX & SWT 2
S Problem mit dem Zeichnen einer Linie auf einem JPanel AWT, Swing, JavaFX & SWT 30
TheJavaKid Kreis, Rechteck, Linie. verschieben AWT, Swing, JavaFX & SWT 5
Student "Dicke" einer Linie - Line2D.Double AWT, Swing, JavaFX & SWT 12
R drawLine gibt hässliche linie AWT, Swing, JavaFX & SWT 4
T Vertikale Linie abgeschnitten AWT, Swing, JavaFX & SWT 2
C Linie in einem JLabel AWT, Swing, JavaFX & SWT 14
G linie / vektor zeichnen AWT, Swing, JavaFX & SWT 2
K Linie wird falsch auf Panel gezeichnet AWT, Swing, JavaFX & SWT 11
M JButtons mit Linie verbinden AWT, Swing, JavaFX & SWT 4
T Polygone und deren Löcher AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen


Oben