hue + saturation wheel

by shaktool forked from Polish Hand Magic (diff: 195)
Explanation:
http://www.smbc-comics.com/index.php?db=comics&id=1914#comic
♥0 | Line 88 | Modified 2012-12-12 02:21:35 | MIT License
play

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