// Copyleft 2002 Andy Deck
Java Documentation import java.awt.*; import java.util.*; public class curl extends Module implements Runnable{ private volatile Thread t; int clicks=0; int curls = 2; int width = 12; int halfWid; Vector series; public void init(lexicon l,String args){ series = new Vector(); super.lex = l; try{ StringTokenizer st = new StringTokenizer(args); switch(st.countTokens()){ case 1: curls = Integer.parseInt(st.nextToken()); break; case 2: curls = Integer.parseInt(st.nextToken()); width = Integer.parseInt(st.nextToken()); break; } if(curls<=0) curls=1; else if (curls>15) curls = 15; if(width<2) width=2; else if(width>150) width=150; }catch(Exception e){ curls=2; width=12; } halfWid = width/2; } public boolean handleEvent(Event event){ if((event.id==Event.MOUSE_UP&&clicks==0)||event.id==Event.MOUSE_DOWN){ if(clicks++ == curls*5) return super.handleEvent(event); if(series.size()>4) series.removeAllElements(); series.addElement(new Point(event.x,event.y)); start(); } return false; } public void stop(){ t = null; } public void start(){ t = new Thread(this,"curl"); t.start(); } public void run(){ boolean doRepaint = false; double n; double x, y; try{ Graphics imgG = clicks%5==0?lex.img.getGraphics():getGraphics(); if(imgG==null) return; setRenderMode(imgG); switch(series.size()){ case 1: Point p0 = (Point)series.elementAt(0); imgG.fillOval(p0.x-halfWid,p0.y-halfWid,width,width); break; case 2: p0 = (Point)series.elementAt(0); Point p1 = (Point)series.elementAt(1); for(int i=0;i<2;i++){ for(n=0;n<=1;n=.0025+n){ x = (1-n)*p0.x + n*p1.x; y = (1-n)*p0.y + n*p1.y; if(i==0) imgG.fillOval((int)x-halfWid,(int)y-halfWid,width,width); else imgG.drawLine( (int)x,(int)y, (int)x,(int)y); } imgG.setColor(Color.white); } break; case 3: imgG.drawImage(lex.img,0,0,Color.black,lex); p0 = (Point)series.elementAt(0); p1 = (Point)series.elementAt(1); Point p2 = (Point)series.elementAt(2); for(int i =0;i<2;i++){ for(n=0;n<=1;n=.0025+n){ x = (1-n)*(1-n)*p0.x + 2*(1-n)*n*p1.x + n*n*p2.x; y = (1-n)*(1-n)*p0.y + 2*(1-n)*n*p1.y + n*n*p2.y; if(i==0) imgG.fillOval((int)x-halfWid,(int)y-halfWid,width,width); else imgG.drawLine( (int)x,(int)y, (int)x,(int)y); } imgG.setColor(Color.white); } break; case 4: imgG.drawImage(lex.img,0,0,Color.black,lex); p0 = (Point)series.elementAt(0); p1 = (Point)series.elementAt(1); p2 = (Point)series.elementAt(2); Point p3 = (Point)series.elementAt(3); for(int i =0;i<2;i++){ for(n=0;n<=1;n=.0025+n){ x = (1-n)*(1-n)*(1-n)*p0.x + 3*(n-1)*(n-1)*n*p1.x + 3*(1-n)*n*n*p2.x + n*n*n*p3.x; y = (1-n)*(1-n)*(1-n)*p0.y + 3*(n-1)*(n-1)*n*p1.y + 3*(1-n)*n*n*p2.y + n*n*n*p3.y; if(i==0) imgG.fillOval((int)x-halfWid,(int)y-halfWid,width,width); else imgG.drawLine( (int)x,(int)y, (int)x,(int)y); } imgG.setColor(Color.white); } break; case 5: p0 = (Point)series.elementAt(0); p1 = (Point)series.elementAt(1); p2 = (Point)series.elementAt(2); p3 = (Point)series.elementAt(3); Point p4 = (Point)series.elementAt(4); // who loves the polynomial? not everyone for(int i =0;i<2;i++){ for(n=0;n<=1;n=.0025+n){ x = (1-n)*(1-n)*(1-n)*(1-n)*p0.x + 4*(1-n)*(1-n)*(1-n)*n*p1.x + 6*(1-n)*(1-n)*n*n*p2.x + 4*(1-n)*n*n*n*p3.x + n*n*n*n*p4.x; y = (1-n)*(1-n)*(1-n)*(1-n)*p0.y + 4*(1-n)*(1-n)*(1-n)*n*p1.y + 6*(1-n)*(1-n)*n*n*p2.y + 4*(1-n)*n*n*n*p3.y + n*n*n*n*p4.y; if(i==0) imgG.fillOval((int)x-halfWid,(int)y-halfWid,width,width); else imgG.drawLine( (int)x,(int)y, (int)x,(int)y); } imgG.setColor(Color.white); } doRepaint = true; break; } Point first = (Point)series.firstElement(); Point last = (Point)series.lastElement(); for(int i =1;i