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.