Quelltext des Applets - Schulportal Bremerhaven

Werbung
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
/**
*
* Beschreibung.
*
* @version 1.1 vom 01.06.05
* @H. Wypior
*/
public class pyramide01 extends Applet {
// Anfang Variablen
private Leinwand Malflaeche;
private CPunkt A;
private CPunkt B;
private CPunkt C;
private CPunkt D;
private CPyramide DEck;
private CPunkt VO;
private CPunkt VU;
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
// Ende
CPunkt Woben = new CPunkt();
CPunkt Wunten = new CPunkt();
WinView WV = new WinView();
CPunkt xAchse = new CPunkt(3000,0,0);
CPunkt yAchse = new CPunkt(0,3000,0);
CPunkt zAchse = new CPunkt(0,0,3000);
CPunkt Ursprung = new CPunkt(0,0,0);
CPunkt xWelt = new CPunkt(2000,0,0);
CPunkt yWelt = new CPunkt(0,2000,0);
CPunkt zWelt = new CPunkt(0,0,2000);
CPunkt WeltNull = new CPunkt(0,0,0);
CPunkt TVek = new CPunkt(0,0,0);
Scrollbar tsb = new Scrollbar();
Scrollbar hsb = new Scrollbar();
Scrollbar vsb = new Scrollbar();
CheckboxGroup cbox = new CheckboxGroup();
Checkbox[] chBox = new Checkbox[3];
CheckboxGroup cbox1 = new CheckboxGroup();
Checkbox[] chProjektion = new Checkbox[3];
Panel pa2 = new Panel();
Panel pa = new Panel();
Panel paGrafik = new Panel();
Panel paRegler = new Panel();
Label lbAchsenwahl = new Label();
Label lbRotation = new Label();
Label lbZoom = new Label();
Label lbTranslation = new Label();
Label lbProjektion = new Label();
Variablen
public void init()
{
double s = 1000;
DEck = new CPyramide(s,WV);
//Achsenendpunkte
//Weltkoordinaten
//Translationsvektor
//Array anlegen
//Array anlegen
//
Malflaeche = new Leinwand(300,300);
int h = Malflaeche.getHeight();
int w = Malflaeche.getWidth();
VO = new CPunkt(0,0,-100);
VU = new CPunkt(w,h,100);
WV.changeViewport(VO,VU);
setLayout(new FlowLayout());
add(paGrafik);
add(paRegler);
paGrafik.add(Malflaeche);
paRegler.setLayout(new GridLayout(11,1));
lbAchsenwahl.setText("Achsenwahl");
paRegler.add(lbAchsenwahl);
paRegler.add(pa);
lbRotation.setText("Rotation");
paRegler.add(lbRotation);
paRegler.add(vsb);
//Rotation
lbZoom.setText("Zoom");
paRegler.add(lbZoom);
paRegler.add(hsb);
//Zoom
lbTranslation.setText("Translation");
paRegler.add(lbTranslation);
paRegler.add(tsb);
//Translation
lbProjektion.setText("Projektionswahl");
paRegler.add(lbProjektion);
paRegler.add(pa2);
// Anfang Komponenten
chBox[0]=new Checkbox("x-Achse",cbox,false);
chBox[1]=new Checkbox("y-Achse",cbox,false);
chBox[2]=new Checkbox("z-Achse",cbox,true);
for (int i=0; i<3; i++)
{
pa.add(chBox[i]);
chBox[i].addItemListener(new chBoxListener(i));
}
chProjektion[0]=new Checkbox("zentral",cbox1,true);
chProjektion[1]=new Checkbox("schräg",cbox1,false);
chProjektion[2]=new Checkbox("orthogonal",cbox1,false);
for (int i=0; i<3; i++)
{
pa2.add(chProjektion[i]);
chProjektion[i].addItemListener(new chPListener(i));
}
hsb.setOrientation(Scrollbar.HORIZONTAL);
hsb.setMaximum(3000);
hsb.setMinimum(200);
hsb.setValue(2000);
hsb.setUnitIncrement(50);
hsb.setBlockIncrement(200);
hsb.addAdjustmentListener(new AdjustmentListener(){
public void adjustmentValueChanged(AdjustmentEvent e)
{
zoom(hsb.getValue());
}
});
vsb.setOrientation(Scrollbar.HORIZONTAL);
vsb.setMaximum(370); //10 Grad mehr, wegen visible amount
vsb.setValue(0);
vsb.setUnitIncrement(1);
vsb.setBlockIncrement(1);
vsb.addAdjustmentListener(new AdjustmentListener(){
public void adjustmentValueChanged(AdjustmentEvent e)
{
rotate(vsb.getValue());
}
});
tsb.setOrientation(Scrollbar.HORIZONTAL);
tsb.setMaximum(500); //10 Grad mehr, wegen visible amount
tsb.setMinimum(-500);
tsb.setValue(0);
tsb.setUnitIncrement(1);
tsb.setBlockIncrement(10);
tsb.addAdjustmentListener(new AdjustmentListener(){
public void adjustmentValueChanged(AdjustmentEvent e)
{
translate(tsb.getValue());
}
});
// Ende Komponenten
}
// Anfang Ereignisprozeduren
public void zoom(int pos)
{
Woben.neu(-pos/2,-pos/2,-pos/2);
Wunten.neu(pos/2,pos/2,pos/2);
WV.changeWindow(Woben,Wunten); //Zoom berechnen
xAchse.Bild(WV);
yAchse.Bild(WV);
zAchse.Bild(WV);
Ursprung.Bild(WV);
xWelt.Bild(WV);
yWelt.Bild(WV);
zWelt.Bild(WV);
WeltNull.Bild(WV);
Malflaeche.repaint();
}
public void rotate(int phi)
{ char Achse= cbox.getSelectedCheckbox().getLabel().charAt(0);
DEck.drehen(Achse, phi-DEck.getWinkel(Achse));
xAchse.drehen(Achse, phi-xAchse.getWinkel(Achse));
yAchse.drehen(Achse, phi-yAchse.getWinkel(Achse));
zAchse.drehen(Achse, phi-zAchse.getWinkel(Achse));
Ursprung.drehen(Achse, phi-Ursprung.getWinkel(Achse));
xAchse.Bild(WV);
//Bildkoordinaten der Achsenendpunkte
yAchse.Bild(WV);
zAchse.Bild(WV);
Ursprung.Bild(WV);
Malflaeche.repaint();
}
public void translate(int v)
{
double tx,ty,tz;
//Translationsvektor
tx = DEck.Flaeche[0].E[0].x-DEck.Flaeche[0].E[0].rx;
TVek.x=v-tx;
ty = DEck.Flaeche[0].E[0].y-DEck.Flaeche[0].E[0].ry;
TVek.y=v-ty;
tz = DEck.Flaeche[0].E[0].z-DEck.Flaeche[0].E[0].rz;
TVek.z=v-tz;
DEck.move(TVek.x,TVek.y,TVek.z); //Übergeben wird der Translationsvektor
xAchse.move(TVek.x,TVek.y,TVek.z);
yAchse.move(TVek.x,TVek.y,TVek.z);
zAchse.move(TVek.x,TVek.y,TVek.z);
Ursprung.move(TVek.x,TVek.y,TVek.z);
xAchse.Bild(WV);
//Bildkoordinaten der Achsenendpunkte
yAchse.Bild(WV);
zAchse.Bild(WV);
Ursprung.Bild(WV);
Malflaeche.repaint();
}
// Ende Ereignisprozeduren
private class chBoxListener implements ItemListener
{
int nr;
char achse;
chBoxListener(int no)
{
nr = no;
switch (no)
{
case 0: achse = 'x'; break;
case 1: achse = 'y'; break;
default: achse = 'z'; break;
}
}
public void itemStateChanged(ItemEvent e)
//durchs Interface vorgegeben
{
vsb.setValue((int) DEck.getWinkel(achse));
}
}
private class chPListener implements ItemListener
{
private int ID;
chPListener(int no)
{
ID = no;
}
public void itemStateChanged(ItemEvent e)
{
WV.PArt = ID;
Malflaeche.repaint();
}
}
private class Leinwand extends Canvas
//durchs Interface vorgegeben
{
int Breite;
int Hoehe;
Leinwand(int width, int height)
{
Breite = width;
Hoehe = height;
setBackground(Color.BLUE);
setForeground(Color.yellow);
//Dreieck nun im Weltfenster verschieben
DEck.move(TVek.x,TVek.y,TVek.z);
xAchse.move(TVek.x,TVek.y,TVek.z);
yAchse.move(TVek.x,TVek.y,TVek.z);
zAchse.move(TVek.x,TVek.y,TVek.z);
Ursprung.move(TVek.x,TVek.y,TVek.z);
xAchse.Bild(WV);
yAchse.Bild(WV);
zAchse.Bild(WV);
Ursprung.Bild(WV);
xWelt.Bild(WV);
yWelt.Bild(WV);
zWelt.Bild(WV);
WeltNull.Bild(WV);
DEck.Bild();
}
public Dimension getMinimumSize()
{
return new Dimension(Breite,Hoehe);
}
public Dimension getPreferredSize()
{
return getMinimumSize();
}
public void paint(Graphics g)
{
g.setColor(Color.white);
//g.drawLine(Ursprung.bx,Ursprung.by,xAchse.bx,xAchse.by);
DEck.zeichne(g);
//g.drawLine(Ursprung.bx,Ursprung.by,yAchse.bx,yAchse.by);
g.setColor(Color.yellow);
//g.drawLine(Ursprung.bx,Ursprung.by,zAchse.bx,zAchse.by);
//g.setColor(Color.green);
g.drawLine(WeltNull.bx,WeltNull.by,xWelt.bx,xWelt.by);
g.drawLine(WeltNull.bx,WeltNull.by,yWelt.bx,yWelt.by);
g.drawLine(WeltNull.bx,WeltNull.by,zWelt.bx,zWelt.by);
}
}
private class CPyramide
{
private WinView Welt;
private CPunkt ViewUp = new CPunkt(0,0,1);
private CPunkt A;
//Standort der Kamera
private
private
private
private
private
CPunkt B;
CPunkt C;
CPunkt D;
CPunkt S;
CDreieck Flaeche[] = new CDreieck[6];
CPyramide(double Seite, WinView VW)
{
Welt = VW;
double s = Seite;
double b = s/2;
//halbe Grundseite
double d = Math.sqrt(s*s + s*s); //Diagonale in der Grundfläche
double c = d/2;
//halbe Grundseitenhöhe
double h = Math.sqrt(s*s-c*c);
//Höhe der Pyramide
A = new CPunkt(-b,-b,-h/2);
B = new CPunkt(b,-b,-h/2);
C = new CPunkt(b,b,-h/2);
D = new CPunkt(-b,b,-h/2);
S = new CPunkt(0,0,h/2);
Flaeche[0] = new CDreieck(A,B,C,Color.magenta,WV,ViewUp); //Grundfläche
Flaeche[1] = new CDreieck(A,C,D,Color.magenta,WV,ViewUp); //Grundfläche
Flaeche[2] = new CDreieck(A,S,B,Color.yellow,WV,ViewUp);
Flaeche[3] = new CDreieck(B,S,C,Color.red,WV,ViewUp);
Flaeche[4] = new CDreieck(C,S,D,Color.white,WV,ViewUp);
Flaeche[5] = new CDreieck(D,S,A,Color.orange,WV,ViewUp);
}
public void move(double tx,double ty,double tz)
{
for (int i=0; i<6; i++)
{
Flaeche[i].move(tx,ty,tz);
}
}
public void drehen(char achse, double alpha)
{
for (int i=0; i<6; i++)
{
Flaeche[i].drehen(achse,alpha);
}
}
public void Bild()
{
for (int i=0; i<6; i++)
{
Flaeche[i].Bild();
}
}
public void zeichne(Graphics gr)
{
Bild();
for (int i=0; i<6; i++)
{
Flaeche[i].zeichne(gr);
//Translationsvektor
}
}
public double getWinkel (char achse)
{
return Flaeche[0].getWinkel(achse);
}
}
private class CDreieck
{
private WinView Welt;
private CPunkt K;
private Polygon PDEck = new Polygon();
private CPunkt u = new CPunkt();
private CPunkt v = new CPunkt();
private CPunkt n = new CPunkt();
CPunkt[] E = new CPunkt[3];
Color Farbe;
//Kamera (Viewup-Vektor)
//Richtungsvektoren
//äußerer Normalenvektor
//Ecken
CDreieck(CPunkt A, CPunkt B, CPunkt C,
Color color, WinView VW, CPunkt Kamera)
{
Welt = VW;
K = Kamera;
E[0] = new CPunkt(A.x,A.y,A.z);
E[1] = new CPunkt(B.x,B.y,B.z);
E[2] = new CPunkt(C.x,C.y,C.z);
Farbe = color;
}
public void move(double tx,double ty,double tz)
{
for (int i=0; i<3; i++)
{
E[i].move(tx,ty,tz);
}
}
public void drehen(char achse, double alpha)
{
for (int i=0; i<3; i++)
{
E[i].drehen(achse,alpha);
}
}
public void Bild()
{
for (int i=0; i<3; i++)
{
Welt.Bild(E[i]);
}
}
public void zeichne(Graphics gr)
//Translationsvektor
{
Bild();
if (sichtbar())
{
gr.setColor(Farbe);
for (int i=0; i<3; i++)
{
PDEck.addPoint(E[i].bx,E[i].by);
}
gr.fillPolygon(PDEck);
PDEck.reset();
}
}
public boolean sichtbar()
{
u.neu(E[0].bx-E[1].bx, E[0].by-E[1].by,E[0].bz-E[1].bz);
v.neu(E[2].bx-E[1].bx, E[2].by-E[1].by,E[2].bz-E[1].bz);
n.neu(u.y*v.z-u.z*v.y, u.z*v.x-u.x*v.z, u.x*v.y-u.y*v.x);
//double sicht = n.x*K.x+n.y*K.y+n.z*K.z;
double sicht = n.z;
return sicht>0;
}
public double getWinkel (char achse)
{
return E[0].getWinkel(achse);
}
}
private class CPunkt
{
double x,y,z;
//Weltkoordinaten
double rx,ry,rz; //relative Koordinaten
double ax,ay,az; //Anfangskoordinaten(werden nie durch Drehungen verändert)
double vx,vy,vz; //Viewportkoordinaten
int bx,by,bz;
//Bildkoordinaten
double xWinkel;
//Winkel, um den der CPunkt gedreht wurde (im Bogenmaß)
double yWinkel;
//Nur sinnvoll, wenn nur in einer Ebene gedreht wird!
double zWinkel;
double Matrix[][] = new double[4][4];
CPunkt()
{
x = 0; y = 0; z
rx = 0; ry = 0;
ax = 0; ay = 0;
vx = 0; vy = 0;
bx = 0; by = 0;
xWinkel = 0;
yWinkel = 0;
zWinkel = 0;
}
= 0;
rz =
az =
vz =
bz =
0;
0;
0;
0;
CPunkt(double wx,double wy,double wz)
{
x = wx; y = wy;
rx = x; ry = y;
ax = x; ay = y;
vx = 0; vy = 0;
bx = 0; by = 0;
xWinkel = 0;
yWinkel = 0;
zWinkel = 0;
z = wz;
rz = z;
az = z;
vz = 0;
bz = 0;
}
public void neg(){
x=-x;
y=-y;
z=-z;
}
public void neu(double nx,double ny,double nz)
{
x = nx; y = ny; z = nz;
rx = x; ry = y; rz = z;
ax = x; ay = y; az = z;
vx = 0; vy = 0; vz = 0;
bx = 0; by = 0; bz = 0;
xWinkel = 0;
yWinkel = 0;
zWinkel = 0;
}
public void move(double tx,double ty,double tz)
//Translationsvektor
{
x = x+tx; y = y+ty; z = z+tz;
//Weltkoordinaten verändern!
}
public void relmove(double tx,double ty,double tz) //Translationsvektor
{
rx = rx+tx; ry = ry+ty; rz = rz+tz;
//rel. Koordinaten verändern!
x = x+tx; y = y+ty; z = z+tz;
//und auch Weltkoord. anpassen
}
public double getWinkel (char achse)
{ double Winkel;
switch (achse)
{
case 'x': Winkel = xWinkel; break;
case 'y': Winkel = yWinkel; break;
case 'z': Winkel = zWinkel; break;
default : Winkel = 0;
}
return Math.toDegrees(Winkel);
}
public void drehen(char achse, double alpha)
{
double Winkel;
double x1,y1,z1;
double tx,ty,tz;
//Translationsvektor
Winkel = Math.toRadians(alpha);
tx=x-rx; ty=y-ry; tz=z-rz;
x1=rx; y1=ry; z1=rz;
switch (achse)
{
case 'x':
xWinkel = xWinkel+Winkel;
ry=y1*Math.cos(Winkel)-z1*Math.sin(Winkel);
rz=y1*Math.sin(Winkel)+z1*Math.cos(Winkel);
break;
case 'y':
yWinkel = yWinkel+Winkel;
rx=x1*Math.cos(Winkel)+z1*Math.sin(Winkel);
rz=-x1*Math.sin(Winkel)+z1*Math.cos(Winkel);
break;
case 'z':
zWinkel = zWinkel+Winkel;
rx=x1*Math.cos(Winkel)-y1*Math.sin(Winkel);
ry=x1*Math.sin(Winkel)+y1*Math.cos(Winkel);
break;
}
x=rx+tx; y=ry+ty; z=rz+tz;
}
public Matrix schraegDrehen(CPunkt P, CPunkt Q, double phi)
{
Matrix M = new Matrix();
double winkel = Math.toRadians(phi);
CPunkt v = new CPunkt(Q.x-P.x,Q.y-P.y,Q.z-P.z); //Richtungsvektor
double vBetrag = Math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
double a = v.x/vBetrag;
double b = v.y/vBetrag;
double c = v.z/vBetrag;
double alpha = Math.asin(b/Math.sqrt(b*b+c*c));
double beta = Math.asin(a);
Matrix T = new Matrix();
CPunkt np = new CPunkt(-P.x,-P.y,-P.z);
T.makeTranslMatrix(np);
Matrix Dx = new Matrix();
Dx.makeDrehMatrix('x',alpha);
Matrix Dy = new Matrix();
Dy.makeDrehMatrix('y',-beta);
Matrix Dz = new Matrix();
Dz.makeDrehMatrix('z',phi);
Matrix IDy = new Matrix();
IDy.makeDrehMatrix('y',beta);
Matrix IDx = new Matrix();
IDx.makeDrehMatrix('x',-alpha);
M=MMul(M,T);
M=MMul(M,Dx);
return M;
}
public void Bild(WinView VW)
{
VW.Bild(this);
}
private Matrix MMul(Matrix a,Matrix b)
{
Matrix tmp=new Matrix();
for (int i=0; i<tmp.E.length; i++)
{
for (int j=0; j<4; j++)
{
tmp.E[i][j]=0;
for (int k=0; k<4; k++)
{
tmp.E[i][j]+=a.E[i][k]*b.E[k][j];
}
}
}
return tmp;
}
}
private class WinView
{
private CPunkt WO;
private CPunkt WU;
private CPunkt VO;
private CPunkt VU;
public int PArt;
private double a;
private double b;
private double Abstand;
//
//
//
//
//
Window-Eckpunkt oben links
Window-Eckpunkt unten rechts
Viewport-Eckpunkt oben links
Viewport-Eckpunkt unten rechts
Projektionsart
//Parameter für Schrägprojektion
// Kameraposition auf der z-Achse
WinView()
{
WO = new CPunkt(-1000,-1000,-1000);
WU = new CPunkt(1000,1000,1000);
VO = new CPunkt(0,0,0);
VU = new CPunkt(200,200,100);
PArt = 0;
// Projektionsart orthogonal
Abstand = 2000;
//a = 0.5;
//b = 0.2;
a = Math.toRadians(Math.sin(120));
b = Math.toRadians(Math.cos(120));
}
public void changeWindow(CPunkt oben, CPunkt unten)
{
WO.neu(oben.x,oben.y,oben.z);
WU.neu(unten.x,unten.y,unten.z);
}
public void changeViewport(CPunkt oben, CPunkt unten)
{
VO.neu(oben.x,oben.y,oben.z);
VU.neu(unten.x,unten.y,unten.z);
}
public void Bild(CPunkt WP)
{
double bx,by,bz;
switch (PArt)
{
case 0:
// Zentral
double d = Abstand;
bx = (int)(d/(d-WP.z)*WP.x);
by = (int)(d/(d-WP.z)*WP.y);
bz = (int)(WP.z);
break;
case 1:
bx = (int) (WP.x+a*WP.z);
by = (int) (WP.y+b*WP.z);
bz = (int) (WP.z);
break;
default:
bx = WP.x;
by = WP.y;
bz = WP.z;
break;
}
WP.vx
WP.vy
WP.vz
WP.bx
WP.by
WP.bz
=
=
=
=
=
=
(bx (by (bz (int)
(int)
(int)
// Orthogonal
WU.x)*((VO.x-VU.x)/(WO.x-WU.x))+VU.x;
WU.y)*((VO.y-VU.y)/(WO.y-WU.y))+VU.y;
WU.z)*((VO.z-VU.z)/(WO.z-WU.z))+VU.z;
WP.vx;
WP.vy;
WP.vz;
}
}
private class Matrix
{
double E[][]=new double[4][4];
Matrix()
{
for (int i=0; i<4; i++)
for (int k=0; k<4; k++)
{
if(i==k)
{
E[i][k]=1;
}
else
{
E[i][k]=0;
}
}
}
public void makeTranslMatrix(CPunkt P)
{
E[3][0] = P.x;
E[3][1] = P.y;
E[3][2] = P.z;
}
public void makeDrehMatrix(char Achse, double alpha)
{
double Winkel;
Winkel = Math.toRadians(alpha);
switch (Achse)
{
case 'x':
E[1][1]=Math.cos(Winkel);
E[1][2]=Math.sin(Winkel);
E[2][1]=-Math.sin(Winkel);
E[2][2]=Math.cos(Winkel);
break;
case 'y':
E[0][0]=Math.cos(Winkel);
E[0][2]=-Math.sin(Winkel);
E[2][0]=Math.sin(Winkel);
E[2][2]=Math.cos(Winkel);
break;
case 'z':
E[0][0]=Math.cos(Winkel);
E[0][1]=Math.sin(Winkel);
E[1][0]=-Math.sin(Winkel);
E[1][1]=Math.cos(Winkel);
break;
}
}
}
}
Herunterladen