/**************************************************************************** ** SpinTetra.java - applet to draw spinning tetrahedron ** Copyright (C) 1996 Ray L. Ewbank ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** ** Direct any questions concerning this piece of Software to: ** ** Ray L. Ewbank ** 29-02 Arlington Road ** Woburn, MA 01801 ** ** (617) 938-7137 ** ** ewbank@gis.net **************************************************************************** */ import java.applet.Applet; import java.awt.Graphics; import java.awt.Point; import java.awt.Color; import java.awt.Event; import java.awt.Dimension; import java.io.StreamTokenizer; import java.io.InputStream; import java.io.IOException; import java.net.URL; public class SpinTetra extends Applet implements Runnable { Twin twin; Eye eye; int tri[] = {0,3,2,2,3,1,1,3,0,0,2,1}; Point3d p[] = { new Point3d( 0.5,-Math.sqrt(3.0)/6.0,-Math.sqrt(3.0)/6.0), new Point3d(-0.5,-Math.sqrt(3.0)/6.0,-Math.sqrt(3.0)/6.0), new Point3d( 0.0, Math.sqrt(3.0)/3.0,-Math.sqrt(3.0)/6.0), new Point3d( 0.0, 0.0, Math.sqrt(3.0)/3.0) }; Point3d tp[]; boolean drawtri[]; Point2d tp2[]; Point dp[]; Thread spinThread; double ct = Math.cos(0.05); double st = Math.sin(0.05); public void init() { eye = new Eye(1.0,2.0,1.0); tp = new Point3d[4]; drawtri = new boolean[4]; tp2 = new Point2d[4]; dp = new Point[4]; computedraw1(); setwindow(); computedraw2(); } public void computedraw() { computedraw1(); computedraw2(); } public void computedraw1() { for (int i=0; i<4; i++) { tp[i] = eye.transform(p[i]); } for (int i=0; i<4; i++) { int k = i*3; drawtri[i] = tp[tri[k+0]].subtract(tp[tri[k+1]]).crossp( tp[tri[k+2]].subtract(tp[tri[k+1]])).z < 0.0; } for (int i=0; i<4; i++) { tp2[i] = new Point2d(tp[i].y/tp[i].z, tp[i].x/tp[i].z); } } void setwindow() { double xmin, xmax, ymin,ymax; xmin = ymin = xmax = ymax = 0.0; for (int i=0; i<4; i++) { if (i == 0) { xmin = xmax = tp2[i].x; ymin = ymax = tp2[i].y; } else { xmin = tp2[i].x < xmin ? tp2[i].x : xmin; xmax = tp2[i].x > xmax ? tp2[i].x : xmax; ymin = tp2[i].y < ymin ? tp2[i].y : ymin; ymax = tp2[i].y > ymax ? tp2[i].y : ymax; } } twin = new Twin(); twin.setDimension(size()); twin.setWindow(xmin,ymin,xmax,ymax); twin.scale(1.2); } void computedraw2() { for (int i=0; i<4; i++) { dp[i] = twin.transform(tp2[i]); } } public void rotate() { for (int i=0; i<4; i++) { double xs = p[i].x; double ys = p[i].y; p[i].x = ct*xs+st*ys; p[i].y = -st*xs+ct*ys; } } public void start() { if (spinThread == null) { spinThread = new Thread(this,"SpinThread"); spinThread.start(); } } public void stop() { spinThread.stop(); spinThread = null; } public void run() { while (spinThread != null) { repaint(); /* ** This doesn't work without this sleep call - I think it should, ** but that this has something to do with pre-emptive threads ** not implemented on Linux */ try { spinThread.sleep(100); } catch(InterruptedException e) { } rotate(); computedraw(); } } /* ** For better performance (to eliminate the small amount of ** flickering that you DO see), redefine the update() method ** so that it does something other than fill the window with ** the background color, then call paint. */ public void paint(Graphics g) { for (int i=0; i<4; i++) { int k = i*3; if (drawtri[i]) { g.drawLine(dp[tri[k]].x,dp[tri[k]].y, dp[tri[k+1]].x,dp[tri[k+1]].y); g.drawLine(dp[tri[k+1]].x,dp[tri[k+1]].y, dp[tri[k+2]].x,dp[tri[k+2]].y); g.drawLine(dp[tri[k+2]].x,dp[tri[k+2]].y, dp[tri[k]].x,dp[tri[k]].y); } } } }