Wie geht dieser Effekt?

Status
Nicht offen für weitere Antworten.

André Uhres

Top Contributor
Eine Spiegelung kann man mit Graphics#copyArea ezeugen.
Die Animation ist eine Folge von Spiegelungen bei denen die y-Quelle verändert wurde.
 

Campino

Top Contributor
ähm...ich würde das als Film oder als Reihung von Bildern, die einfach übereinander geszeichnet werden, machen...
 

André Uhres

Top Contributor
Campino hat gesagt.:
ähm...ich würde das als Film oder als Reihung von Bildern, die einfach übereinander geszeichnet werden, machen...
Ja gut, das ist ja auch kein Problem wenn man die Bilder erstmal hat.
Die erforderlichen Bilder bekommst du auf die oben beschriebene Art.
 

kaie

Bekanntes Mitglied
Eigentlich ist sowas gar nicht mal so schwer zu programmieren, geht sogar komplett ohne Java Advanced Imaging und den ganzen Schnickschnack. Man muss nur jeweils die einzelnen Bildzeilen des gespiegelten Bereichs um einen gewissen Betrag versetzen. Ich habe einfach eine (physikalisch ziemlich unsinnige) Funktion angesetzt, die einigermaßen gut aussieht. Wer Verbesserungsvorschläge hat, möge sich bitte melden.

Code:
import java.awt.*;
import java.net.*;

import javax.swing.*;

public class Spiegelung extends JPanel implements Runnable
{
    private Image bild        = null;
    private int   phase       = 0;
    private int   wellenhoehe = 3;

    public Spiegelung(String s)
    {
        // Bild laden
        try
        {
            bild = new ImageIcon(new URL(s)).getImage();
        } catch (Exception e)
        {
            System.out.println("Bild nicht gefunden!");
        }

        // JPanel-Groesse setzen
        setPreferredSize(new Dimension(bild.getWidth(null), bild
                .getHeight(null)));

        // Aktualisier-Thread starten
        new Thread(this).start();
    }

    public void paint(Graphics g)
    {
        // Groesse des Bildes ermitteln
        int w = bild.getWidth(null);
        int h = bild.getHeight(null);

        // Position der Wassergrenze berechnen
        int m = h * 2 / 3;

        // Hintergrund zeichnen
        g.drawImage(bild, 0, 0, null);

        // Spiegelung zeichnen
        for (int y = m; y < h; y++)
        {
            int q = (int) (m - Math.pow(y - m, 1.1) + wellenhoehe
                    * Math.sin(y * .25 + phase * .5));
            g.drawImage(bild, 0, y, w, y + 1, 0, q, w, q + 1, null);
        }

        // halbtransparentes blau über die Spiegelung zeichnen
        g.setColor(new Color(0, 0, 255, 20));
        g.fillRect(0, m, w, h - m);
    }

    public void run()
    {
        while (true)
        {
            repaint();
            phase++;
            try
            {
                Thread.sleep(50);
            } catch (Exception e)
            {
            }
        }
    }

    public static void main(String[] args) throws Exception
    {
        // neuen Frame mit einer Spiegelung erzeugen
        JFrame f = new JFrame("Eine Beispielspiegelung");

        String url = "http://www.sz.ruhr-uni-bochum.de/imperia/md/images/sz/greihe75.jpg";
        f.getContentPane().add( new Spiegelung(url) );
        
        f.pack();
        f.setVisible(true);
    }

}

Viel Spass damit wünscht

kaie
 

Revenant

Aktives Mitglied
hui...

könntest du für mich noch kurz ein paar worte zu deiner for schleife da verlieren .... hab da nich so den durchblick
 

kaie

Bekanntes Mitglied
In der Schleife passiert Folgendes:

Wir laufen vom oberen Rand des Wassers (den ich auf 2/3 der Gesamthöhe gesetzt habe) zeilenweise nach unten und zeichnen jeweils eine Zeile. Eine einfache Spiegelung würde man einfach mit der Zeile
Code:
int q=m-(y-m);
erreichen. Um einen leichten Tiefeneffekt zu erreichen, habe ich den Term in der Klammer mit dem Pi-mal-Daumen-Wert 1,1 potenziert:
Code:
int q=(int)(m-Math.pow(y-m,1.1));
Auf diesen Wert addieren wir nun noch einen Sinus-Anteil drauf, dessen Amplitude die Wellenhöhe ist. Für die Phasenverschiebung werden die y-Koordinate und die zeitlich wachsende Phasenkomponente addiert, jeweils mit einem durch trial-and-error ermittelten Skalierungsfaktor. Und schon habe wir:
Code:
int q = (int) (m - Math.pow(y - m, 1.1) + wellenhoehe * Math.sin(y * .25 + phase * .5));
Diese Zeilenangabe können wir nun direkt zum Zeichnen der Zeile verwenden.

Alles klar? :D
 

Revenant

Aktives Mitglied
Respekt man Respekt... der Alghorytmus is schon ziemlich äh "fortgeschritten" :roll: ... hm. Ich hab so nen ähnlichen Effekt noch mit nem Kreis gesehn - dort wo die Maus über dem Bild war hat es sich immer so "verzerrt", als ob ein Tropfen ins Wasser fallen würde.

Wie geht sowas dann?

Und vor allem kennt jemand Fachliteratur für sowas? Suche schon seit geraumer Zeit ein Buch in der Richtung, aber da scheint es nichts zu geben.

EDIT:
Also hier mal ne Sammlung an Sachen die mich so interressieren:

http://www.die3sphaere.de/bilder-galerie/java/java6/java-bild-6.html

http://www.die3sphaere.de/bilder-galerie/java/java1/java-bild-1.html

http://www.die3sphaere.de/bilder-galerie/java/java5/java-bild-5.html
 

kaie

Bekanntes Mitglied
OK, es ist Sonntag, ich habe Langeweile, und so habe ich mich von Deinem plumpen Push provozieren lassen, mich auch an eines der anderen Beispiele zu wagen: das BumpMapping (im letzten Beispiel).

Meine Lösung sieht momentan so aus. Ist noch nicht perfekt, erfüllt aber seinen Zweck.

Als Literatur über BumpMapping habe ich folgende Seite verwendet: http://www.whisqu.se/per/docs/graphics12.htm. Alle wichtigen Informationen über den verwendeten Algorithmus findet man dort.

Bei den Erd-Texturen habe ich mich mal ganz dreist hier bedient: http://www.celestiamotherlode.net/catalog/earth.php (alle Bilder skaliert auf 500x250)

Und hier ist der Quelltext:
Code:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

import javax.swing.*;

public class BumpMapping extends JPanel implements MouseMotionListener
{
    // Attribute
    private Image   bild;
    private Image   bump;
    private int     lichtX = 50;
    private int     lichtY = 70;
    private int[][] map;
    private int[][] bumpX;
    private int[][] bumpY;
    private int     w;
    private int     h;

    public BumpMapping(Image bild, Image bump)
    {
        // Bilder laden
        this.bild = bild;
        this.bump = bump;
        // Bildgröße merken
        w = bump.getWidth(this);
        h = bump.getHeight(this);
        // Tabellen berechnen
        environMap();
        bumpMap();
        // Größe und Listener setzen
        setPreferredSize(new Dimension(w, h));
        addMouseMotionListener(this);
    }

    // Normalenvektoren für die Lampe berechnen
    public void environMap()
    {
        map = new int[256][256];
        for (int y = 0; y < 256; y++)
        {
            for (int x = 0; x < 256; x++)
            {
                double nX = (x - 128) / 128f;
                double nY = (y - 128) / 128f;
                double nZ = Math.max(0, 1 - Math.sqrt(nX * nX + nY * nY));
                map[x][y] = (int) (nZ * 255);
            }
        }
    }

    // Normalen der Bumpmap-Oberfläche berechnen
    public void bumpMap()
    {
        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        bi.getGraphics().drawImage(bump, 0, 0, null);
        bumpX = new int[w][h];
        bumpY = new int[w][h];
        int[] rgb = bi.getRGB(0, 0, w, h, null, 0, w);
        for (int y = 0; y < h; y++)
        {
            for (int x = 0; x < w; x++)
            {
                bumpX[x][y] = (rgb[Math.min(w - 1, x + 1) + y * w] & 255)
                        - (rgb[Math.max(0, x - 1) + w * y] & 255);
                bumpY[x][y] = (rgb[x + w * Math.min(h - 1, y + 1)] & 255)
                        - (rgb[x + w * Math.max(0, y - 1)] & 255);
            }
        }
    }

    public void paintComponent(Graphics graphics)
    {
        // Hintergrund und normales Bild zeichnen
        super.paintComponent(graphics);
        graphics.drawImage(bild, 0, 0, null);

        // neues Bild als Array erzeugen
        int[] erg = new int[w * h];
        int pos = 0;

        // Punkte setzen
        for (int y = 0; y < h; y++)
        {
            for (int x = 0; x < w; x++)
            {
                int px = Math.max(0, Math.min(255, -bumpX[x][y] + 127
                        + (x - lichtX) / 3));
                int py = Math.max(0, Math.min(255, -bumpY[x][y] + 127
                        + (y - lichtY) / 3));
                int f = map[px][py];
                erg[pos++] = f | (f << 8) | (f << 16) | f << 24;
            }
        }
        // Bild erzeugen und zeichnen
        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        bi.setRGB(0, 0, w, h, erg, 0, w);
        graphics.drawImage(bi, 0, 0, null);
    }

    // MouseListener
    public void mouseDragged(MouseEvent me)
    {
    }

    public void mouseMoved(MouseEvent me)
    {
        lichtX = me.getX();
        lichtY = me.getY();
        repaint();
    }

    // Hauptmethode
    public static void main(String[] args) throws Exception
    {
        // BumpMapping-Bild erzeugen
        BumpMapping b = new BumpMapping(new ImageIcon("earth.jpg").getImage(),new ImageIcon("bump.jpg").getImage());

        // Fenster anzeigen
        JFrame f = new JFrame("Beispiel für Bumpmapping");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(b);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

Ich hoffe, ich baue die beiden anderen Beispielseiten nicht auch noch nach. Sonst ist wieder der ganze Sonntag vorbei...

kaie
 

kaie

Bekanntes Mitglied
Und zu guter letzt hier noch ein Effekt mit Regentropfen. Das Bild stammt aus der Wikipedia, die Tropfen sind einfach größer werdende Ellipsen mit Transparenzen. Wie bei den anderen Effekten gilt auch hier: ist noch lange nicht perfekt, aber das Prinzip wird hoffentlich deutlich. Viel Spass mit dem Quelltext:
Code:
import java.awt.*;
import java.net.*;

import javax.swing.*;

public class Pfuetze extends JPanel implements Runnable
{
    // Attribute
    private Image   bild;
    private int     w;
    private int     h;
    private int[][] welle  = new int[100][3];
    private int     anzahl = 0;

    public Pfuetze(Image bild)
    {
        // Bilder laden
        this.bild = bild;
        // Bildgröße merken
        w = bild.getWidth(this);
        h = bild.getHeight(this);
        // Größe und Listener setzen
        setPreferredSize(new Dimension(w, h));
        new Thread(this).start();
    }

    public void paintComponent(Graphics g)
    {
        // Hintergrund und normales Bild zeichnen
        super.paintComponent(g);
        g.drawImage(bild, 0, 0, null);
        ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        for( int i=0; i<anzahl; i++ )
        {
            for( int j=-2; j<=2; j++ )
            {
                g.setColor( new Color(200-j*j*30,200-j*j*30,200-j*j*30,(150-welle[i][2]*5)/(3-Math.abs(j))) );
                g.drawOval(welle[i][0]-welle[i][2]+j,welle[i][1]-welle[i][2]*2/5,welle[i][2]*2,welle[i][2]*2*2/5);
            }
        }

    }

    public void run()
    {
        while (true)
        {
            try
            {
                Thread.sleep(50);
            } catch (Exception e)
            {
            }
            
            // neue Tropfen erzeugen
            if( Math.random()<.8 )
            {
                welle[anzahl][0] = (int)(Math.random()*w);
                welle[anzahl][1] = (int)(Math.random()*h);
                welle[anzahl][2] = 0;
                anzahl=(anzahl+1)%100;
            }
            
            // Tropfen weiterbewegen und löschen
            for( int i=0; i<anzahl; i++ )
            {
                welle[i][2]++;
                if( welle[i][2]==30 )
                {
                    welle[i]=welle[anzahl-1];
                    welle[anzahl-1]=new int[3];
                    anzahl--;
                    i--;
                }
            }
            
            repaint();
        }
    }

    // Hauptmethode
    public static void main(String[] args) throws Exception
    {
        // BumpMapping-Bild erzeugen
        Pfuetze b = new Pfuetze(new ImageIcon("bild.jpg").getImage());

        // Fenster anzeigen
        JFrame f = new JFrame("Beispiel für Regenpfützen");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(b);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}
So, hoffe damit erstmal alle Bildeffekte erschlagen zu haben. Jetzt wünscht aber wirklich noch ein schönes Restwochenende
kaie
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
komplettlost Vollbildmodus für MacOs Nutzer geht nicht AWT, Swing, JavaFX & SWT 13
B Swing Menü geht nicht AWT, Swing, JavaFX & SWT 5
izoards Bild ausdrucken - PageFormat setzen geht nicht AWT, Swing, JavaFX & SWT 5
J import javafx.fxml* bei JavaFX 13 geht nicht mehr AWT, Swing, JavaFX & SWT 7
S PatentComponent geht nicht? AWT, Swing, JavaFX & SWT 3
H automatische Anzahl der Spalten ermitteln -> geht nicht AWT, Swing, JavaFX & SWT 6
B JavaFX Wo liegt mein Gedankenfehler ??? KeyEvent geht nicht ... AWT, Swing, JavaFX & SWT 8
J Warum geht das nicht? if-else usw..... compilieren geht nicht -- HILFE!!! AWT, Swing, JavaFX & SWT 10
LexeB4F setValueAT geht nicht... wieso? AWT, Swing, JavaFX & SWT 14
T JLabel in die Mitte(JLabel.CENTER geht nicht) AWT, Swing, JavaFX & SWT 12
X Swing JButton's zum JScrollPane hinzufügen geht nicht. Bitte um Hilfe. AWT, Swing, JavaFX & SWT 9
F Swing String[] in JTextArea ausgeben. Jeder Eintrag in neue Zeile, aber ohne "\n"- Geht das? AWT, Swing, JavaFX & SWT 3
B Swing Form undecorated: Beim Bewegen geht die Maus immer automatisch zur linken Seite. AWT, Swing, JavaFX & SWT 7
I JavaFX - MP3 geht nicht AWT, Swing, JavaFX & SWT 4
N gewünschte ActionListener bei RadioButton mit isSelected geht nicht AWT, Swing, JavaFX & SWT 2
C Swing Update von swing-TableModels per Thread. Eins geht, das andere nicht, warum? AWT, Swing, JavaFX & SWT 12
S KeyListener geht nicht AWT, Swing, JavaFX & SWT 12
B JInternalFrame Focus setzten geht nicht AWT, Swing, JavaFX & SWT 2
D Swing fullscreen switch geht nicht richtig AWT, Swing, JavaFX & SWT 8
F Icongröße ändern, geht das ? AWT, Swing, JavaFX & SWT 2
Q Swing MouseListener auf JTable geht nicht AWT, Swing, JavaFX & SWT 2
0 JTable Spaltenbreite automatisch an Inhalt anpassne geht nicht AWT, Swing, JavaFX & SWT 3
antonbracke Multiplayer Shooter- Wie geht das mit Canvas & Graphics AWT, Swing, JavaFX & SWT 6
K Options-Frame integrieren (zum zuschalten und wegschalten wie geht man da ran? AWT, Swing, JavaFX & SWT 7
R JTextField mit abgerundeten Ecken - Geht über Grenze hinaus AWT, Swing, JavaFX & SWT 4
B Java und ansprechende Benutzeroberflächen - geht das? AWT, Swing, JavaFX & SWT 16
V Swing Custom JToggleButton in JTable - Click-Event geht erst beim zweiten Mal AWT, Swing, JavaFX & SWT 7
C Java2D Transparenz geht bei einfärben verloren AWT, Swing, JavaFX & SWT 7
T transparent geht nicht (btw: rechteck) AWT, Swing, JavaFX & SWT 13
E Null-Layout - Wie geht es ohne? AWT, Swing, JavaFX & SWT 19
Y LookAndFeel Nimbus einschalten geht nicht AWT, Swing, JavaFX & SWT 31
M Bild aus .jar Archiv laden geht nicht AWT, Swing, JavaFX & SWT 6
L Stopp Button geht nicht AWT, Swing, JavaFX & SWT 2
S JDesktopPane bei Button-Klick anzeigen geht nicht AWT, Swing, JavaFX & SWT 5
D JList Scrollbar machen geht nicht AWT, Swing, JavaFX & SWT 4
J Label mit transparentem hintergrund - geht das? AWT, Swing, JavaFX & SWT 21
H Sub-Dialog von modalem JDialog aus aufrufen - geht das? AWT, Swing, JavaFX & SWT 6
B Panels stapeln, geht das? AWT, Swing, JavaFX & SWT 7
P SetBounds auf JPanel geht nicht! AWT, Swing, JavaFX & SWT 2
S SWT Composite mit Layout Manager geht nicht AWT, Swing, JavaFX & SWT 4
S JPanel geht über Rand hinaus AWT, Swing, JavaFX & SWT 7
E setAlwaysOnTop geht verloren AWT, Swing, JavaFX & SWT 3
B Swing Variable in JTextfield geht nicht AWT, Swing, JavaFX & SWT 10
B Swing setDefaultButton geht nicht - Komponente fängt Events ab AWT, Swing, JavaFX & SWT 5
M FileFilter geht nicht AWT, Swing, JavaFX & SWT 5
A repaint() geht nicht ? AWT, Swing, JavaFX & SWT 5
D Jlist auf 10 Zeilen begrenzen geht bei mir nicht AWT, Swing, JavaFX & SWT 2
D Runtime.getRuntime.exec() + SWT oder Swing = geht nicht AWT, Swing, JavaFX & SWT 2
M Action.DISPLAYED_MNEMONIC_INDEX_KEY geht nicht mehr AWT, Swing, JavaFX & SWT 2
F JScrollPane setLayout geht nicht AWT, Swing, JavaFX & SWT 2
R MVC: System.out.prinln in View umleiten geht nicht richtig AWT, Swing, JavaFX & SWT 7
B MouseListener / doppelklick geht net AWT, Swing, JavaFX & SWT 16
G JToggleButton pressed geht nicht AWT, Swing, JavaFX & SWT 2
G setLocationRelativeTo(frame) geht plötzlich nicht mehr AWT, Swing, JavaFX & SWT 3
G fireTableDataChanged() geht das auch ohne vector? AWT, Swing, JavaFX & SWT 13
Z Buttons erscheinen erst wenn man mit der Maus drüber geht AWT, Swing, JavaFX & SWT 7
P GridBagLayout einfaches Beispiel geht nicht? AWT, Swing, JavaFX & SWT 5
I Tastur eingabe geht nicht (wenn Button vorhanden) AWT, Swing, JavaFX & SWT 5
W Swing, 2 JProgressbars und threads geht das? AWT, Swing, JavaFX & SWT 2
X JTable "geht" erst beim 2.Klick AWT, Swing, JavaFX & SWT 2
I JRadioButton disablen geht nicht AWT, Swing, JavaFX & SWT 4
M Wieso geht das nicht! AWT, Swing, JavaFX & SWT 3
G JDialog hinter Glasspane von JFrame. Geht das? AWT, Swing, JavaFX & SWT 3
P [SWT] - ProgressBar, Prozentzahlen live anzeigen geht nicht AWT, Swing, JavaFX & SWT 13
W netbeans projekt in Eclipse importieren -gui teil geht nicht AWT, Swing, JavaFX & SWT 5
V JTable - farbige Boolean-Felder - geht das? AWT, Swing, JavaFX & SWT 3
O Panels ein und ausblenden - geht das? AWT, Swing, JavaFX & SWT 3
T Look and Feel ändern geht nicht, obwohl es geht. AWT, Swing, JavaFX & SWT 2
F Serialisiertes Object geht nicht zu Inizialisieren AWT, Swing, JavaFX & SWT 7
K setSize und setLocation geht nicht AWT, Swing, JavaFX & SWT 8
S JFileChooser Pfadübergabe mit Leerzeichen geht nicht AWT, Swing, JavaFX & SWT 6
G Warum geht das nicht? AWT, Swing, JavaFX & SWT 3
S JScrollPane in einem JDialog = geht nicht? AWT, Swing, JavaFX & SWT 14
B Layoutvorgabe: Geht so was überhaupt? AWT, Swing, JavaFX & SWT 5
S Animation geht nicht AWT, Swing, JavaFX & SWT 3
S JLabel zeilenumbruch ? geht das in JDialog? AWT, Swing, JavaFX & SWT 2
T Paint-Methode geht nicht AWT, Swing, JavaFX & SWT 5
I SWT - Browser.setUrl(url) geht nicht :-( AWT, Swing, JavaFX & SWT 6
M Antialiasing geht . bis zum repaint ! AWT, Swing, JavaFX & SWT 4
J Jar Datei geht nicht richtig AWT, Swing, JavaFX & SWT 7
S JTextArea background Transparent geht nicht AWT, Swing, JavaFX & SWT 23
raptorrs Swing, Datenformate und wie geht der Datentransfer? AWT, Swing, JavaFX & SWT 8
M setOpaque() geht. und geht nicht :-( AWT, Swing, JavaFX & SWT 2
A Zeichnen auf zwei Labels. Geht nit AWT, Swing, JavaFX & SWT 7
R Farbcode geht nicht AWT, Swing, JavaFX & SWT 4
I setUndecorated geht nicht. AWT, Swing, JavaFX & SWT 3
G Zugriff auf TextField geht nicht AWT, Swing, JavaFX & SWT 5
L JComboBox befüllen geht nicht. AWT, Swing, JavaFX & SWT 18
G jbutton mit linebreak. setEnabled geht nicht mehr AWT, Swing, JavaFX & SWT 4
J Gleitende Fenster in Java - geht das? AWT, Swing, JavaFX & SWT 2
G Look&Feel geht nicht AWT, Swing, JavaFX & SWT 3
B Jlist getSelectedIndices geht net AWT, Swing, JavaFX & SWT 2
Z JScrollPane geht nicht AWT, Swing, JavaFX & SWT 7
F Internes Frame RICHTIG schließen..geht das überhaupt ? AWT, Swing, JavaFX & SWT 2
N Methode für Bild laden geht nur in der eigenen Klasse... AWT, Swing, JavaFX & SWT 3
A Speichern-Dialog geht nicht weg AWT, Swing, JavaFX & SWT 13
A Scrollen von Fenster geht nicht AWT, Swing, JavaFX & SWT 4
R GUI geht nicht! AWT, Swing, JavaFX & SWT 2
P Image in JApplet geht nicht AWT, Swing, JavaFX & SWT 2
H Fehler: Zum Ausführen dieser Anwendung benötigte JavaFX-Runtime-Komponenten fehlen AWT, Swing, JavaFX & SWT 44

Ähnliche Java Themen

Neue Themen


Oben