Java & JavaScript


Home
Applets
   3D:
 · Würfel
 · Würfel 2
 · Würfel 3
 · Tetraeder
 · Tetraeder 2
 · Dodekaeder
 · Ikosaeder
 · Fußball
 · Kugel
 · Kugel 2
   Fraktale:
 · Apfelmännchen
 · Apfelmännchen 2
 · Apfelmännchen 3
 · Apfelmännchen MA
 · Apfelmännchen Zoom
 · Apfelmännchen Zoom 2
 · Juliamenge
 · Juliamenge MA
 · Julia-Generator
 · Koch-Kurve
 · Koch-Kurve 2
 · Hilbert-Kurve
 · Sierpinski-Dreieck
 · Sierpinski-Dreieck 2
 · Sierpinski-Dreieck 3
 · Sierpinski-Teppich
 · Pythagoras-Baum
 · Lindenmayer-System
 · Lindenmayer-System 2
   Mathematik:
 · Funktionsplotter
 · Eratosthenes-Sieb
 · Miller-Rabin-Test
   Verschiedenes:
 · Morsezeichen-Ticker
 · Analoguhr
Scripts
Gäste
Kontakt



Apetri: 3D Grafikprogrammierung
- Anzeige -


- Applets : 3D : Würfel 3 -


Ein rotierender Würfel mit Beleuchtungs-Effekt als Java-Applet.

[Der Würfel mit Beleuchtungs-Effekt in Rotation als Java-Applet lässt sich allerdings nur mit aktiviertem Java betrachten !]


Wuerfel3.java

import java.awt.*;
import java.applet.*;

public class Wuerfel3 extends Applet {

    // 8 Eckpunkte 1-8
    // mit je 3 Koordinaten 1,2,3
    double p[][] = new double[9][4];

    int x=1, y=2, z=3;

    public void init() {
        setBackground(new Color(255,255,255));

        // 8 Eckpunkte im lokalen Würfel-Koordinatensystem
        // Nullpunkt = Mittelpunkt
        p[1][x] = -100; p[1][y] = -100; p[1][z] = -100;
        p[2][x] = +100; p[2][y] = -100; p[2][z] = -100;
        p[3][x] = +100; p[3][y] = -100; p[3][z] = +100;
        p[4][x] = -100; p[4][y] = -100; p[4][z] = +100;
        p[5][x] = -100; p[5][y] = +100; p[5][z] = -100;
        p[6][x] = +100; p[6][y] = +100; p[6][z] = -100;
        p[7][x] = +100; p[7][y] = +100; p[7][z] = +100;
        p[8][x] = -100; p[8][y] = +100; p[8][z] = +100;

        //       8 - - - - - 7
        //     / |         / |
        //    5 - - - - - 6  |
        //    |  |        |  |
        //    |  4 - - - -|- 3
        //    | /         | /
        //    1 - - - - - 2

        // y-Werte spiegeln
        for (int i=1;i<9;i++) {
            p[i][y] = -p[i][y];
        }
    }

    // Rotationswinkel in rad
    double ax = 0.01;
    double ay = 0.0075;
    double az = 0.005;

    Image buffer;
    Graphics2D gBuffer;

    double c[] = new double[9];

    int w = 200; // -> Weltkoordinaten
    double px, py, pz;

    public void paint(Graphics g) {

        // Double-Buffering
        if (buffer==null) {
            buffer=createImage(this.getSize().width, this.getSize().height);
            gBuffer=(Graphics2D)buffer.getGraphics();
        }
        gBuffer.clearRect(0,0, this.getSize().width, this.getSize().height);

        // Antialiasing
        gBuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

        // Perspektive: *1+z/1000
        for (int i=1;i<9;i++) {
            c[i] = 1+p[i][z]/1000;
        }

        // 6 Würfelflächen zeichnen
        drawPolygon(1,2,3,4);
        drawPolygon(7,6,5,8);
        drawPolygon(6,2,1,5);
        drawPolygon(4,3,7,8);
        drawPolygon(3,2,6,7);
        drawPolygon(5,1,4,8);

        g.drawImage (buffer,0,0,this);

        // Verzögerung
        try {Thread.sleep(20);}
        catch (InterruptedException e) {}

        for (int i=1;i<9;i++) {

            px = p[i][x];
            py = p[i][y];
            pz = p[i][z];

            // Rotation um x-Achse
            p[i][y] = py*Math.cos(ax)-pz*Math.sin(ax);
            p[i][z] = py*Math.sin(ax)+pz*Math.cos(ax);

            py = p[i][y];
            pz = p[i][z];

            // Rotation um y-Achse
            p[i][x] = px*Math.cos(ay)+pz*Math.sin(ay);
            p[i][z] =-px*Math.sin(ay)+pz*Math.cos(ay);

            px = p[i][x];

            // Rotation um z-Achse
            p[i][x] = px*Math.cos(az)-py*Math.sin(az);
            p[i][y] = py*Math.cos(az)+px*Math.sin(az);
        }

        repaint();
    }

    public void update(Graphics g) {paint(g);}

    // Fläche zeichnen
    public void drawPolygon(int i, int j, int k, int h) {

        // Kreuzprodukt der eine Fläche aufspannenden Vektoren bilden
        // Wenn Betrag der z-Koordinate positiv: Fläche anzeigen

        if((p[i][x]*c[i]-p[j][x]*c[j])*(p[k][y]*c[k]-p[j][y]*c[j])
          -(p[i][y]*c[i]-p[j][y]*c[j])*(p[k][x]*c[k]-p[j][x]*c[j]) > 0) {
            // |j->i x j->k| > 0

            // x,y-Koordinaten
            int xCoords[] = {(int)(p[i][x]*c[i])+w,(int)(p[j][x]*c[j])+w,
                             (int)(p[k][x]*c[k])+w,(int)(p[h][x]*c[h])+w};
            int yCoords[] = {(int)(p[i][y]*c[i])+w,(int)(p[j][y]*c[j])+w,
                             (int)(p[k][y]*c[k])+w,(int)(p[h][y]*c[h])+w};

            // Winkel zwischen dem Vektor (v1,v2,v3), der senkrecht auf der Fläche steht
            // und dem Einheitsvektor in Richtung der Beleuchtungsquelle (0,0,1)
            // (d.h. Licht von vorne) bestimmt die Helligkeit der Fläche.

            double v1 = (p[i][y]-p[j][y])*(p[k][z]-p[j][z])
                       -(p[i][z]-p[j][z])*(p[k][y]-p[j][y]);
            double v2 = (p[i][z]-p[j][z])*(p[k][x]-p[j][x])
                       -(p[i][x]-p[j][x])*(p[k][z]-p[j][z]);
            double v3 = (p[i][x]-p[j][x])*(p[k][y]-p[j][y])
                       -(p[i][y]-p[j][y])*(p[k][x]-p[j][x]);

            int deg = (int) Math.toDegrees(Math.asin(Math.sqrt(
                        (v2*v2+v1*v1)/(v1*v1+v2*v2+v3*v3))));

            gBuffer.setColor(new Color(220-deg,220-deg,220-deg));
            gBuffer.fillPolygon(new Polygon(xCoords,yCoords,4));
        }
    }
}


Schema der Berechnung des Winkels zwischen dem Vektor v, der senkrecht auf einer Fläche steht und dem Vektor q in Richtung der Lichtquelle:

Einfallswinkel

          | [v1]   [q1] |   | [v1] |   | [q1] |
= arcsin( | [v2] x [q2] | / | [v2] | . | [q2] | )
          | [v3]   [q3] |   | [v3] |   | [q3] |

                 (v2*q3-v3*q2)² + (v3*q1-v1*q3)² + (v1*q2-v2*q1)²
= arcsin( sqrt(  ------------------------------------------------  ) )
                          (v1²+v2²+v3²) * (q1²+q2²+q3²)

Die Wahl von (0,0,1) für (q1,q2,q3) hat die Berechnung erheblich vereinfacht.


Download  Wuerfel_3.zip (Applet und Code, ca. 4 kb)




© 2001-2004 Albert Kluge - Alle Rechte vorbehalten
Impressum | Datenschutz | Nutzung | eMail