/* Spiro by Jimmc * Copyright 1996 Jim McBeath * * Permission to use, copy, and distribute Spiro, in source or binary form, * for personal non-commercial use is hereby granted without fee, provided * that this copyright notice appears in all copies, and that no charge is * associated with such copies. * * Permission to modify Spiro and make derivative works for personal * non-commercial use, and to distribute such modified versions, is hereby * granted without fee, provided that the users of such a modified version * are clearly notified that the work is a modified version of Spiro and * not the original Spiro. As with unmodified distributions, this copyight * notice must appear in all modified copies, and no charge may be associated * with such copies. * * The author makes no representations about the suitability of this software * for any purpose. It is provided "as-is", without any express or implied * warranty. In no event will the author be held liable for any damages * arising from the use of this software. */ /* SpiroCanvas - the drawing and state portion of Spiro * * Jim McBeath, May 1996 */ import java.util.Properties; import java.awt.*; import java.io.*; import java.net.URL; class SpiroState { /* Parameters controling the image. If adding or chainging these, need * to modify methods that convert between SpiroState and properties */ WheelState wheels[]; String color; /* name(RGB) of color in which to draw this pattern */ int dashPattern[]; /* on/off/etc steps */ int steps; /* numer of steps requested */ String chain; /* chain draw another file first */ /* The following portions of the state are ignored when chained */ boolean animate; /* true means draw wheels and go slowly */ int animationDelay; boolean animateCount; String drawMode; /* Synchronous, Direct, or Backing */ /* Internal state variables used during generation of the image, * reset at the beginning of drawing the image. */ int numwheels; int lcmsteps; /* LCM of teeth counts in wheels[] */ int numsteps; /* either lcmsteps or user-requested number of steps */ int stepNumber; //The number of the current step being animated int lastx, lasty; int x, y; int cx, cy; int dashIndex; /* index into dashPattern */ int dashOffset; /* offset into count at dashPattern[dashIndex] */ boolean drawState; /* true to draw, false to skip */ public SpiroState(int nwheels) { numwheels = nwheels; wheels = new WheelState[numwheels]; //Set up default values in case no Advanced mode drawMode = "Direct"; } protected void clearWheels() { /* clear wheel state, and calculate first point */ int i; x = cx; y = cy; int t[] = new int[numwheels]; for (i=0; i0 && animateCount) { String stepInfo = ""+stepNumber+"/"+numsteps; g.drawString(stepInfo,4,12); } } for (i=0; i=1.0) wheels[i].pos -= 1.0; } } } //Calculate new point stepWheelsCalc(g,false); if (doDraw) stepNumber++; if (dashPattern!=null && dashPattern.length>0) { if (dashOffset++>=dashPattern[dashIndex]) { drawState = !drawState; dashOffset = 1; if (++dashIndex>=dashPattern.length) dashIndex = 0; } } //draw line if (doDraw && drawState) g.drawLine(lastx,fix_y(lasty),x,fix_y(y)); if (animate) { //if (animationDelay==0) //animationDelay = 1; //draw new animation stepWheelsCalc(g,true); try { //If we don't put in any delay, the process uses 100% of the cpu time, //and will draw too fast to see on fast processors. On a 350Mhz box, //it draws 1000 steps in about 4 seconds. //But if we put in even 1ns of delay, then the sleep takes about 50ms, //so it takes about 20 seconds to draw the 1000 steps. Thread.sleep(animationDelay,1); //slow enough to see } catch (Exception e) { if (sleepErrorCount++<10) System.out.println("Sleep exception: "+e); } /* repaint is not needed when in direct mode, and makes the drawing take literally about 10 times as long. if (canvas!=null) canvas.repaint(); */ tk.sync(); } lastx = x; /* save previous point */ lasty = y; } private int fix_y(int y) { return (2*cy - y); } private int fix_y(int y, int size) { return (2*cy - y - size); } private void drawSpiroChain(Graphics g, Panel canvas, SpiroCanvas rcanvas, String chainList[], String chain) { if (chainList==null) chainList = new String[0]; String newChainList[] = new String[chainList.length+1]; int i; for (i=0; i0) p.put("dashPattern", IntVector.toCommaString(dashPattern)); p.put("steps",Integer.toString(steps)); if (chain!=null && !chain.equals("")) p.put("chain",chain); p.put("animate",(animate?"true":"false")); if (drawMode!=null && !drawMode.equals("")) p.put("drawMode",drawMode); return p; } public SpiroState(Properties p) { /* create a SpiroState from a property list */ String s; int i = 0; numwheels = 0; while (true) { s = p.getProperty("wheel"+(i+1)+"Radius"); if (s==null) break; numwheels++; WheelState newwheels[] = new WheelState[numwheels]; for (int j=0; j