|
- Applets : 3D : Würfel 3 -
Ein rotierender Würfel mit Beleuchtungs-Effekt als Java-Applet.
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
|