Colors! |
For many purposes, however, the HSV representation is more suitable. It represents a color using three components:
Our first program will display a window like this:
We first need to learn how to display a window. You need to have the CS109UI module installed, see the installation instructions.
Download the example program uitest1.kt. You can run the example from the command line by saying:
$ ktc uitest1.kt $ kt Uitest1Kt
Read the section "Basic Usage" of the cs109ui documentation.
Our program rainbow.kt will take one command line parameter, the value v (if the command line parameter is omitted, use v = 255). It should then create a BufferedImage of width 360 and height 256, and fill pixel \((x,y)\) of this image with the color with hue \(x\), saturation \(y\), and value v. To set the pixel, use the setRGB method of BufferedImage.
Here is a function that converts from HSV representation to RGB representation:
// Input h in [0,359], s in [0,255], v in [0,255] // Output r,g,b in [0,255] fun hsvtorgb(h: Int, s: Int, v: Int): Triple<Int, Int, Int> { if (s == 0) { // no color, just grey return Triple(v, v, v) } else { val sector = h / 60 val f = (h % 60) val p = v * ( 255 - s ) / 255 val q = v * ( 15300 - s * f ) / 15300 val t = v * ( 15300 - s * ( 60 - f )) / 15300 return when(sector) { 0 -> Triple(v, t, p) 1 -> Triple(q, v, p) 2 -> Triple(p, v, t) 3 -> Triple(p, q, v) 4 -> Triple(t, p, v) else -> Triple(v, p, q) } } }
Compile and run your program like this:
$ ktc rainbow.kt $ kt RainbowKt 180
Here is the output for a few different v-values:
Now read the section "Updating the display" of the cs109ui documentation, and change the program as follows: It no longer takes a command line parameter. Instead the v-value starts with v = 255, but then it continuously changes until it reaches v = 0. The program should terminate automatically after that.
Change the v-value by one every time you call show, and wait for 100 milliseconds. You should also change the title of the window so that it always shows the current v-value.
Let's now write a program that can test your color vision. It displays a window like this:
$ ktc colorguess.kt $ kt ColorguessKt Which square has a different color? (x to exit) 3a That is correct You answered 1 of 1 tests correctly. Which square has a different color? (x to exit) 1b That is correct You answered 2 of 2 tests correctly. Which square has a different color? (x to exit) 3a That is correct You answered 3 of 3 tests correctly. Which square has a different color? (x to exit) 2b That is correct You answered 4 of 4 tests correctly. Which square has a different color? (x to exit) 1d That is correct You answered 5 of 5 tests correctly. Which square has a different color? (x to exit) 3b That is not correct. Square 4c has a different color. Press Enter for the next question> You answered 5 of 6 tests correctly. Which square has a different color? (x to exit) 2d That is not correct. Square 2c has a different color. Press Enter for the next question> You answered 5 of 7 tests correctly. Which square has a different color? (x to exit) 1c That is correct You answered 6 of 8 tests correctly. Which square has a different color? (x to exit) x
Note that when the answer is correct, the program immediately displays the next test. When the answer is not correct, however, we need to give the user the chance to look at the colors again after revealing the correct answer—that's why the program says "Press Enter for the next question".
Your program should have one command line parameter, an integer that we will call delta. It indicates the distance between the different color and the standard color. If no command line argument is given, use the value delta = 20.
The following function generates a random color in HSV space:
fun randomHSV(): Triple<Int, Int, Int> { return Triple(random.nextInt(360), 128 + random.nextInt(128), 128 + random.nextInt(128)) }
(Note that I'm excluding colors that are too dark or too grayish.)
The special color differs only in its hue from the standard color (saturation and value are the same). Flip a coin (for instance, using random.nextInt(2)). With probability \(1/2\), add delta to the hue, otherwise add 360 - delta to the hue (don't forget to do this operation modulo 360).
Keep showing colors to the user until the user types "x".
Here is an example for delta = 5. Can you distinguish the different color?
Change your program so that instead of using the keyboard, the user should select the different color by clicking on the square.
Read the section "Mouse input" of the cs109ui documentation.
Your program should not use the terminal at all, all input and output should be through the graphical user interface.
Colors! |