Skip to content

Instantly share code, notes, and snippets.

@andyli
Created February 20, 2011 05:52
Show Gist options
  • Select an option

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

Select an option

Save andyli/835750 to your computer and use it in GitHub Desktop.
onthewings.stuffs.stuff7
/**
* 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.
*/
package onthewings.stuffs.stuff7;
import cpp.Sys;
import feffects.easing.Back;
import feffects.easing.Cubic;
import feffects.easing.Expo;
import feffects.easing.Quad;
import feffects.easing.Quart;
import feffects.easing.Sine;
import hxColorToolkit.spaces.HSL;
import nme.geom.Point;
import of.Context;
import org.casalib.util.NumberUtil;
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;
using feffects.easing.Expo;
class PolyLine {
public var points(default, null):Array<Point>;
public function new(?pts:Array<Point>):Void {
points = pts == null ? [] : pts;
}
public function draw(app:BaseApp):Void {
app.noFill();
app.beginShape();
for (pt in points) {
app.vertex(pt.x, pt.y);
}
app.endShape();
}
public function drawCurve(app:BaseApp):Void {
if (points.length == 0) return;
app.noFill();
app.beginShape();
app.curveVertex(points[0].x, points[0].y);
for (pt in points) {
app.curveVertex(pt.x, pt.y);
}
app.curveVertex(points[points.length - 1].x, points[points.length - 1].y);
app.endShape();
}
}
class Feather {
public var polyline0(default, null):Array<PolyLine>;
public var polyline1(default, null):Array<PolyLine>;
public var width(default, null):Float;
public var height(default, null):Float;
public function new():Void {
}
public function generate(width:Float, height:Float, truckPrecent:Float = 0.25, proportion:Float = 0.2):Feather {
this.width = width;
this.height = height;
polyline0 = [];
polyline1 = [];
for (i in 0...cast height) {
var y0 = height * truckPrecent + i.map(0, height - 1, 0, height * (1 - truckPrecent));
var y1 = y0 + i.map(0, height, 10, 0);
var y2 = y1 + i.map(0, height, 20, 0);
var y3 = y2 + i.map(0, height, 50, 0);
var truckRadius = i.easeIn(width * 0.04, -width * 0.04, height-1) * 0.5;
var len = i.easeIn(width * proportion, -width * proportion, height-1);
var line = new PolyLine();
line.points.push(new Point(truckRadius, y0));
line.points.push(new Point(truckRadius + len * 0.2, y1));
line.points.push(new Point(truckRadius + len * 0.8, y2));
line.points.push(new Point(truckRadius + len, y3));
polyline0.push(line);
len = i.easeIn(width * (1 - proportion), -width * (1 - proportion), height - 1);
line = new PolyLine();
line.points.push(new Point(-truckRadius, y0));
line.points.push(new Point(-len*0.2 - truckRadius, y1));
line.points.push(new Point(-len*0.8 - truckRadius, y2));
line.points.push(new Point(-len - truckRadius, y3));
polyline1.push(line);
}
return this;
}
public function draw(app:BaseApp):Void {
for (line in polyline0)
line.drawCurve(app);
for (line in polyline1)
line.drawCurve(app);
//app.fill();
for (y in 0...cast height) {
app.circle(0, y, y.easeIn(width * 0.04, -width * 0.04, height));
}
}
}
class Leaf {
var side:Array<Feather>;
public var width(default, null):Float;
public var height(default, null):Float;
public function new():Void {
}
public function generate(w:Float, h:Float):Leaf {
width = w;
height = h;
side = [];
for (i in 0...20) {
var s = i < 10 ? Quad.easeOut(i, 0.5, 0.5, 10) : Quart.easeIn(i - 10, 1, -0.5, 10);
side.push(new Feather().generate(h * 0.06 * s, w * 0.5 * s, 0.05, 0.5));
}
return this;
}
public function draw(app:BaseApp):Void {
app.pushMatrix();
app.setColor(10, 155, 10, 255);
app.setLineWidth(width * 0.005);
app.line(0, 0, 0, height);
app.setColor(10, 155, 10, 10);
app.setLineWidth(1);
app.pushMatrix();
app.rotateZ(-90);
for (i in 0...side.length){
app.pushMatrix();
var f = side[i];
app.translate(i.map(0, side.length, -height*0.2, -height), 0);
app.rotateZ(i.map(0, side.length, 10, 80));
f.draw(app);
app.popMatrix();
}
app.popMatrix();
app.scale( -1, 1);
app.pushMatrix();
app.rotateZ(-90);
for (i in 0...side.length){
app.pushMatrix();
var f = side[i];
app.translate(i.map(0, side.length, -height*0.2, -height), 0);
app.rotateZ(i.map(0, side.length, 10, 80));
f.draw(app);
app.popMatrix();
}
app.popMatrix();
app.popMatrix();
}
}
class Main extends BaseApp
{
var screenCap:Image;
var width:Int;
var height:Int;
var leaf:Leaf;
override public function setup():Void {
setFrameRate(30);
enableAlphaBlending();
enableSmoothing();
background(255, 255, 255);
screenCap = new Image();
screenCap.allocate(getWidth(), getHeight(), Constants.OF_IMAGE_COLOR);
var p = screenCap.getPixels();
for (i in 0...p.length) {
p[i] = cast 255;
}
screenCap.update();
width = getWidth();
height = getHeight();
leaf = new Leaf().generate(width * 0.4, height);
}
override public function draw():Void {
translate(width * 0.5, height);
scale(0.15, 0.15, 0.15);
var y = 0.0;
var offsetX, offsetY;
while (y < height*4) {
offsetX = NumberUtil.randomWithinRange(-width * 0.1, width * 0.1);
offsetY = NumberUtil.randomWithinRange(height * 0.2, height);
if (y > height*1.5 && Math.random() > 0.5) {
setColor(10, 155, 10, 255);
setLineWidth(width * 0.002);
line(0, 0, offsetX, -offsetY);
translate(offsetX, -offsetY);
do {
var _x = NumberUtil.randomWithinRange(-width * 0.3, width * 0.3);
var _y = -NumberUtil.randomWithinRange(height * 0.3, height);
setColor(10, 155, 10, 255);
setLineWidth(width * 0.002);
line(0, 0, _x, _y);
pushMatrix();
translate(_x, _y);
setLineWidth(width * 0.001);
for (i in 0...1000) {
var pt = new Point(NumberUtil.randomWithinRange(0, width*0.2), 0);
pt.rotatePoint(new Point(), NumberUtil.randomWithinRange(0, 360));
setColor(227, 187, 224, 130);
line(0, 0, pt.x, pt.y);
setColor(143, 141, 118, 100);
circle(pt.x, pt.y, width * 0.0005);
}
popMatrix();
} while (Math.random() > 0.5);
} else {
setColor(10, 155, 10, 255);
setLineWidth(width * 0.002);
line(0, 0, offsetX, -offsetY);
translate(offsetX, -offsetY);
pushMatrix();
rotateZ(NumberUtil.randomWithinRange( 40, 180) * (Math.random() > 0.5 ? 1 : -1));
drawLeaves();
popMatrix();
}
y += offsetY;
}
}
function drawLeaves():Void {
pushMatrix();
setColor(10, 155, 10, 255);
setLineWidth(width * 0.002);
line(0, 0, 0, height);
translate(0, height);
pushMatrix();
rotateZ(20);
leaf.draw(this);
rotateZ(50);
leaf.draw(this);
popMatrix();
pushMatrix();
rotateZ(-20);
leaf.draw(this);
rotateZ(-50);
leaf.draw(this);
popMatrix();
popMatrix();
}
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(), 1920, 1080, Constants.OF_FULLSCREEN);
//AppRunner.setupOpenGL(new AppGlutWindow(), 1280, 720, 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