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);}
}
|