/* * Copyright (C) 2002 Clemens Fuchslocher * * ddd.java - 14.02.2002 - v0.1 * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * Tested with: * o Netscape Navigator 4.79 & Java 1.1.5 - Windows 98SE * o Netscape Navigator 4.79 & Java 1.1.5 - GNU/Linux * o Netscape Navigator 4.79 & Java(TM) 2 Runtime Environment, SE v1.3.1 - GNU/Linux * o Internet Explorer 5.0 & Microsoft VM for Java, 5.0 Release 5.0.0.3167 - Windows 98SE * o Internet Explorer 5.0 & Java(TM) 2 Runtime Environment, SE v1.3.1 - Windows 98SE * o Mozilla 0.9.9 & Java(TM) 2 Runtime Environment, SE v1.3.1 - GNU/Linux * o Opera 6.01 & Sun Java Runtime Environment 1.3 - Windows 98SE * o Opera 6 B1 & Java(TM) 2 Runtime Environment, SE v1.3.1 - GNU/Linux * o appletviewer, Java(TM) 2 SDK, Standard Edition v1.3.1 - GNU/Linux * */ import java.awt.*; import java.awt.event.*; import java.applet.Applet; import java.util.Hashtable; public class ddd extends Applet implements ItemListener { private ddd_calc c; private List list; public void init () { setLayout (new FlowLayout (FlowLayout.LEFT)); list = new List (7, false); list.add ("line"); list.add ("helix"); list.add ("plane"); list.add ("rectangle"); list.add ("big_circle"); list.add ("small_circle"); list.select (0); list.addItemListener (this); add (list); } public void start () { c = new ddd_calc (this); c.go = true; c.start (); } public void stop () { c.go = false; } public void destroy () { } public String getAppletInfo() { return "ddd v0.1 - 14.02.2002 - Clemens Fuchslocher - http://www.fht-esslingen.de/~clfuit00/"; } public void itemStateChanged (ItemEvent e) { c.selected = (star []) c.objects.get (list.getSelectedItem ()); } } class star { public double x, y, z; star (double x, double y, double z) { this.x = x; this.y = y; this.z = z; } } class ddd_calc extends Thread { private final int FPS = 1000/60; private final int STARS = 800; private final int PERIOD = 315; // sin (x/(16*pi), T=2*pi/w, w=1/12*pi private Applet a; private double sin_table[]; private double cos_table[]; private star line[]; private star helix[]; private star plane[]; private star current[]; private star rectangle[]; private star big_circle[]; private star small_circle[]; private int width, height; private Graphics g; private Graphics offscreen_g; private Image offscreen; public star selected[]; public Hashtable objects; public boolean go = false; public ddd_calc (Applet a) { this.a = a; width = a.getSize ().width; height = a.getSize ().height; offscreen = a.createImage(width, height); offscreen_g = offscreen.getGraphics (); g = a.getGraphics (); line = new star[STARS]; helix = new star[STARS]; plane = new star[STARS]; current = new star[STARS]; rectangle = new star[STARS]; big_circle = new star[STARS]; small_circle = new star[STARS]; sin_table = new double [PERIOD]; cos_table = new double [PERIOD]; for (int i = 0; i < PERIOD; i++) { sin_table[i] = Math.sin (i / (16 * Math.PI)); cos_table[i] = Math.cos (i / (16 * Math.PI)); } for (int i = 0; i < STARS; i++) { /* helix */ helix[i] = new star (50 * Math.sin (i / (3 * Math.PI)), 50 * Math.cos (i / (3 * Math.PI)), i/1.5 - 266); /* line */ line[i] = new star (i/1.5 - 266, 0, 1); /* big_circle */ big_circle[i] = new star (140 * Math.sin (i / Math.PI), 140 * Math.cos (i / Math.PI), 1); /* small_circle */ small_circle[i] = new star (1, 40 * Math.sin (i / Math.PI), 40 * Math.cos (i / Math.PI)); /* plane */ plane[i] = new star ((Math.random () * 320) - 160, 1, (Math.random () * 320) - 160); current[i] = new star (0, 0, 0); } /* rectangle */ int i = 0; for (int z = 0; z < 8; z++) { for (int y = 0; y < 10; y++) { for (int x = 0; x < 10; x++) { rectangle[i] = new star ((x * 30) - 150, (y * 30) - 150, (z * 30) - 120); i++; } } } objects = new Hashtable (); objects.put ("line", line); objects.put ("helix", helix); objects.put ("plane", plane); objects.put ("rectangle", rectangle); objects.put ("big_circle", big_circle); objects.put ("small_circle", small_circle); selected = line; } public void run () { Color color; double cos; double sin; int t = 0; long time = System.currentTimeMillis (); int fps = 0; int frames = 0; int seconds = 0; double x, y, z; double x_t, y_t, z_t; double x_delta, y_delta, z_delta; long this_tick_count; long last_tick_count = System.currentTimeMillis (); while (go) { frames++; offscreen_g.setColor (Color.black); offscreen_g.fillRect(0, 0, width, height); if ((System.currentTimeMillis () - time) >= 1000) { seconds++; time = System.currentTimeMillis (); fps = ((frames/seconds) * 100) / 100; } offscreen_g.setColor (Color.white); offscreen_g.drawString(fps + " fps", width/2, height-20); t = (t + 1) % PERIOD; cos = cos_table[t]; sin = sin_table[t]; for (int i = 0; i < STARS; i++) { x_t = selected[i].x; y_t = selected[i].y; z_t = selected[i].z; x_delta = (current[i].x - x_t) / 40; y_delta = (current[i].y - y_t) / 40; z_delta = (current[i].z - z_t) / 40; x = current[i].x -= x_delta; y = current[i].y -= y_delta; z = current[i].z -= z_delta; // Mathematische Formelsammlung, Lothar Papula, 5. Auflage // 9.1.3.3 Drehung eines kartesischen Koordinatensystems // rotation um y achse x_t = (x * cos + z * sin); z_t = (x * -sin + z * cos); x = x_t; z = z_t; // rotation um x achse y_t = (y * cos + z * -sin); z_t = (y * sin + z * cos); y = y_t; z = z_t; // rotation um z achse x_t = (x * cos + y * -sin); y_t = (x * sin + y * cos); x = x_t; y = y_t; int c = (int) z + 200; if (c > 255) c = 255; else if (c < 0) c = 0; color = new Color (c, c, c); // 3d -> 2d projektion, strahlensatz, mc extra 3/95 offscreen_g.setColor (color); offscreen_g.fillRect ((int) (200 * (x / (z/2 - 300)) + width/2), (int) (200 * (y / (z/2 - 300)) + height/2), 2, 2); } this_tick_count = System.currentTimeMillis (); if ((this_tick_count - last_tick_count) < FPS) { try { Thread.sleep (FPS - (this_tick_count - last_tick_count)); } catch (InterruptedException e) { } } last_tick_count = this_tick_count; g.drawImage (offscreen, 0, 0, a); } } }