[Prev][Up][Top] VW - CVM 1.1 [Bib][Respond][Find][Help]


Code for the Wallpaper Applet

Written by Frank Farris

If you want to use this code, just remove the html tags at the beginning and end of the file. This is displayed as pre-formatted text, so the edges may be cut off if your browser window isn't big enough.

import java.applet.Applet;
import java.awt.*;
import java.lang.*;

public class WallpaperMaker extends Applet  {

   Wallpaper wall;
   WallpaperControls controls;
   CardLayout card;
   public void init() {
       resize(500,500);	  
       setLayout(new BorderLayout());
       wall = new Wallpaper();
       controls = new WallpaperControls(wall);
       add("Center",wall);
       add("South", controls);
 	

        }
public void start(){
	
	controls.enable();
	}
public void stop(){ controls.disable();}


// this event handler only handles cataclysmic events
 public boolean handleEvent(Event evt)
    {  if (evt.id==Event.WINDOW_DESTROY){ System.exit(0);}
       return false;}



public String getAppletInfo() {
      return "Wallpaper by Farris";
   }

   }// end of applet
class Term {
  // has two integer frequencies
   public int n;
   public int m;
   // with a real coefficient out front
   public double coeff;
   // a default constructor to make a null term
   public Term(){n=0;m=0;coeff=0.0;}
   public Term(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // and it knows how to return a value
   public double value(double x, double y){
     // this is a vacuous function that returns 0
     return 0.0;};
   public String formula(){String tempString= " ";
             tempString=tempString+" ";
	     return tempString;};
}// end of Term class -- this has descendants below
class ssTerm extends Term {
  // has two integer frequencies
   public int n;
   public int m;
   // with a real coefficient out front
   public double coeff;
   // a default constructor to make a null term
   public ssTerm(){n=0;m=0;coeff=0.0;}
   public ssTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // and it knows how to return a value
   public double value(double x, double y){
     // this is a sine-sine term
     return coeff*Math.sin(n*x)*Math.sin(m*y);};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"sin("+n+"X)"+"sin("+m+"Y)";
	     return tempString;};
}// end of Term class -- later this will have descendants
class ccTerm extends Term {
  // I guess it needs its own constructors

   public  ccTerm(){n=0;m=0;coeff=0.0;}
   public ccTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  //this is a cosine-cosine term
   public double value(double x, double y){

     return coeff*Math.cos(n*x)*Math.cos(m*y);};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"cos("+n+"X)"+"cos("+m+"Y)";
	     return tempString;};
}// end of cc-Term class
class csTerm extends Term {

   public  csTerm(){n=0;m=0;coeff=0.0;}
   public csTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // the only new thing is that this overrides previous value fcn
   public double value(double x, double y){

     return coeff*Math.cos(n*x)*Math.sin(m*y);};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"cos("+n+"X)"+"sin("+m+"Y)";
	     return tempString;};
}// end of cs-Term class

class scTerm extends Term {
 
   public  scTerm(){n=0;m=0;coeff=0.0;}
   public scTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // the only new thing is that this overrides previous value fcn
   public double value(double x, double y){
     // this is just an example for a rectangular cell
     return coeff*Math.sin(n*x)*Math.cos(m*y);};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"sin("+n+"X)"+"cos("+m+"Y)";
	     return tempString;};
}// end of sc-Term class

class shexTerm extends Term {


   public  shexTerm(){n=0;m=0;coeff=0.0;}
   public shexTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // the only new thing is that this overrides previous value fcn
   public double value(double x, double y){
     // this is just an example for a rectangular cell
     return coeff*(Math.sin(n*x+m*y)+Math.sin(m*x-(n+m)*y)
     	+Math.sin(-(n+m)*x+n*y));

     };
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"S("+n+", "+m+")";
	     return tempString;};
}// end of shexTerm class
class chexTerm extends Term {
 

   public  chexTerm(){n=0;m=0;coeff=0.0;}
   public chexTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // the only new thing is that this overrides previous value fcn
   public double value(double x, double y){
     // this is just an example for a rectangular cell
     return coeff*(Math.cos(n*x+m*y)+Math.cos(m*x-(n+m)*y)
     	+Math.cos(-(n+m)*x+n*y));};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"C("+n+", "+m+")";
	     return tempString;};
}// end of chexTerm class

class csqTerm extends Term {


   public  csqTerm(){n=0;m=0;coeff=0.0;}
   public csqTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // the only new thing is that this overrides previous value fcn
   public double value(double x, double y){
     // this is just an example for a rectangular cell
     return coeff*(Math.cos(n*x)*Math.cos(m*y)+Math.cos(m*x)*Math.cos(n*y));};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"C("+n+", "+m+")";
	     return tempString;};
}// end of csqTerm class

class csqnegTerm extends Term {


   public csqnegTerm(){n=0;m=0;coeff=0.0;}
   public csqnegTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // the only new thing is that this overrides previous value fcn
   public double value(double x, double y){
     // this is just an example for a rectangular cell
     return coeff*(Math.cos(n*x)*Math.cos(m*y)-Math.cos(m*x)*Math.cos(n*y));};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"C-("+n+","+m+")";
	     return tempString;};
}// end of csqnegTerm class

class ssqTerm extends Term {


   public  ssqTerm(){n=0;m=0;coeff=0.0;}
   public ssqTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // the only new thing is that this overrides previous value fcn
   public double value(double x, double y){
     // this is just an example for a rectangular cell
     return coeff*(Math.sin(n*x)*Math.sin(m*y)-Math.sin(m*x)*Math.sin(n*y));};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"S("+n+", "+m+")";
	     return tempString;};
}// end of ssqTerm class

class ssqnegTerm extends Term {


   public  ssqnegTerm(){n=0;m=0;coeff=0.0;}
   public ssqnegTerm(double coeff, int n, int m){
      this.coeff=coeff; this.n=n ; this.m=m;
     };
  // the only new thing is that this overrides previous value fcn
   public double value(double x, double y){
     // this is just an example for a rectangular cell
     return coeff*(Math.sin(n*x)*Math.sin(m*y)+Math.sin(m*x)*Math.sin(n*y));};
   public String formula(){String tempString= " ";
             tempString=tempString+coeff+"S-("+n+", "+m+")";
	     return tempString;};
}// end of ssqnegTerm class

  ////////////////////////////////////////////
  ///////////////////////////////////////////
class WallpaperFunction {
   public static final double pi=Math.PI;
  // should be an array of Terms with initializer and fcn to return value

    public int numTerms= 0;
    public Term[] terms;
  // makes a default wallpaper with twenty terms
   public WallpaperFunction(){terms = new Term[20];
   for(int k=0;k  < 20;k++){terms[k]=new Term();}
       };
 // computes output value of function from world coords
 public double functionValue(double x, double y){
   double xLattice, yLattice;
   double sumValue=0;
   xLattice=x;
   yLattice=1.414*y;
  for (int j=0; j < numTerms; j++){
    sumValue=sumValue+terms[j].value(xLattice,yLattice);}
    return sumValue;
  }
 // computes string for formula
 public String formula(){
   String temp="";
   for (int p=0;p < numTerms;p++){temp=temp+terms[p].formula()+" + ";}
   return temp+"         ";};
 // enables us to add a term of any type -- fcn has unused flexibility
 // in addWhere variable
  public void addTerm(Term tempTerm, int addWhere){

        terms[addWhere]=tempTerm;
        numTerms=numTerms+1;}
	
 // deletes last term
 public void deleteTerm(int termNum){
         numTerms=numTerms-1;
         Term nullTerm = new Term(0.0,0,0);
	 terms[termNum]=nullTerm;}
 public double wallMax(){
      double tempMax=0;
      double x,y;
   for (int i=0; i < 100;i++){
     for(int k=0;k < 100;k++){
      x = i*pi/50.0;y=k*pi/50.0;
      double  tempHeight=0;
       for (int j=0; j < numTerms+1;j++){
        tempHeight=tempHeight+terms[j].value(x,y);
        };
        tempHeight=Math.abs(tempHeight);
        if(tempHeight > tempMax){tempMax=tempHeight;};};}
    return tempMax;}

}

/////////////////////////////////////////////

// a hexWallpaperFunction will only overwrite value function
class hexWallpaperFunction extends WallpaperFunction{
  public static final double qr = Math.sqrt(3);
   public hexWallpaperFunction(){terms = new Term[20];
   for(int k=0;k <20;k++){terms[k]=new Term();}
        };
 // computes output value of function from world coords
 public double functionValue(double x, double y){
   double xLattice, yLattice;
   double sumValue=0;
   xLattice=x+y/qr;
   yLattice=2*y/qr;
  for (int j=0; j < numTerms;j++){
    sumValue=sumValue+terms[j].value(xLattice,yLattice);}
   return sumValue;
   }
 } // end of hexWallpaperFunction class

 // a sqWallpaperFunction will make wallpaper in square cells
 class sqWallpaperFunction extends WallpaperFunction{
    public sqWallpaperFunction(){terms = new Term[20];
    for(int k=0;k < 20;k++){terms[k]=new Term();}
        };
   // computes output value of function from world coords
   public double functionValue(double x, double y){

   double sumValue=0;

    for (int j=0; j < numTerms;j++){
      sumValue=sumValue+terms[j].value(x,y);}
    return sumValue;
   }
 } // end of sqWallpaperFunction class
   ///////////////////////////////////////////
   ///////////////////////////////////////////


 // here is the wallpaper class -- the thing that owns a function and
 // knows how to paint it

 class Wallpaper  extends Panel{
    //  this is the thing that displays the wallpaper function it owns.
 // size of view window:
     public int ViewX = 150;
     public int ViewY = 150;
    // the image for off-screen drawing
   Image  image, newimage;
   Graphics offg;

     public WallpaperFunction f;
   // makes the default wallpaper empty
   // user must add terms
   public Wallpaper(){
                       f=new WallpaperFunction();
	      };
   public boolean willRecompute = true;

   public void paint(Graphics g) {
      g.setColor(Color.black);
      g.drawString(f.formula(),0,ViewY+120);
  // somehow it matters to call createImage from within paint
  // doing this when image was declared resulted in NullPointerException
      newimage =createImage(ViewX+100, ViewY+100);
      offg= newimage.getGraphics();

    //This recomputes the image and paints it in an offscreen place
       if (willRecompute==true){
   // first paint a big white rectangle
       offg.setColor(Color.white);
       offg.fillRect(0,0,ViewX+100,ViewY+100);
    int altitude;
    double x, y;
    double wallMax=f.wallMax();
       if (wallMax==0){wallMax=1;};
    for (int j=50; j < (ViewY+50); j++) {
       y=12.0*j/(double)ViewY;
       for (int i=50; i < (ViewX+50); i++) {
            x=12.0*i/(double)ViewX;
            altitude=(byte)(255.0*f.functionValue(x,y)/wallMax)+128;
	
	
	 Color color=new Color(altitude ,altitude%128  ,255-altitude);
         offg.setColor(color);
         offg.fillRect(i,j,1,1);

         }
    } ;
    // this replaces existing image with newly computed one
     image = newimage;
     willRecompute=false;
 }
       // question:  "this" below implements interface ImageObserver.  What
       // does it do?
       g.drawImage(image,0,0,Color.white,this);

 // end of paint method

 }} // end of wallpaperView class
 /////////////////////////////////////////////////////////
 // Wallpaper Controls class

class WallpaperControls extends Panel {
 public TextField coeffVal,nVal,mVal;
 public Wallpaper w;
 public Panel buttoncards;
 public Panel pCoeff;
 public Panel selector;
 public CardLayout card;
 public WallpaperControls(Wallpaper w) {
  	
      this.w=w;
      setLayout(new BorderLayout());
      selector = new Panel();
      selector.setLayout(new GridLayout(3,1));
      selector.add(new Button("hex"));
      selector.add(new Button("rect"));
      selector.add(new Button("square"));
      add("West",selector);
      buttoncards = new Panel();
      card = new CardLayout();
      buttoncards.setLayout(card);
      buttoncards.add("hex",new HexButton());
      buttoncards.add("square", new SquareButton());
      buttoncards.add("rect", new RectButton());
      card.show(buttoncards, "rect");
      add("Center",buttoncards);
  //   this panel is where we enter new data - give default values
      Panel pCoeff = new Panel();
      pCoeff.setLayout(new GridLayout(3,2));
      pCoeff.add( new Label("coeff"));
      pCoeff.add(coeffVal = new TextField("1",6));
      pCoeff.add(new Label("x freq"));
      pCoeff.add(nVal=new TextField("0",4));
      pCoeff.add(new Label("y freq"));
      pCoeff.add(mVal = new TextField("0",4));
      add("East",pCoeff);
 }

 // event handler for WallpaperControl
 public boolean action(Event ev, Object arg){
      if (ev.target instanceof Button) 
      //whichever button is pressed, we read the textfields
         int n_ = Integer.parseInt(nVal.getText().trim());
	 int m_ =Integer.parseInt(mVal.getText().trim());
         double newCoeff =
                Float.valueOf(coeffVal.getText()).floatValue();
      // read buttons from HexButton
      if ("add S(n,m) hex term".equals(arg))
      { shexTerm temp= new shexTerm(newCoeff, n_,m_);
        w.f.addTerm(temp,w.f.numTerms);
        w.repaint(0,w.ViewY+100,600,w.ViewY+120);	
          };
    if ("add C(n,m) hex term".equals(arg))
      {chexTerm temp= new chexTerm(newCoeff, n_,m_);
           w.f.addTerm(temp,w.f.numTerms);
           w.repaint(0,w.ViewY+100,600,w.ViewY+120);	
          };
     // read buttons from RectButton
      if ("add cos-cos term".equals(arg))
      { ccTerm temp= new ccTerm(newCoeff, n_,m_);
        w.f.addTerm(temp,w.f.numTerms);
        w.repaint(0,w.ViewY+100,600,w.ViewY+120);	
        };
     if ("add sin-cos term".equals(arg))
      { scTerm temp= new scTerm(newCoeff, n_,m_);
        w.f.addTerm(temp,w.f.numTerms);
        w.repaint(0,w.ViewY+100,600,w.ViewY+120);	
         };
    if ("add cos-sin term".equals(arg))
      {   csTerm temp= new csTerm(newCoeff, n_,m_);
          w.f.addTerm(temp,w.f.numTerms);
          w.repaint(0,w.ViewY+100,600,w.ViewY+120);
	 };
    if ("add sin-sin term".equals(arg))
      {ssTerm temp= new ssTerm(newCoeff, n_,m_);
       w.f.addTerm(temp,w.f.numTerms);
       w.repaint(0,w.ViewY+100,600,w.ViewY+120);	
       };
   // read buttons on SquareButton
    if ("add C(n,m) term".equals(arg))
      { csqTerm temp= new csqTerm(newCoeff, n_,m_);
        w.f.addTerm(temp,w.f.numTerms);
        w.repaint(0,w.ViewY+100,600,w.ViewY+120);	
        };
     if ("add S(n,m) term".equals(arg))
      { ssqTerm temp= new ssqTerm(newCoeff, n_,m_);
        w.f.addTerm(temp,w.f.numTerms);
        w.repaint(0,w.ViewY+100,600,w.ViewY+120);	
         };
    if ("add C-(n,m) term".equals(arg))
      {   csqnegTerm temp= new csqnegTerm(newCoeff, n_,m_);
          w.f.addTerm(temp,w.f.numTerms);
          w.repaint(0,w.ViewY+100,600,w.ViewY+120);
	 };
     if ("add S-(n,m) term".equals(arg))
      {ssqnegTerm temp= new ssqnegTerm(newCoeff, n_,m_);
       w.f.addTerm(temp,w.f.numTerms);
       w.repaint(0,w.ViewY+100,600,w.ViewY+120);	
       };
   // read buttons common to all
     if ("delete last term".equals(arg))
      {    w.f.deleteTerm(w.f.numTerms);
           w.repaint(0,w.ViewY+100,600,w.ViewY+120);
   	};
      if ("redraw".equals(arg))
      {  w.willRecompute=true;
         w.repaint(0,0,w.ViewX+100,w.ViewY+120);
       };
      if ("hex".equals(arg))
       { w.f = new hexWallpaperFunction();
         w.willRecompute=true;
         card.show(buttoncards,"hex");
         w.repaint();
         repaint();
         };
       if ("rect".equals(arg))
       { w.f = new WallpaperFunction();
         w.willRecompute=true;
         card.show(buttoncards, "rect");
         w.repaint();
         repaint();
         };
          if ("square".equals(arg))
       { w.f = new sqWallpaperFunction();
         w.willRecompute=true;
         card.show(buttoncards, "square");
         w.repaint();
         repaint();
         };
       return true;} else
       {return false;};
 }// end action
         } // end WallpaperControls class

 // ButtonPanel is made to be extended in three ways
 class ButtonPanel extends Panel{
	
     public ButtonPanel(){};
     }// that's all
	
	
 class HexButton extends ButtonPanel{
      public HexButton(){
      setLayout(new GridLayout(2,2));
     // put four  buttons in the panel     -- mirrors?
      add(new Button("add C(n,m) hex term"));
      add(new Button("add S(n,m) hex term"));
      add(new Button("delete last term"));
      add(new Button("redraw"));
	};

  }; //end class

 class RectButton extends ButtonPanel{
	 public RectButton(){
	 setLayout(new GridLayout(3,2));
	 add(new Button("add cos-cos term"));
     add(new Button("add cos-sin term"));
     add(new Button("add sin-cos term"));
     add(new Button("add sin-sin term"));
     add(new Button("delete last term"));
     add(new Button("redraw"));
       }
 	} // end of RectButton class
	
 class SquareButton extends ButtonPanel{
	 public SquareButton(){
	 setLayout(new GridLayout(3,2));
	 add(new Button("add C(n,m) term"));
     add( new Button("add S(n,m) term"));
     add(new Button("add C-(n,m) term"));
     add(new Button("add S-(n,m) term"));
     add(new Button("delete last term"));
     add(new Button("redraw"));
     }
	 } // end of SquareButton class
		

[Up] Directions for Future Work
[Prev] Some Programming Challenges
[Bib][Respond]
[Find][Help] 

Communications in Visual Mathematics, vol 1, no 1, August 1998.
Copyright © 1998, The Mathematical Association of America. All rights reserved.
Created: 01 Jul 1998 --- Last modified: 18 Aug 1998 23:59:59
Comments to: CVM@maa.org