import java.applet.Applet; import java.awt.*; import java.awt.event.*; /** * * Zoom, Drehungen um 3 Achsen * * @version 1.1 vom 20.05.05 * @H. Wypior */ public class zoom extends Applet { // Anfang Variablen private Leinwand Malflaeche; private Punkt Woben = new Punkt(); private Punkt Wunten = new Punkt(); private WinView WV = new WinView(); private Punkt[] Dreieck = new Punkt[3]; private Scrollbar hsb = new Scrollbar(); private Scrollbar vsb = new Scrollbar(); private CheckboxGroup cbox = new CheckboxGroup(); private Checkbox[] chBox = new Checkbox[3]; //Array anlegen private Panel pa = new Panel(); // Ende Variablen public void init() { Malflaeche = new Leinwand(); setLayout(new BorderLayout()); // Anfang Komponenten add("Center",Malflaeche); add("South", hsb); add("East", vsb); add("North", pa); 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)); } 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.VERTICAL); 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()); } }); // 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 WV.Bild(Dreieck[0]); WV.Bild(Dreieck[1]); WV.Bild(Dreieck[2]); Malflaeche.repaint(); } public void rotate(int phi) { char Achse= cbox.getSelectedCheckbox().getLabel().charAt(0); for (int i=0; i<3; i++) { Dreieck[i].drehen(Achse, phi-Dreieck[i].getWinkel(Achse)); WV.Bild(Dreieck[i]); } 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) Dreieck[nr].getWinkel(achse)); } } private class Leinwand extends Canvas { private Polygon DEck = new Polygon(); Leinwand() { setBackground(Color.BLUE); setForeground(Color.yellow); Dreieck[0]=new Punkt(-500,0,0); Dreieck[1]=new Punkt(500,0,0); Dreieck[2]=new Punkt(0,-400,0); //Dreieck nun im Weltfenster verschieben for (int i=0; i<3; i++) { Dreieck[i].move(200,300,200); //Übergeben wird der Translationsvektor } WV.Bild(Dreieck[0]); WV.Bild(Dreieck[1]); WV.Bild(Dreieck[2]); } public void paint(Graphics g) { g.setColor(Color.orange); for (int i=0; i<3; i++) { DEck.addPoint(Dreieck[i].bx,Dreieck[i].by); } g.fillPolygon(DEck); DEck.reset(); } } private class Punkt { double x,y,z; double rx,ry,rz; double ax,ay,az; double vx,vy,vz; int bx,by,bz; double xWinkel; double yWinkel; double zWinkel; Punkt() { x = 0; y = 0; z rx = 0; ry = 0; ax = 0; ay = 0; bx = 0; by = 0; xWinkel = 0; yWinkel = 0; zWinkel = 0; } //Weltkoordinaten //relative Koordinaten //Anfangskoordinaten(werden nie durch Drehungen verändert) //Viewportkoordinaten //Bildkoordinaten //Winkel, um den der Punkt gedreht wurde (im Bogenmaß) //Nur sinnvoll, wenn nur in einer Ebene gedreht wird! = 0; rz = 0; az = 0; bz = 0; Punkt(double wx,double wy,double wz) { x = wx; y = wy; z = wz; rx = x; ry = y; rz = z; ax = x; ay = y; az = z; bx = 0; by = 0; bz = 0; xWinkel = 0; yWinkel = 0; zWinkel = 0; } 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; 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; } } private { Punkt Punkt Punkt Punkt class WinView WO WU VO VU = = = = new Punkt(-1000,-1000,-1000); // Window-Eckpunkt oben links new Punkt(1000,1000,1000); // Window-Eckpunkt unten rechts new Punkt(0,0,0); // Viewport-Eckpunkt oben links new Punkt(300,300,300); // Viewport-Eckpunkt unten rechts WinView() { } public void changeWindow(Punkt oben, Punkt unten) { WO.neu(oben.x,oben.y,oben.z); WU.neu(unten.x,unten.y,unten.z); } public void changeViewport(Punkt oben, Punkt unten) { VO.neu(oben.x,oben.y,oben.z); VU.neu(unten.x,unten.y,unten.z); } public void Bild(Punkt WP) { double vx = (WP.x - WU.x)*((VO.x-VU.x)/(WO.x-WU.x))+VU.x; double vy = (WP.y - WU.y)*((VO.y-VU.y)/(WO.y-WU.y))+VU.y; double vz = (WP.z - WU.z)*((VO.z-VU.z)/(WO.z-WU.z))+VU.z; WP.bx = (int) vx; WP.by = (int) vy; WP.bz = (int) vz; } } }