Kleinere Positionsangabe als einzelne Pixel bei Image?

Domi96

Mitglied
Hi liebe Community,
ich bin neu hier und habe eine Frage bezüglich der positionierung eines Image.
Mir reicht leider die positionierung nach einzelnen Pixel als Ganzzahl nicht aus und brauche etwas genaueres und hoffe, dass es sowas gibt. Am Besten wäre eine Positionsangabe per double wenn sowas überhaupt möglich ist 😉


Vielleicht ein Denkanstoß:

Ich habe von Subpixel gehört weiß aber nicht genauch was das ist und meine Recherche hilft mir in dem Kontext auch nicht weiter.

Dankeschön 🙂

Dominik
 
Pixel sind die kleinsten Elemente eines Bildes. Ein Bild ist diskret Unterteilt in pixel, man kann nicht einen Pixel per Kommazahl ansprechen. Was wäre den 0.5, 0.5 für ein Pixel?

Subpixel sind auf dem Monitor und beschreiben die einzelnen Leuchten eines Pixels.
 
Ich habe mich vielleicht falsch ausgedrückt:
Ich möchte eine Positionsangabe zu einem Bild haben und eine kleiner Positionsangabe als 1 (weil nur Ganzzahl möglich).
 
Zuletzt bearbeitet:
Dann verwendest du als Positionsangabe double oder float, castest die Werte in der Zeichenmethode nach int. Gerechnet wird dabei weiterhin mit den double-Werten
Java:
g2d.drawImage( image, (int)x, (int)y, w, h, null );
// Oder so ähnlich, je nachdem wie du das Bild auf dem Bildschirm realisierst

Oder spielt es eine Rolle, dass ein Bild tatsächlich nur einen teil eines Pixels ausfüllt?
Was nicht funktioniert aber dem menschlichen Gehirn/Auge durch Kantenglättung vorgetäuscht wird indem der "halbe" Pixel die Farbe halbe halbe mischt mit einer anderen Farbe die sich an der selben Stelle befindet. AA ist jedoch aufwendig und rechenintensiv.
Alternativ gibt es noch Multisampling, was ca. den selben Effekt hat und viel weniger rechenleistung benötigt. Jedoch wird bei Multisampling eher einfach das Bild leicht verwischt. Wenn also wirklich der Pixel an sich wichtig ist, ist das keine Alternative.
 
@ Network

Ja es spiel eine Rolle, da meine Positionsangabe auch auf die "halben Positionen" angewiesen ist :/ Mit casten habe ich es auch schon versucht, jedoch ist das zu ungenau, da ich immer einen Wer zwischen 0 und 1 erhalte. Beim Casten erhalte ich dann immer 0...

ABer am Besten erkläre ich was ich vor habe:

Ich habe ein Image, welchem ich alle paar zeiteinheiten eine neue Position zuweise, damit eine Bewegung entsteht:
Java:
g2d.drawImage(figBall.getImage(), figBall.getX(), figBall.getY(), this);

x und y berechnen sich dabei aus dem Winkel, in dem sich der Ball bewegt:

Java:
 if(angle<90){
    		dx=(int)(Math.sin(Math.PI*(angle)/180)*tempo);
    		dy=(int)(Math.cos(Math.PI*(angle)/180)*tempo);
    		
    	}else if(angle<180){
    		dx=(int)(Math.sin(Math.PI*(angle-90)/180)*tempo);
    		dy=(int)(-Math.cos(Math.PI*(angle-90)/180)*tempo);
    		
    	}else if(angle<270){
    		dx=-(int)(Math.sin(Math.PI*(angle-180)/180)*tempo);
    		dy=-(int)(Math.cos(Math.PI*(angle-180)/180)*tempo);
    		
    	}else if(angle<360){
    		dx=-(int)(Math.sin(Math.PI*(angle-270)/180)*tempo);
    		dy=(int)(Math.cos(Math.PI*(angle-270)/180)*tempo);
    	}else{
    		dx=0;
    		dy=0;
    	}
	        x =x+(dx);
	        y =y+(dy);

Wie man sieht berechne ich momentan dx und dy mit einem Typcast aus sin / cos.

doch ergibt das einen double Wert, wobei es auch wichtig ist, was hinter dem Komma steht. Da beim Casten meist 0 raus kommt und somit keine Bewegung zu Stande kommt. Daher brauche ich wirklich eine Positionsbestimmung mit dem double Wert...

Danke schonmal für die bisherigen Antworten 🙂
 
Aha ich verstehe.
Gegenfrage: Du möchtest die Bewegung eines Elektrons um den Atomkern darstellen und dafür suchst du jetzt einen Bildschirm dessen Pixel so groß wie Elektronen sind?

Wie wäre es wenn du deiner sin- und cos-Funktion einen Multiplikator verpasst, damit das menschliche Auge die Bewegung auch wahrnehmen kann?

Ein Bildschirm kann nicht als relativer Vergleich gewählt werden und sollte er auch nicht. Wenn ich dein Programm jetzt auf meinem Smartphone ausführe ist ein Pixel gleich viel kleiner als auf meinem groben Desktopmonitor.
Die Pixel von dem Bildschirm passen 10 mal in einen Pixel meines Desktopbildschirms. Deine Software würde jetzt daraus aber wiederum nur einen "Teil" nehmen. Dabei wären 5 Pixel ja bereits die hälfte eines Pixels eines anderen Bildschirms. Völliger Nonsense.

Entschuldige wenn ich das so voreilig vieleicht abstempel, aber ich finde das Vorhaben ehrlich gesagt nicht sinnvoll. OO dreht sich nebenbei auch um solche Problemstellungen - wo die Anzeige nur für die Anzeige zuständlich ist und nicht die logischen Zusammenhänge dahinter. 🙂

Gruß
Net

PS: Bitte revidier mich wenn ich zu voreilig geurteilt habe. 🙂
 
Lass
Code:
x
,
Code:
y
,
Code:
dx
und
Code:
dy
vom Typ
Code:
double
sein. Nur beim Zeichnen rechnest du dann in
Code:
int
um.

… wobei das weiter oben bereits vorgeschlagen wurde.
 
Wenn du diese Zahl hast:
0,42
und sie mit 100 Multiplizierst bevor du sie übergibst, stellt der Monitor die Bewegung mit 42 Pixeln dar.
Da wären deine Nachkommastellen, dargestellt und sogar sehr gut erkennbar.
Oder verstehe ich dein Problem ganz falsch.
 
nein genau das ist mein Problem.
Sorry das ich das ich mein Problem so schlecht rüberbringen kann 🙂

Diese Idee hatte ich auch schon, jedoch ergiebt sich dann das Problem, dass alle paar millisekunden der Punkt um zu viele Pixel springt...

Aber ich probiere es mit dem Ansatz weiter und setzte die Wiederholungsrate etwas runter 🙂

Danke
 
Ich verwende für sowas eine Vektor Klasse wie z.B die hier.
[Java] 2D Vector class - Pastebin.com

Die Position aller Objekte wird dann als Vektor dargestellt. Das gleiche gilt auch für die Geschwindigkeit.
bsp.

Java:
class Ball {
    Vec pos = new Vec(0,0);
    Vec tempo = new Vec(0,0);
    public setSpeed(double angle, double speed) {
        tempo = Vec.X_AXIS.rotate(angle).mul(speed);
    }
    public void update(double time) {
        pos = pos.add(tempo.mul(time));
    }
    public void paint(Graphics2D g) {
        g.setColor(...);
        g.fillOval((int)pos.x, (int)pos.y, ...);
    }
}

Wie du siehst wird hier überall mit double Werten gearbeitet, erst in der paint Methode wird dann gecastet.
 
Kann ich wenn ich einem Durchlauf das Bild um einen halben Pixel in x Richtung verschieben muss nciht einfach eine Runde aussetzten und dann in der darauffolgenden Runde um 1 erhöhen? kommt das aufs gleiche raus?
 
Ich habe aber eine Bewegung in x und y Rifchtung die zwischen 0 und 1 liegt:

Java:
if(angle<90){
            dx=(int)(Math.sin(Math.PI*(angle)/180)*tempo);
            dy=(int)(Math.cos(Math.PI*(angle)/180)*tempo);
            
        }else if(angle<180){
            dx=(int)(Math.sin(Math.PI*(angle-90)/180)*tempo);
            dy=(int)(-Math.cos(Math.PI*(angle-90)/180)*tempo);
            
        }else if(angle<270){
            dx=-(int)(Math.sin(Math.PI*(angle-180)/180)*tempo);
            dy=-(int)(Math.cos(Math.PI*(angle-180)/180)*tempo);
            
        }else if(angle<360){
            dx=-(int)(Math.sin(Math.PI*(angle-270)/180)*tempo);
            dy=(int)(Math.cos(Math.PI*(angle-270)/180)*tempo);
        }else{
            dx=0;
            dy=0;
        }
            x =x+(dx);
 y =y+(dy);

Wenn ich da caste erhalte ich immer 0. Ich gehe grade mit dem Vorschlag von NETWORK an die sache ran.
 
Kann ich wenn ich einem Durchlauf das Bild um einen halben Pixel in x Richtung verschieben muss nciht einfach eine Runde aussetzten und dann in der darauffolgenden Runde um 1 erhöhen? kommt das aufs gleiche raus?

Und wenn du jetzt mehrere Bilder hast, die sich unterschiedlich schnell bewegen? Eines wird um nen halben Pixel pro Durchllauf verschoben, ein anderes um 0.123423 Pixel usw. Und meistens ist die Bewegung auch nicht parallel zu einer der Axen.

Domi96 hat gesagt.:
Wenn ich da caste erhalte ich immer 0
Du sollst ja auch nicht casten, sondern mit float oder double arbeiten.
 
Zuletzt bearbeitet:
und das soll klappen? ISt es nicht das gleiche wenn ich 0,97 erst caste und dann 0 erhalte und es zum alten x ( Beispielsweise x=15) dazu addiere und dann 15 erhalte.
oder ob ich x mit der 0,97 addiere und dann beispielsweise 15,97 erhalte und dann caste und trotzdem 15 erhalte?
 
Nein ist nicht das gleiche.
Du rechnest dann im nächsten Durchlauf mit der 15,97 weiter, einzig allein fürs zeichnen castest du. An den Werten mit denen du rechnest änderst du gar nix.
 
und das soll klappen? ISt es nicht das gleiche wenn ich 0,97 erst caste und dann 0 erhalte und es zum alten x ( Beispielsweise x=15) dazu addiere und dann 15 erhalte.
oder ob ich x mit der 0,97 addiere und dann beispielsweise 15,97 erhalte und dann caste und trotzdem 15 erhalte?
Eigentlich ist es ganz einfach. Du berechnest Deine Werte so als ob es gar keine Pixel gäbe. Das tust Du in einer eigenen Klasse(-nhirarchie). Lass uns das "Modell" nennen.

Für die Anzeige lässt Du Dir die aktuellen Positionen aus dem Modell geben, multipliziertst die mit NETWORKs
Code:
100
, die wir in der Konstanten
Code:
ZOOM_FAKTOR
abgelegt haben und castest die Ergebnisse nach
Code:
int
. Nach dem Zeichen vergisst Du diese umgerechneten Werte.

Nun klar?

bye
TT
 
Zuletzt bearbeitet:
Hab' nicht alles gelesen, aber mit graphics2D#draw(shape) kann man auch Dinge zeichnen, die double-Koordinaten haben - und wenn man AntiAliasing AN hat, macht das sogar einen Unterschied zu ganzzahligen Koordinaten.
 

Neue Themen


Zurück
Oben