Ohessa on koodit sekä javasovelluksena (listaus 1), että java-appletina (listaus 2).
Eri värien aallonpituutta voi muuttaa painamalla hiiren pohjaan kyseisen värin kohdalla ja vetämällä joko ylös (aallonpituus kasvaa) tai alas (aallonpituus pienenee).
Vastaavasti käyrän siirtäminen oikealle tai vasemmalle onnistuu painamalla nappi pohjaan ja vetämällä joko oikealle tai vasemmalle.
Aallonpituuksia ja aloituskohtaa voi muuttaa myös näppäimistöllä näppäimillä
Q, A, Z (punaisen aallonpituus),
W, S, X (vihreän aallonpituus),
E, D, C (sinisen aallonpituus),
R, F, V (punaisen aloituskohta),
T, G, B (vihreän aloituskohta),
Y, H ja N (sinisen aloituskohta).
Valmiiksi käännetty applet löytyy toiminnassa osoitteesta http://www.students.tut.fi/~maki36/java/Gradient.html
Gradient.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
public class Gradient extends JFrame implements KeyListener, MouseListener, MouseMotionListener {
// Muutama muuttuja, jotka määrittelevät aallonpituuden ja aloituskohdan
double r1 = 50;
double g1 = 50;
double b1 = 50;
double r2 = 0;
double g2 = 0;
double b2 = 0;
// Muuttujat hiiriohjausta varten
int mouseX, mouseY;
int previousX, previousY;
public Gradient() {
this.setSize(Toolkit.getDefaultToolkit().getScreenSize());
this.setUndecorated(true);
this.setVisible(true);
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
int width = this.getWidth();
int height = this.getHeight();
int red, green, blue;
for (int i = 0; i < width; i++) {
// Lasketaan väriarvot punaiselle, vihreälle ja siniselle
// Laskukaava on muotoa (int)((sin(i / x1 + x2) + 1) * 128)
// i / x1 määrittelee aallonpituuden
// + x2 siirtää sinin aloituskohtaa
// + 1 muuttaa arvojoukon joukosta [-1, 1] joukoksi [0, 2]
// * 128 muuttaa arvojoukon joukosta [0, 2] joukoksi [0, 256]
// ja lopuksi (int) pyöristää tuloksen alaspäin, jolloin lopullinen arvojoukko on [0, 256]
red = (int)((Math.sin(i / r1 + r2) + 1) * 128);
green = (int)((Math.sin(i / g1 + g2) + 1) * 128);
blue = (int)((Math.sin(i / b1 + b2) + 1) * 128);
// Arvo 256 on teoriassa mahdollinen, mutta käytännössä lähes mahdoton
// Laitetaan kuitenkin varmuuden vuoksi pieni tarkastus
if (red == 256) red = 255;
if (green == 256) green = 255;
if (blue == 256) blue = 255;
// Piirretään eri värien käyrät
g.setColor(new Color(red, 0, 0));
g.drawLine(i, 0, i, height / 8);
g.setColor(new Color(0, green, 0));
g.drawLine(i, height / 8, i, (height / 8) * 2);
g.setColor(new Color(0, 0, blue));
g.drawLine(i, (height / 8) * 2, i, (height / 8) * 3);
g.setColor(new Color(red, green, blue));
g.drawLine(i, (height / 8) * 3, i, height);
}
// Tulostetaan lopuksi päälle käytetty laskukaava
//g.setColor(Color.BLUE);
//g.drawString("sin(i / " + r1 + " + " + r2 + ")", 10, height / 16);
//g.setColor(Color.RED);
//g.drawString("sin(i / " + g1 + " + " + g2 + ")", 10, (height / 16) * 3);
//g.setColor(Color.GREEN);
//g.drawString("sin(i / " + b1 + " + " + b2 + ")", 10, (height / 16) * 5);
}
public static void main(String[] e) {
Gradient baa = new Gradient();
}
public void keyTyped(KeyEvent e) {}
// Näppäimistönkäsittely
public void keyPressed(KeyEvent e) {
// Esc lopettaa
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {System.exit(0);}
// Q, A ja Z säätää punaisen aallonpituutta
if (e.getKeyCode() == KeyEvent.VK_Q) {r1 *= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_A) {r1 /= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_Z) {r1 = Math.random() * 100;}
// W, S ja X säätää vihreän aallonpituutta
if (e.getKeyCode() == KeyEvent.VK_W) {g1 *= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_S) {g1 /= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_X) {g1 = Math.random() * 100;}
// E, D ja C säätää sinisen aallonpituutta
if (e.getKeyCode() == KeyEvent.VK_E) {b1 *= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_D) {b1 /= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_C) {b1 = Math.random() * 100;}
// R, F ja V säätää punaisen aloituskohtaa
if (e.getKeyCode() == KeyEvent.VK_R) {r2 += 1 / r1;}
if (e.getKeyCode() == KeyEvent.VK_F) {r2 -= 1 / r1;}
if (e.getKeyCode() == KeyEvent.VK_V) {r2 = Math.random() * Math.PI * 2;}
// T, G ja B säätää vihreän aloituskohtaa
if (e.getKeyCode() == KeyEvent.VK_T) {g2 += 1 / g1;}
if (e.getKeyCode() == KeyEvent.VK_G) {g2 -= 1 / g1;}
if (e.getKeyCode() == KeyEvent.VK_B) {g2 = Math.random() * Math.PI * 2;}
// Y, H ja N säätää sinisen aloituskohtaa
if (e.getKeyCode() == KeyEvent.VK_Y) {b2 += 1 / b1;}
if (e.getKeyCode() == KeyEvent.VK_H) {b2 -= 1 / b1;}
if (e.getKeyCode() == KeyEvent.VK_N) {b2 = Math.random() * Math.PI * 2;}
repaint();
}
public void keyReleased(KeyEvent e) {}
// Hiirenkäsittely
public void mouseDragged(MouseEvent e) {
// Ylös ja alas liikuttaminen säätää aallonpituutta
// Vasemmalle ja oikealle liikuttaminen taas säätää aloituskohtaa
if (mouseY < this.getHeight() / 8) {
r1 *= Math.pow(1.005, (previousY - e.getY()));
}
if (mouseY < this.getHeight() / 8) {
r2 += (previousX - e.getX()) * 1 / r1;
}
if (mouseY > this.getHeight() / 8 && mouseY < (this.getHeight() / 8) * 2) {
g1 *= Math.pow(1.005, (previousY - e.getY()));
}
if (mouseY > this.getHeight() / 8 && mouseY < (this.getHeight() / 8) * 2) {
g2 += (previousX - e.getX()) * 1 / g1;
}
if (mouseY > (this.getHeight() / 8) * 2 && mouseY < (this.getHeight() / 8) * 3) {
b1 *= Math.pow(1.005, (previousY - e.getY()));
}
if (mouseY > (this.getHeight() / 8) * 2 && mouseY < (this.getHeight() / 8) * 3) {
b2 += (previousX - e.getX()) * 1 / b1;
}
if (mouseY > (this.getHeight() / 8) * 3) {
r1 *= Math.pow(1.005, (previousY - e.getY()));
g1 *= Math.pow(1.005, (previousY - e.getY()));
b1 *= Math.pow(1.005, (previousY - e.getY()));
}
if (mouseY > (this.getHeight() / 8) * 3) {
r2 += (previousX - e.getX()) * 1 / r1;
g2 += (previousX - e.getX()) * 1 / g1;
b2 += (previousX - e.getX()) * 1 / b1;
}
previousX = e.getX();
previousY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
// Napataan koordinaatit ylös kun hiiren nappulaa painetaan
mouseX = e.getX();
mouseY = e.getY();
previousX = e.getX();
previousY = e.getY();
}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}GradientApplet.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class GradientApplet extends Applet implements KeyListener, MouseListener, MouseMotionListener {
// Muutama muuttuja, jotka määrittelevät aallonpituuden ja aloituskohdan
double r1 = 50;
double g1 = 50;
double b1 = 50;
double r2 = 0;
double g2 = 0;
double b2 = 0;
// Muuttujat hiiriohjausta varten
int mouseX, mouseY;
int previousX, previousY;
public void init() {
this.setSize(750, 500);
this.setVisible(true);
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
int width = this.getWidth();
int height = this.getHeight();
int red, green, blue;
for (int i = 0; i < width; i++) {
// Lasketaan väriarvot punaiselle, vihreälle ja siniselle
// Laskukaava on muotoa (int)((sin(i / x1 + x2) + 1) * 128)
// i / x1 määrittelee aallonpituuden
// + x2 siirtää sinin aloituskohtaa
// + 1 muuttaa arvojoukon joukosta [-1, 1] joukoksi [0, 2]
// * 128 muuttaa arvojoukon joukosta [0, 2] joukoksi [0, 256]
// ja lopuksi (int) pyöristää tuloksen alaspäin, jolloin lopullinen arvojoukko on [0, 256]
red = (int)((Math.sin(i / r1 + r2) + 1) * 128);
green = (int)((Math.sin(i / g1 + g2) + 1) * 128);
blue = (int)((Math.sin(i / b1 + b2) + 1) * 128);
// Arvo 256 on teoriassa mahdollinen, mutta käytännössä lähes mahdoton
// Laitetaan kuitenkin varmuuden vuoksi pieni tarkastus
if (red == 256) red = 255;
if (green == 256) green = 255;
if (blue == 256) blue = 255;
// Piirretään eri värien käyrät
g.setColor(new Color(red, 0, 0));
g.drawLine(i, 0, i, height / 8);
g.setColor(new Color(0, green, 0));
g.drawLine(i, height / 8, i, (height / 8) * 2);
g.setColor(new Color(0, 0, blue));
g.drawLine(i, (height / 8) * 2, i, (height / 8) * 3);
g.setColor(new Color(red, green, blue));
g.drawLine(i, (height / 8) * 3, i, height);
}
// Tulostetaan lopuksi päälle käytetty laskukaava
//g.setColor(Color.BLUE);
//g.drawString("sin(i / " + r1 + " + " + r2 + ")", 10, height / 16);
//g.setColor(Color.RED);
//g.drawString("sin(i / " + g1 + " + " + g2 + ")", 10, (height / 16) * 3);
//g.setColor(Color.GREEN);
//g.drawString("sin(i / " + b1 + " + " + b2 + ")", 10, (height / 16) * 5);
}
public void keyTyped(KeyEvent e) {}
// Näppäimistönkäsittely
public void keyPressed(KeyEvent e) {
// Esc lopettaa
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {System.exit(0);}
// Q, A ja Z säätää punaisen aallonpituutta
if (e.getKeyCode() == KeyEvent.VK_Q) {r1 *= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_A) {r1 /= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_Z) {r1 = Math.random() * 100;}
// W, S ja X säätää vihreän aallonpituutta
if (e.getKeyCode() == KeyEvent.VK_W) {g1 *= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_S) {g1 /= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_X) {g1 = Math.random() * 100;}
// E, D ja C säätää sinisen aallonpituutta
if (e.getKeyCode() == KeyEvent.VK_E) {b1 *= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_D) {b1 /= 1.005;}
if (e.getKeyCode() == KeyEvent.VK_C) {b1 = Math.random() * 100;}
// R, F ja V säätää punaisen aloituskohtaa
if (e.getKeyCode() == KeyEvent.VK_R) {r2 += 1 / r1;}
if (e.getKeyCode() == KeyEvent.VK_F) {r2 -= 1 / r1;}
if (e.getKeyCode() == KeyEvent.VK_V) {r2 = Math.random() * Math.PI * 2;}
// T, G ja B säätää vihreän aloituskohtaa
if (e.getKeyCode() == KeyEvent.VK_T) {g2 += 1 / g1;}
if (e.getKeyCode() == KeyEvent.VK_G) {g2 -= 1 / g1;}
if (e.getKeyCode() == KeyEvent.VK_B) {g2 = Math.random() * Math.PI * 2;}
// Y, H ja N säätää sinisen aloituskohtaa
if (e.getKeyCode() == KeyEvent.VK_Y) {b2 += 1 / b1;}
if (e.getKeyCode() == KeyEvent.VK_H) {b2 -= 1 / b1;}
if (e.getKeyCode() == KeyEvent.VK_N) {b2 = Math.random() * Math.PI * 2;}
repaint();
}
public void keyReleased(KeyEvent e) {}
// Hiirenkäsittely
public void mouseDragged(MouseEvent e) {
// Ylös ja alas liikuttaminen säätää aallonpituutta
// Vasemmalle ja oikealle liikuttaminen taas säätää aloituskohtaa
if (mouseY < this.getHeight() / 8) {
r1 *= Math.pow(1.005, (previousY - e.getY()));
}
if (mouseY < this.getHeight() / 8) {
r2 += (previousX - e.getX()) * 1 / r1;
}
if (mouseY > this.getHeight() / 8 && mouseY < (this.getHeight() / 8) * 2) {
g1 *= Math.pow(1.005, (previousY - e.getY()));
}
if (mouseY > this.getHeight() / 8 && mouseY < (this.getHeight() / 8) * 2) {
g2 += (previousX - e.getX()) * 1 / g1;
}
if (mouseY > (this.getHeight() / 8) * 2 && mouseY < (this.getHeight() / 8) * 3) {
b1 *= Math.pow(1.005, (previousY - e.getY()));
}
if (mouseY > (this.getHeight() / 8) * 2 && mouseY < (this.getHeight() / 8) * 3) {
b2 += (previousX - e.getX()) * 1 / b1;
}
if (mouseY > (this.getHeight() / 8) * 3) {
r1 *= Math.pow(1.005, (previousY - e.getY()));
g1 *= Math.pow(1.005, (previousY - e.getY()));
b1 *= Math.pow(1.005, (previousY - e.getY()));
}
if (mouseY > (this.getHeight() / 8) * 3) {
r2 += (previousX - e.getX()) * 1 / r1;
g2 += (previousX - e.getX()) * 1 / g1;
b2 += (previousX - e.getX()) * 1 / b1;
}
previousX = e.getX();
previousY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
// Napataan koordinaatit ylös kun hiiren nappulaa painetaan
mouseX = e.getX();
mouseY = e.getY();
previousX = e.getX();
previousY = e.getY();
}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}Hieno :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.