// *********************************************************** // >>start // >name: RunningRainbow // >class: Applet // >Autor: (C) 1996 by Oleg V. Baranovsky. // >e-mail: oleg@usemb.kiev.ua // >URL: http://www.usemb.kiev.ua/oleg/ // >Description: // >>start // Implements different methods for generation of running rainbow lines // >>end // >Classification: Graphics/VisualEffects // >>end // *********************************************************** import java.awt.*; import java.applet.Applet; import java.lang.Math; import java.lang.System; public class RunningRainbow extends Applet implements Runnable { int delay; int shift; int offset; double ss, ar, ag, ab, sr, sg ,sb, ar1; String direction; String method; boolean isInvert; boolean isRunning; boolean isParams=false; Thread animatorThread; Image offImage; Graphics offGraphics; public void init() { isRunning=true; if (!isParams) getParams(); } public void getParams() { String str; isParams=true; // How many milliseconds between frames? str = getParameter("delay"); int fps = (str != null) ? Integer.parseInt(str) : 100; delay = (fps > 10) ? fps : 100; // Shift between frames. str = getParameter("shift"); fps = (str != null) ? Integer.parseInt(str) : 2; fps = (fps >= 0 && fps < 256) ? fps : 2; shift = size().width*fps/256; direction = getParameter("direction"); if (direction == null) direction = new String("left"); str = getParameter("invert"); isInvert = str != null; method = getParameter("method"); if (method == null) method = new String("none"); if (method.compareTo("gaussian") == 0){ //Now let's get parameters for color generator. ar = getDoubleParam("ar", 0.); ag = getDoubleParam("ag", 0.5); ab = getDoubleParam("ab", 1.); ar1 = getDoubleParam("ar1", 0.); if (getParameter("ss") != null) { ss = getDoubleParam("ss", 0.5); sr = sg = sb = ss; } else { sr = getDoubleParam("sr", 0.5); sg = getDoubleParam("sg", 0.5); sb = getDoubleParam("sb", 0.5); } sr = sr*sr/2; sg = sg*sg/2; sb = sb*sb/2; } } public double getDoubleParam(String param, double defValue) { String str; double dbl; str = getParameter(param); if (str != null) dbl = parseDouble(str); else dbl = defValue; if (dbl < 0 || dbl > 1) dbl = defValue; return dbl; } public void start() { if (isRunning) { if (animatorThread == null) { animatorThread = new Thread(this); //getParams(); } animatorThread.start(); } } public void stop() { animatorThread = null; } public boolean mouseDown(Event e, int x, int y) { if(isRunning) { isRunning=false; stop(); } else { isRunning=true; start(); } return true; } public void run() { //Let's put somehow lower than normal priority. Thread.currentThread().setPriority(3); if (direction.compareTo("none") == 0) { offset = shift; repaint(); return; } // Remember the starting time long startTime = System.currentTimeMillis(); while (Thread.currentThread() == animatorThread) { // Display the next frame of animation. repaint(); // Delay depending on how far we are behind. try { startTime += delay; Thread.sleep(Math.max(0, startTime-System.currentTimeMillis())); } catch (InterruptedException e) { break; } if (direction.compareTo("right") == 0) { offset-=shift; if (offset < 0) offset = size().width; } else if (direction.compareTo("left") == 0) { offset+=shift; if (offset >= size().width) offset = 0; } } } // Paint the previous frame (if any). public void paint(Graphics g) { if (offImage != null) { g.drawImage(offImage, -offset, 0, this); g.drawImage(offImage, size().width-offset, 0, this); } } public void update(Graphics g) { if (offImage == null) createBuffer(); g.drawImage(offImage, -offset, 0, this); g.drawImage(offImage, size().width-offset, 0, this); } public void createBuffer() { int x; if (offImage == null) offImage=createImage(size().width, size().height); offGraphics=offImage.getGraphics(); if (method.compareTo("gaussian") == 0) { for (x = 0; x < size().width; x++) { offGraphics.setColor(cg(x)); offGraphics.drawLine(x, 0, x, size().height); } } else { for (x = 0; x < size().width; x++) { offGraphics.setColor(c(x)); offGraphics.drawLine(x, 0, x, size().height); } } } public Color c(int x){ if (x >= size().width) x -= size().width; double y = (double)x * 6. / (double)(size().width); double r, g, b; if (y < 1) { r = 1; g = y; b = 0;} else if (y < 2) { r = 2.-y; g = 1; b = 0;} else if (y < 3) { r = 0; g = 1; b = y-2.0;} else if (y < 4) { r = 0; g = 4.0-y; b = 1;} else if (y < 5) { r = y-4.0; g = 0; b = 1;} else { r = 1; g = 0; b = 6.0-y;} return new Color((float)r, (float)g, (float)b); } public Color cg(int x){ while (x >= size().width) {x -= size().width;}; double y = (double)x / (double)(size().width); double r, g, b; if (ar1 != 0 && y > 0.5) r = y - ar1; else r = y - ar; g = y - ag; b = y - ab; if (sr != 0) r = Math.exp(-r*r/sr); else r = 0; if (sg != 0) g = Math.exp(-g*g/sg); else g = 0; if (sb != 0) b = Math.exp(-b*b/sb); else b = 0; if (isInvert) return new Color((float)(1-r), (float)(1-g), (float)(1-b)); else return new Color((float)r, (float)g, (float)b); } public double parseDouble(String str) { Double d = new Double(str); return d.doubleValue(); } public String getAppletInfo() { return "Running Rainbow applet. Copyright (c)1997, by Oleg V. Baranovsky."; } public String[][] getParameterInfo() { String[][] info = { // Parameter Name Kind of Value Description {"delay", "Integer", "delay of animation"}, {"shift", "Integer", "shift of animation"}, {"direction", "String", "direction of animation: left or right"}, {"method", "Integer", "method of rainbow rendering: gaussian or trapezoid"}, {"ar", "Double", "mean value of red component"}, {"ag", "Double", "mean value of green component"}, {"ab", "Double", "mean value of blue component"}, {"sr", "Double", "dispersion of red component"}, {"sg", "Double", "dispersion of green component"}, {"sb", "Double", "dispersion of blue component"}, }; return info; } }