# Trotz Antialiasing zu verpixelt



## _-`avaj´-_ (14. Dez 2012)

Hallo erstmal an alle!
Ich versuche seit längerem ein Spiel zu programmieren: Stick Wars
Das Spiel gibt es schon und ich finde es klasse, deshalb möchte ich es gerne selber programmieren und ausbauen...

Link:
http://www.stickpage.com/stickwargameplay.shtml

Da das Spiel nicht aus Strichmännchen im eingetlichem Sinn besteht (also nur aus Strichen) sondern aus 2 dimensionalen nun ja... Strichen  werde ich mine Strichmännchen aus Polygonen basteln.
So weit so gut. Damit das alles funktioniert muss ich die Stricke auch drehen können... Das klappt auch wunderbar aber sobald ich das mache wird das ganze sehr verpixelt, obwohl ich Antialiasing an habe:







Gibt es eine Art in Java "genauer" zu Zeichnen?


@Admin:
Kann ich die Bilddatei bei euch hochladen?
Im Moment hab ich die Datei auf meinem Server hohgeladen und der ist nicht immer online...


----------



## Landei (14. Dez 2012)

Wie wäre es mit einem Stückchen Code, meine Kristallkugel ist gerade etwas verschmiert...


----------



## _-`avaj´-_ (15. Dez 2012)

Ein Auszug aus meinem JPannel, in dem alles gezeichnet wird:
Also alles was gezeichnet werden muss ist drawable und hat die Methode draw(Graphics g)...
Aber trotz 
	
	
	
	





```
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
```
 ist das ganze verpixelt...


```
@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		try {
			for (Drawable d : list) {
				d.draw(g2);
			}
		} catch (java.util.ConcurrentModificationException e) {
		}
	}
```


----------



## xehpuk (15. Dez 2012)

Und wie sieht die 
	
	
	
	





```
draw()
```
 aus?

Für dicke Striche brauchst du keine Polygone. Da reichen auch Linien in Verbindung mit [JAPI]BasicStroke[/JAPI].
Siehe dazu: Stroking and Filling Graphics Primitives (The Java™ Tutorials > 2D Graphics > Working with Geometry)


----------



## tröööt (15. Dez 2012)

naja ... ein monitor hat nun mal pixel die horizontal/vertikal ausgrichtet sind ... und entsprechend wird auch gezeichnet ...

nur wie GENAU das gemacht wird hängt halt von den einstellungen und vor allem der auflösung und der größe des objektes ab ... und selbst SVG hat mit diesem problem zu kämpfen ... denn ein rechner kann es nun mal nicht anders darstellen ...


----------



## Spacerat (15. Dez 2012)

Scheint, als würde die "2-Dimensionale Linie" (also das Rechteck) in der Reihenfolge gezeichnet, antialiased und anschliessend ohne Aliasing vergrössert. Meine Glaskugel ist aber ebenso verpixelt, wie Landei's Kristallkugel verschmiert. Zumindest lässt sich das Aliasing ansatzweise erkennen.


----------



## _-`avaj´-_ (15. Dez 2012)

tröööt hat gesagt.:


> naja ... ein monitor hat nun mal pixel die horizontal/vertikal ausgrichtet sind ... und entsprechend wird auch gezeichnet ...
> 
> nur wie GENAU das gemacht wird hängt halt von den einstellungen und vor allem der auflösung und der größe des objektes ab ... und selbst SVG hat mit diesem problem zu kämpfen ... denn ein rechner kann es nun mal nicht anders darstellen ...



Also wenn ich in jedem Spiel solche Pixel hätte würd ich mich aufhängen gehen!
Spass beiseite: Ich meine damit, dass andere es auch hinbekommen dass ihre Grafiken nicht so eckig aussehen...



Spacerat hat gesagt.:


> Scheint, als würde die "2-Dimensionale Linie" (also das Rechteck) in der Reihenfolge gezeichnet, antialiased und anschliessend ohne Aliasing vergrössert. Meine Glaskugel ist aber ebenso verpixelt, wie Landei's Kristallkugel verschmiert. Zumindest lässt sich das Aliasing ansatzweise erkennen.



Ohh sorry, ich hab gedacht das wäre klar: Das rechts ist nur eine Vergrößerung mit der Bildschirmlupe, um es klarer zu machen, wie eckig das Ding ist...



xehpuk hat gesagt.:


> Und wie sieht die
> 
> 
> 
> ...



Ich habe gedacht draw() wäre klar... Da wird halt einfach das Polygon gezeichnet:
(x bzw. y sind die Koordinaten jew. in einem Array)


```
@Override
	public void draw(Graphics g) {
		g.fillPolygon(x, y, x.length);
	}
```

Und wegen BasicStroke:
So wie ich das sehe lässt sich das ganze aber nicht drehen... bzw. hat eine x, eine y Koordinate so wie Länge und Breite wie ein Rechteck aber keine 2 Verbindungspunkte oder?


----------



## xehpuk (15. Dez 2012)

Am besten postest du mal ein KSKB. Wo sind die Punkte fürs Polygon? Wo wird gedreht? Etc.
Außerdem fehlt in deiner 
	
	
	
	





```
paintComponent()
```
 der Aufruf von 
	
	
	
	





```
super.paintComponent()
```
. Könnte vielleicht schon daran liegen.

Hier ein Beispiel mit gut zu sehendem Antialiasing bei Polygon (schwarz) und Linie (rot):

```
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Stroking extends JPanel {
	private final int[] xs = {0, 40, 40, 0};
	private final int[] ys = {0, 0, 20, 20};
	
	@Override
    protected void paintComponent(final Graphics g) {
		super.paintComponent(g);
        final Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setTransform(AffineTransform.getTranslateInstance(20, 10));
		g2.rotate(Math.PI / 10);
		g2.setColor(Color.BLACK);
        g2.fillPolygon(xs, ys, xs.length);
		g2.setTransform(AffineTransform.getTranslateInstance(80, 10));
		g2.rotate(Math.PI / 10);
		g2.setStroke(new BasicStroke(20, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
		g2.setColor(Color.RED);
		final int y = (ys[0] + ys[2]) / 2;
		g2.drawLine(xs[0], y, xs[1], y);
		g2.dispose();
    }
	
	public static void main(final String... args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				final JFrame f = new JFrame();
				f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				final Stroking s = new Stroking();
				s.setBackground(Color.WHITE);
				s.setPreferredSize(new Dimension(130, 50));
				f.setContentPane(s);
				f.pack();
				f.setLocationRelativeTo(null);
				f.setVisible(true);
			}
		});
	}
}
```
Ergebnis:





Falls dir das Transformieren der 
	
	
	
	





```
Graphics2D
```
 neu erscheint: Transforming Shapes, Text, and Images (The Java™ Tutorials > 2D Graphics > Advanced Topics in Java2D)


----------



## Marco13 (15. Dez 2012)

xehpuk hat gesagt.:


> Außerdem fehlt in deiner
> 
> 
> 
> ...



Das klingt im ersten Moment komisch, könnte aber wirklich sein - insbesondere, wenn mehrfach gezeichnet wird (mit repaint) könnten sich die eigentlich halbtransparenten Pixel vom Antialiasing "aufsummieren" und am Ende wie ungeantialiaste aussehen.


----------



## Spacerat (15. Dez 2012)

Marco13 hat gesagt.:


> Das klingt im ersten Moment komisch, könnte aber wirklich sein - insbesondere, wenn mehrfach gezeichnet wird (mit repaint) könnten sich die eigentlich halbtransparenten Pixel vom Antialiasing "aufsummieren" und am Ende wie ungeantialiaste aussehen.


Glaub' ich weniger, weil "super.paintComponent()" ja aufgerufen wird, bevor das Antialiasing überhaupt gesetzt wird. Kann man aber testen, indem man es halt mal auskommentiert.


----------



## xehpuk (15. Dez 2012)

Marco13 hat gesagt.:


> Das klingt im ersten Moment komisch, könnte aber wirklich sein - insbesondere, wenn mehrfach gezeichnet wird (mit repaint) könnten sich die eigentlich halbtransparenten Pixel vom Antialiasing "aufsummieren" und am Ende wie ungeantialiaste aussehen.


Japs, genau so war es gedacht. Gerade wenn hier anscheinend so ein Mischmasch aus active und passive rendering (alle x ms 
	
	
	
	





```
repaint()
```
) verwendet wird, die Repaints also programmatisch ausgelöst werden.



Spacerat hat gesagt.:


> Glaub' ich weniger, weil "super.paintComponent()" ja aufgerufen wird, bevor das Antialiasing überhaupt gesetzt wird. Kann man aber testen, indem man es halt mal auskommentiert.


Es ist ja nur zum Leeren des Hintergrunds da. Von daher ist es egal, ob das Antialiasing aktiv ist.

Ich habe das nun auch getestet, indem ich 
	
	
	
	





```
super.paintComponent()
```
 auskommentiert und Folgendes der 
	
	
	
	





```
main()
```
 hinzugefügt habe:

```
new Timer().scheduleAtFixedRate(new TimerTask() {
	@Override
	public void run() {
		s.repaint();
	}
}, 1000, 1000);
```
In der Tat überlagern sich die transluzenten Antialiasing-Pixel jede Sekunde immer mehr, sodass es am Ende opak wird.

Hier die ersten 100 Zeichnungen:





Die ersten 10 Zeichnungen fünffach vergrößert:


----------



## _-`avaj´-_ (15. Dez 2012)

Jo genau das war der Fehler!
Auch in mienem Programm sieht das ganze bestens aus nach dem der super-Aufruf da steht!
Ok das das ganze so ein einfacher dummer Fehler ist hätte ich nicht gedacht 
Aber danke an alle!


----------



## Marco13 (15. Dez 2012)

Diesen Effekt hatte ich schonmal in http://www.java-forum.org/awt-swing-swt/141994-fading-jpanel.html#post944348 , aber weiß nicht ob ich in diesem Fall noch drauf gekommen wäre


----------



## tröööt (15. Dez 2012)

_-`avaj´-_ hat gesagt.:


> Also wenn ich in jedem Spiel solche Pixel hätte würd ich mich aufhängen gehen!
> Spass beiseite: Ich meine damit, dass andere es auch hinbekommen dass ihre Grafiken nicht so eckig aussehen...


du musst es nur stark genug vergrößern ... dann siehst du es ...

"kantenglättung" ... um mal das deutsche wort zu nutzen ... ist nichts weiter als das die berechnung der entsprechenden werte der pixel genauer vorgenommen wird ... und man somit den unterschied nicht mehr ganz so krass wahrnimmt ...
würde man aber jedes pixel was auch nur um ein bit vom anderen abweicht in einer anderen farbe darstellen so wäre das ergebnis ungefähr gleich dem beispiel ganz oben ...

es ist nun mal fakt das ein rechner nur mit solch quadratischen pixeln die eine horinzontale/veritkale ausrichtung haben umgehen kann ... und entsprechend sind monitore auch so gebaut diese genau so anzuzeigen ... und daran können auch die besten algorithmen nichts ändern .... sondern nur die darstellung soweit anpassen das es unser "blödes" menschliches auge nicht mehr so direkt wahrnehmen kann ...


----------

