hue + saturation wheel
forked from Polish Hand Magic (diff: 195)
Explanation: http://www.smbc-comics.com/index.php?db=comics&id=1914#comic
ActionScript3 source code
/**
* Copyright shaktool ( http://wonderfl.net/user/shaktool )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/wSGM
*/
package {
import flash.display.*;
import flash.events.*;
import flash.media.*;
[SWF(width='465', height='465', backgroundColor='#777777', frameRate='15')]
public class Main extends Sprite {
private const WIDTH: Number = 465;
private const HEIGHT: Number = 465;
private const gamma: Number = 2.2;
private const invGamma: Number = 1.0 / 2.2;
private const RLum: Number = 0.2126;
private const GLum: Number = 0.7152;
private const BLum: Number = 0.0722;
private var targetBrightness: Number = 0.5;
private var dragging: Boolean = false;
private var template: Vector.<Number> = new Vector.<Number>();
private var data: BitmapData = new BitmapData(WIDTH, HEIGHT, false, 0x000000);
public function Main() {
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
addChild(new Bitmap(data));
bake();
render();
}
private function mouseDown(event: MouseEvent): void {
dragging = true;
targetBrightness = 1.0 - mouseY / HEIGHT;
targetBrightness *= targetBrightness;
render();
}
private function mouseUp(event: MouseEvent): void {
dragging = false;
}
private function mouseMove(event: MouseEvent): void {
if (!dragging) return;
}
private function bake(): void {
template.length = WIDTH * HEIGHT * 3;
template.fixed = true;
var midX: Number = WIDTH / 2.0;
var midY: Number = HEIGHT / 2.0;
var cosg: Number = Math.cos(Math.PI * 2.0 / 3.0);
var sing: Number = Math.sin(Math.PI * 2.0 / 3.0);
var cosb: Number = Math.cos(-Math.PI * 2.0 / 3.0);
var sinb: Number = Math.sin(-Math.PI * 2.0 / 3.0);
for (var j: int = 0; j < HEIGHT; j++) {
for (var i: int = 0; i < WIDTH; i++) {
var diffX: Number = (i - midX) / WIDTH;
var diffY: Number = (j - midY) / HEIGHT;
if (diffX * diffX + diffY * diffY > 0.25) continue;
var red: Number = diffY + 0.5;
var green: Number = diffY * cosg - diffX * sing + 0.5;
var blue: Number = diffY * cosb - diffX * sinb + 0.5;
var minimum: Number = Math.min(Math.min(red, green), blue);
var maximum: Number = Math.max(Math.max(red, green), blue);
var black: Number = Math.max(0.0, 1.0 - maximum - minimum );
var white: Number = Math.max(0.0, minimum - 1.0 + maximum);
var scale: Number = 1.0 / (1.0 - white - black);
red = (red - white) * scale;
green = (green - white) * scale;
blue = (blue - white) * scale;
template[(i + j * WIDTH) * 3 + 0] = red;
template[(i + j * WIDTH) * 3 + 1] = green;
template[(i + j * WIDTH) * 3 + 2] = blue;
}
}
}
private function render(): void {
var mathSqrt: Function = Math.sqrt;
for (var j: int = 0; j < HEIGHT; j++) {
for (var i: int = 0; i < WIDTH; i++) {
var index: int = (i + j * WIDTH) * 3;
var red: Number = template[index];
var green: Number = template[index + 1];
var blue: Number = template[index + 2];
/*
var sum: Number = red * RLum + green * GLum + blue * BLum;
var scale: Number = targetBrightness / sum;
red *= scale;
green *= scale;
blue *= scale;
var overflow: Number = 0;
var underflow: Number = 0;
if (red > 1.0) { overflow += (red - 1.0) * RLum; red = 1.0; } else { (underflow += 1.0 - red ) * RLum; }
if (green > 1.0) { overflow += (green - 1.0) * GLum; green = 1.0; } else { (underflow += 1.0 - green) * GLum; }
if (blue > 1.0) { overflow += (blue - 1.0) * BLum; blue = 1.0; } else { (underflow += 1.0 - blue ) * BLum; }
scale = (underflow - overflow) / underflow;
red = (red - 1.0) * scale + 1.0;
green = (green - 1.0) * scale + 1.0;
blue = (blue - 1.0) * scale + 1.0;
*/
/*
red *= 2.0 * targetBrightness;
green *= 2.0 * targetBrightness;
blue *= 2.0 * targetBrightness;
*/
//red = Math.pow(red, invGamma);
//green = Math.pow(green, invGamma);
//blue = Math.pow(blue, invGamma);
red = mathSqrt(red);
green = mathSqrt(green);
blue = mathSqrt(blue);
var red2: int = red > 1.0 ? 255.0 : red * 255.0;
var green2: int = green > 1.0 ? 255.0 : green * 255.0;
var blue2: int = blue > 1.0 ? 255.0 : blue * 255.0;;
data.setPixel(i,j,(red2 << 16) + (green2 << 8) + (blue2));
}
}
}
}
}
