PrecedenteAltri AppletSuccessivo



Disegno di una f(x,y) con un codice di colori

Questo esempio visualizza una funzione reale di due variabili reali z=f(x,y) utilizzando un codice cromatico per i valori della funzione.

Provate a immaginare la forma della funzione prima di leggere il codice Java.

Questo browser non e' abilitato
a visualizzare applet

Istruzioni:

Facendo click con il mouse in diversi punti del quadrato si modificano i valori di due parametri e la funzione viene ricalcolata e ridisegnata
L'applet è di piccole dimensioni e il ricalcolo dovrebbe essere ragionevolmente veloce su quasi tutte le piattaforme. Un click&drag permette di generare in maniera continua una grande varietà di configurazioni.


Codice sorgente: colorplot.java

import java.applet.*;
import java.awt.*;
import java.awt.image.*;

// converte 'value' in un colore dal nero al blu
class ColourScheme {
  static Color Colour(float value) {
    if(value <= 0.0)         return Color.black;
    else if (value <= 1.0)   return new Color(0.0f,0.0f,value);
    else                     return Color.blue;
  }
}

public class colorplot extends Applet implements Runnable  {
  int width, height;
  double xcorner, ycorner, delta;
  boolean needsRecalc;
  double p1=10,p2=10;

  public void init() {
    width = size().width;	
    height = size().height;	
    xcorner = -1.0;
    ycorner = -1.0;
    delta = 2.0 / width;
    needsRecalc = true;
  }

  Thread kick;

  public void start() {
    kick = new Thread(this);
    kick.setPriority(Thread.MAX_PRIORITY);
    kick.start();
  }

  public void stop() {
    kick = null;
  }

  public void run() {
    Graphics g = getGraphics();
    g.setColor(Color.white);
    g.fillRect(0, 0, width, height);
    doIt();
  }

  Image img, prevImg;

  synchronized void doIt() {
    Graphics g = getGraphics();
    GraphProducer producer;
    try {
      while(true) {
	producer = new GraphProducer (width, height,
				  xcorner, ycorner, delta,
				  p1,p2);
	while(needsRecalc) {
	  Thread producerThread = new Thread(producer);
	  producerThread.setPriority(Thread.MIN_PRIORITY);
	  producerThread.start();
	  if(producer.blockUntilFinished()) { // wait for successful calc
	    needsRecalc = false;
	    prevImg = img;
	    img = createImage(producer);
	    g.drawImage(img,0,0,this);
	  } 
	}
	wait(); 
      } 
    } catch (InterruptedException e) {;}
  } 

  public void paint(Graphics g) {
    if(img != null) { 
      g.drawImage(img, 0, 0, this);
    } else {
      g.setColor(Color.white);
      g.fillRect(0, 0, width, height);
    }
  }


  public synchronized boolean mouseDown(Event e, int x, int y) {
    if (img != null && !needsRecalc) {
      p1 = 20.0*(double)x/size().width;
      p2 = 20.0*(double)y/size().height;
      needsRecalc = true;
      notify();
    }
    return true;
  }
  public synchronized boolean mouseDrag(Event e, int x, int y) {
    if (img != null && !needsRecalc) {
      p1 = 20.0*(double)x/size().width;
      p2 = 20.0*(double)y/size().height;
      needsRecalc = true;
      notify();
    }
    return true;
  }


}

class GraphProducer implements ImageProducer, Runnable {
  int width, height;
  double xcorner, ycorner, delta;
  double p1=10.0,p2=10.0;
  MemoryImageSource mims;
  boolean finished;

  GraphProducer (int width, int height, double xcorner, double ycorner,
			double delta, double p1, double p2) {
    this.width = width;
    this.height = height;
    this.xcorner = xcorner;
    this.ycorner = ycorner;
    this.delta = delta;
    this.p1 = p1;
    this.p2 = p2;

    finished = false;
  }

  public synchronized boolean blockUntilFinished() {
    try {
      while(!finished) {
        wait();
      }
      return true;
    } catch (InterruptedException e) {
      return false;
    }
  }

  // calcola l'immagine utilizzando la funzione getValue(x,y)
  public synchronized void run() {
    int i,j;
    double x,y;

    int pix[] = new int[height*width];
    for(j=0; j < height; j++) {
      y = ycorner + j*delta;
      for(i=0; i < width; i++) {
        x = xcorner + i*delta;
        pix[j*width + i] = ColourScheme.Colour(getValue(x,y)).getRGB();
      }
    }
    mims = new MemoryImageSource(width, height, pix, 0, width);
    finished = true;
    notify();	// notify all threads waiting on this object
  }

  // Questa e' la funzione che viene mostrata nel grafico. 
  // Il suo valore deve essere compreso fra 0 e 1
  // (oppure bisogna cambiare ColourScheme.Colour())

  float getValue(double x, double y) {
    return (float)(0.5*(Math.sin((int)(p1)*Math.atan2(y,x)+p2*(x*x+y*y))+1.0));
  }

  public void addConsumer(ImageConsumer consumer)   
 		{mims.addConsumer(consumer);}
  public void removeConsumer(ImageConsumer consumer) 
		{mims.removeConsumer(consumer);}
  public boolean isConsumer(ImageConsumer consumer)  
		{return mims.isConsumer(consumer);}
  public void startProduction(ImageConsumer consumer)
		{mims.startProduction(consumer);}
  public void requestTopDownLeftRightResend(ImageConsumer consumer) 
		{mims.requestTopDownLeftRightResend(consumer);}
}
  





PrecedenteAltri AppletSuccessivo


Gian Marco Todesco