Skip to content

Instantly share code, notes, and snippets.

@andyli
Created April 4, 2011 07:41
Show Gist options
  • Select an option

  • Save andyli/901255 to your computer and use it in GitHub Desktop.

Select an option

Save andyli/901255 to your computer and use it in GitHub Desktop.
onthewings.stuffs.stuff10
/**
* Some of the renderings can be found at
* http://www.flickr.com/photos/andy-li/sets/72157625719497466/
*
*
* Copyright (c) 2011, Andy Li http://www.onthewings.net/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
color scheme:
http://www.colourlovers.com/palette/378803/night_city
*/
package onthewings.stuffs.stuff10;
import cpp.Sys;
import hxColorToolkit.spaces.RGB;
import hxColorToolkit.spaces.HSL;
import nme.geom.Point;
import nme.geom.Vector3D;
import org.casalib.util.NumberUtil;
import of.Context;
using of.Context.Functions;
using Math;
using Lambda;
using DateTools;
using StringTools;
using nme.geom.Point;
using org.casalib.util.ArrayUtil;
using org.casalib.util.NumberUtil;
using org.casalib.util.GeomUtil;
using org.casalib.util.ConversionUtil;
using hxColorToolkit.ColorToolkit;
//Park-Miller-Carta Pseudo-Random Number Generator
//https://github.com/pnitsch/BitmapData.js/blob/master/js/BitmapData.js
class PRNG {
public var seed:Float;
public function new():Void {
seed = 1;
}
public function next(){
return gen() / 2147483647;
}
public function nextRange(min:Float, max:Float){
return min + ((max - min) * next());
}
public function gen(){
return seed = (seed * 16807) % 2147483647;
}
}
//https://github.com/pnitsch/BitmapData.js/blob/master/js/Simplex.js
class SimplexNoise {
var rand:PRNG;
static var grad3:Array<Array<Int>> =
[
[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],
[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],
[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]
];
var p:Array<Int>;
var perm:Array<Int>;
public function new(gen:PRNG):Void {
rand = gen;
}
public function setSeed(seed:Float):Void {
this.p = [];
this.rand.seed = seed;
for (i in 0...256) {
this.p[i] = Std.int(this.rand.nextRange(0, 255));
}
this.perm = [];
for(i in 0...512) {
this.perm[i]=this.p[i & 255];
}
}
inline static function dot(g:Array<Int>, x:Float, y:Float):Float {
return g[0]*x + g[1]*y;
}
public function noise(xin:Float, yin:Float):Float {
var n0, n1, n2;
var F2 = 0.5*(Math.sqrt(3.0)-1.0);
var s = (xin+yin)*F2;
var i = Std.int(xin+s);
var j = Std.int(yin+s);
var G2 = (3.0-Math.sqrt(3.0))/6.0;
var t = (i+j)*G2;
var X0 = i-t;
var Y0 = j-t;
var x0 = xin-X0;
var y0 = yin-Y0;
var i1, j1;
if(x0>y0) {i1=1; j1=0;}
else {i1=0; j1=1;}
var x1 = x0 - i1 + G2;
var y1 = y0 - j1 + G2;
var x2 = x0 - 1.0 + 2.0 * G2;
var y2 = y0 - 1.0 + 2.0 * G2;
var ii = i & 255;
var jj = j & 255;
var gi0 = this.perm[ii+this.perm[jj]] % 12;
var gi1 = this.perm[ii+i1+this.perm[jj+j1]] % 12;
var gi2 = this.perm[ii+1+this.perm[jj+1]] % 12;
var t0 = 0.5 - x0*x0-y0*y0;
if(t0<0) n0 = 0.0;
else {
t0 *= t0;
n0 = t0 * t0 * dot(grad3[gi0], x0, y0);
}
var t1 = 0.5 - x1*x1-y1*y1;
if(t1<0) n1 = 0.0;
else {
t1 *= t1;
n1 = t1 * t1 * dot(grad3[gi1], x1, y1);
}
var t2 = 0.5 - x2*x2-y2*y2;
if(t2<0) n2 = 0.0;
else {
t2 *= t2;
n2 = t2 * t2 * dot(grad3[gi2], x2, y2);
}
return 70.0 * (n0 + n1 + n2);
}
}
class Main extends BaseApp
{
var screenCap:Image;
var width:Int;
var height:Int;
override public function setup():Void {
setFrameRate(1);
enableAlphaBlending();
setCircleResolution(40);
enableSmoothing();
background(8, 0, 0);
width = getWidth();
height = getHeight();
screenCap = new Image();
screenCap.allocate(width, height, Constants.OF_IMAGE_COLOR);
var p = screenCap.getPixels();
for (i in 0...p.length) {
p[i] = cast 0;
}
screenCap.update();
}
override public function draw():Void {
/* draw stars */
for (i in 0...80000){
var s_x = NumberUtil.randomWithinRange(0, width);
var s_y = NumberUtil.randomWithinRange(0, height);
var brightness = random(0,1).pow(150).map(0,1,0,255);
var color = new HSL(random(0, 270), random(0, 30), random(0, 100)).toRGB();
noFill();
setColor(color.red.round(), color.green.round(), color.blue.round(), brightness.round());
circle(s_x, s_y, 0.8);
fill();
setColor(color.red.round(), color.green.round(), color.blue.round(), (brightness * 0.1).round());
circle(s_x, s_y, 2);
setColor(color.red.round(), color.green.round(), color.blue.round(), (brightness * 0.02).round());
circle(s_x, s_y, 5);
}
/* draw moon */
setColor(225, 225, 235, 255);
fill();
circle(width * 0.8, height * 0.2, 40);
setColor(225, 225, 245, 5);
circle(width * 0.8, height * 0.2, 41);
setColor(225, 225, 245, 1);
circle(width * 0.8, height * 0.2, 45);
noFill();
setColor(225, 225, 245, 255);
circle(width * 0.8, height * 0.2, 40);
fill();
for (i in 0...150){
var color = new HSL(random(0, 270), random(0, 50), random(0, 10)).toRGB();
setColor(color.red.round(), color.green.round(), color.blue.round(), random(1, 5).round());
circle(width * 0.8 + random(-40,40), height * 0.2 + random(-40,40), random(0, 10));
}
/* draw city */
pushMatrix();
translate(0, height*0.7);
var yStep = height / 20;
var x;
var y = yStep;
do {
x = 0.0;
var s = y/height + 0.2;
do {
var w = NumberUtil.randomWithinRange(20, 30) * s;
var h = NumberUtil.randomWithinRange(20, 100) * s;
var d = 15 * s;
var hsl = new RGB(93, 89, 16).toHSL();
hsl.lightness *= s;
hsl.saturation *= s;
var colorScheme = hsl.getColor().getAnalogousScheme(10 * s, 10 * s).array();
var bodyColor = colorScheme.random().toRGB();
var ceilingColor = colorScheme.random().toRGB();
fill();
setColor(bodyColor.red.round(), bodyColor.green.round(), bodyColor.blue.round());
rect(x, y-h, w, h);
setColor(ceilingColor.red.round(), ceilingColor.green.round(), ceilingColor.blue.round());
rect(x, y-h-d, w, d);
/* window light */
var win_grid_x = 3;
var win_grid_y = 8;
var win_w = w / win_grid_x;
var win_h = h / win_grid_y;
var hsl = new RGB(255, 246, 66).toHSL();
hsl.lightness *= s;
var lightColor = hsl.toRGB();
for (i in 0...NumberUtil.randomIntegerWithinRange(0,30)) {
var win_x = x + win_w * NumberUtil.randomIntegerWithinRange(0, win_grid_x-1);
var win_y = y - win_h * NumberUtil.randomIntegerWithinRange(0, win_grid_y-1);
setColor(lightColor.red.round(), lightColor.green.round(), lightColor.blue.round(), 50);
rect(win_x, win_y, win_w, win_h);
setColor(lightColor.red.round(), lightColor.green.round(), lightColor.blue.round(), 255);
rect(win_x + win_w*0.1, win_y + win_h*0.1, win_w*0.8, win_h*0.8);
}
x += w;
} while (x < width);
y += yStep * s;
} while (y < height + yStep*2);
popMatrix();
var noiseImg = new Image();
noiseImg.allocate(width, height, Constants.OF_IMAGE_COLOR_ALPHA);
var p = noiseImg.getPixels();
/* draw cloud */
//perlinNoise modified from https://github.com/pnitsch/BitmapData.js/blob/master/js/BitmapData.js
var randomSeed = Date.now().getTime();
var baseX = 500;
var baseY = 300;
var imData = p;
var simplexR = new SimplexNoise(new PRNG());
simplexR.setSeed(randomSeed);
var simplexG = new SimplexNoise(new PRNG());
simplexG.setSeed(randomSeed+1);
var simplexB = new SimplexNoise(new PRNG());
simplexB.setSeed(randomSeed+2);
var pos = 0, cr, cg, cb;
for(y in 0...height) {
for(x in 0...width) {
cr = Std.int(((simplexR.noise(x/baseX, y/baseY)+1)*0.5)*255);
cg = Std.int(((simplexG.noise(x/baseX, y/baseY)+1)*0.5)*255);
cb = Std.int(((simplexB.noise(x/baseX, y/baseY)+1)*0.5)*255);
imData[pos++] = cast 255;
imData[pos++] = cast 255;
imData[pos++] = cast 255;
imData[pos++] = cast Std.int((cr + cg + cb) / 3 * (y - height*0.7).abs().map(0, height*0.5, 1, 0).constrain(0,1) * 0.2);
}
}
noiseImg.update();
setColor(255, 255, 255, 150);
noiseImg.draw(0,0);
}
override public function keyPressed(key:Int):Void {
if (key == 's'.charCodeAt(0)){
screenCap.grabScreen(0, 0, width, height);
screenCap.saveImage(Date.now().format("%Y%m%d_%H%M%S") + ".png");
} else if (key == 'a'.charCodeAt(0)) {
setup();
}
}
public static function main():Void {
AppRunner.setupOpenGL(new AppGlutWindow(), 1680, 1050, Constants.OF_FULLSCREEN);
//AppRunner.setupOpenGL(new AppGlutWindow(), 1024, 768, Constants.OF_WINDOW);
AppRunner.runApp(new Main());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment