Team:Cornell/javascripts/mycodraw
From 2013.igem.org
R.Lizarralde (Talk | contribs) |
R.Lizarralde (Talk | contribs) |
||
Line 1: | Line 1: | ||
+ | var P_TURN = 0.1; | ||
+ | var P_SPLIT = 0.1/256; | ||
+ | var P_TRAIL = 1.0; | ||
+ | var P_DIE = 0.01; | ||
+ | var mc = 0x44; | ||
+ | var myc = [mc, mc, mc]; | ||
+ | var invertFood = false; | ||
+ | var invertMyc = true; | ||
+ | var antialias = true; | ||
+ | var l = 50; | ||
+ | var bleedHue = 0; | ||
+ | var overEat = 1; | ||
+ | //var alive = true; | ||
+ | //var started = false; | ||
- | function mycoDraw( | + | var w; |
+ | var h; | ||
+ | var food; | ||
+ | var draw; | ||
+ | var cx; | ||
+ | var cy; | ||
+ | |||
+ | var tips; | ||
+ | var trls; | ||
+ | var dirs; | ||
+ | var trns; | ||
+ | var spts; | ||
+ | var jins; | ||
+ | var tins; | ||
+ | var trqs; | ||
+ | var trcs; | ||
+ | var trailCounts; | ||
+ | |||
+ | function mycoDraw() | ||
{ | { | ||
+ | var src_canvas = document.getElementById("mycosource"); | ||
+ | w = src_canvas.children[0].width; | ||
+ | h = src_canvas.children[0].height; | ||
+ | src_canvas.width = w; | ||
+ | src_canvas.height = h; | ||
+ | food = src_canvas.getContext("2d"); | ||
+ | food.drawImage(src_canvas.children[0], 0, 0); | ||
+ | |||
var canvas = document.getElementById("mycodraw"); | var canvas = document.getElementById("mycodraw"); | ||
- | + | canvas.width = w; | |
- | canvas. | + | canvas.height = h; |
- | canvas.height = | + | draw = canvas.getContext("2d"); |
- | var | + | draw.fillStyle = "#F2F2F2"; |
- | + | draw.fillRect(0, 0, canvas.width, canvas.height); | |
- | + | ||
- | + | cx = width/2; | |
+ | cy = height/2; | ||
+ | |||
+ | tips = new Array(); | ||
+ | trls = new Array(); | ||
+ | dirs = new Array(); | ||
+ | trns = new Array(); | ||
+ | spts = new Array(); | ||
+ | jins = new Array(); | ||
+ | tins = new Array(); | ||
+ | trqs = new Array(); | ||
+ | trcs = new Array(); | ||
+ | trailCounts = new Array(); | ||
+ | |||
+ | for(var i = 0; i < 100; i++) | ||
+ | { | ||
+ | tips.push([Math.random()*w,Math.random()*h]); | ||
+ | trls.push(new Array(l)); | ||
+ | dirs.push(Math.floor(Math.random()*360)); | ||
+ | trns.push(Math.random() > 0.5); | ||
+ | spts.push(10); | ||
+ | trailCounts.push(0); | ||
+ | } | ||
+ | |||
+ | var speed = 10; | ||
+ | for(var t = 0; tips.length > 0; t = (l > 0 ? (t+1)%l : 0)) | ||
+ | { | ||
+ | for(var i = tips.length-1; i >= 0; i--) | ||
+ | { | ||
+ | var p = tips[i]; | ||
+ | var trl = trls[i]; | ||
+ | if(l > 0) trl[t] = p; | ||
+ | spts[i] = spts[i] - 1; | ||
+ | |||
+ | var vals = colorPovar(p, null, 1.0, dirs[i]); //the main strand-coloring call | ||
+ | var out = vals[0]; | ||
+ | if(out > 0.45) //turns the tips around if they hit the edge | ||
+ | { | ||
+ | var dx = p[0] - cx; | ||
+ | var dy = p[1] - cy; | ||
+ | var theta = Math.floor(Math.abs((Math.atan(dy/dx)/Math.PI)*180)); | ||
+ | if(dx > 0 == dy < 0) | ||
+ | { theta = 180*(dx > 0 ? 1 : 2) - theta; } | ||
+ | if(dx > 0 && dy > 0) | ||
+ | { theta = theta + 180; } | ||
+ | dirs[i] = theta; | ||
+ | } | ||
+ | var wp = vals[1]; | ||
+ | var ref = [vals[2], vals[3], vals[4]]; | ||
+ | |||
+ | if(trailCounts[i] == 0 && Math.random() < P_TRAIL && | ||
+ | vals[3] > 0.4 && vals[4] > 0.5 && | ||
+ | ( Math.abs(vals[2] - bleedHue) < 0.05 || | ||
+ | Math.abs(Math.abs(vals[2]-1.0) - bleedhue) < 0.05) | ||
+ | )) | ||
+ | { | ||
+ | trailCounts[i] = l; | ||
+ | jins.push(0); | ||
+ | tins.push(t); | ||
+ | trqs.push(trls[i].slice(0)) | ||
+ | trcs.push(ref); | ||
+ | } | ||
+ | else | ||
+ | { trailCounts[i] = Math.max(trailCounts[i]-1, 0); } | ||
+ | |||
+ | if(Math.random() < P_TURN*wp*wp*wp*wp) { trns[i] = !trns[i]; } | ||
+ | if(Math.random() < P_SPLIT*(wp*256)/(tips.length/50) && spts[i] < 1) | ||
+ | { | ||
+ | spts[i] = 10; | ||
+ | trls.push(trls[i].slice(0)); | ||
+ | tips.push(p.slice(0)); | ||
+ | dirs.push(dirs[i]); | ||
+ | trns.push(!trns[i]); | ||
+ | spts.push(10); | ||
+ | trailCounts.push(0); | ||
+ | } | ||
+ | if(out < 0.1 && Math.random() < P_DIE*(1.0-wp)) | ||
+ | { | ||
+ | tips.splice(i, 1); | ||
+ | trls.splice(i, 1); | ||
+ | dirs.splice(i, 1); | ||
+ | trns.splice(i, 1); | ||
+ | spts.splice(i, 1); | ||
+ | trailCounts.splice(i, 1); | ||
+ | //original: prvar dead | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | var turn = Math.floor(Math.random()*5); | ||
+ | dirs[i] = (dirs[i] + (trns[i] ? turn : -1*turn))%360; | ||
+ | var xd = wp*Math.cos(((dirs[i])/180.0)*Math.PI); | ||
+ | var yd = wp*Math.sin(((dirs[i])/180.0)*Math.PI); | ||
+ | tips[i] = [p[0] + xd, p[1] + yd]; | ||
+ | } | ||
+ | } | ||
+ | if(l > 0) //trail-coloring | ||
+ | { | ||
+ | for(var i = tins.length - 1; i >= 0; i--) | ||
+ | { | ||
+ | colorPovar(trqs[i][(tins[i]+(l-1)-jins[i])%l], trcs[i], trailStrength*(1.0-((1.0*jins[i])/(1.0*l))), 0); | ||
+ | jins[i] = jins[i]+1; | ||
+ | if(jins[i] == l) //this trail is completed | ||
+ | { | ||
+ | jins.splice(i, 1); | ||
+ | tins.splice(i, 1); | ||
+ | trqs.splice(i, 1); | ||
+ | trcs.splice(i, 1); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | if(speed > 1.0) | ||
+ | { | ||
+ | pausecomp(Math.floor(speed + 0.5)); | ||
+ | speed = speed*0.999; | ||
+ | } | ||
+ | } | ||
} | } | ||
+ | |||
+ | function colorPovar(p, ref, strength, dir) | ||
+ | { | ||
+ | var rets = new Array(5); | ||
+ | if(p == null) | ||
+ | return rets; | ||
+ | var dx1 = p[0]-0.5; | ||
+ | var dx2 = p[0]+0.5; | ||
+ | var dy1 = p[1]-0.5; | ||
+ | var dy2 = p[1]+0.5; | ||
+ | var x1 = Math.floor(dx1 - (dx1 < 0 ? 1 : 0)); | ||
+ | var x2 = Math.floor(dx2 - (dx2 < 0 ? 1 : 0)); | ||
+ | var y1 = Math.floor(dy1 - (dy1 < 0 ? 1 : 0)); | ||
+ | var y2 = Math.floor(dy2 - (dy2 < 0 ? 1 : 0)); | ||
+ | var x = [x2, x1, x1, x2, x1-1, x1, x2, x2+1]; | ||
+ | var y = [y2, y2, y1, y1, 0, 0, 0, 0]; | ||
+ | var mx = ((x1+x2)/2.0) + 0.5; | ||
+ | var my = ((y1+y2)/2.0) + 0.5; | ||
+ | //percentages in each nearby pixel, numbered in this fashion: | ||
+ | // x1 x2 | ||
+ | // y1 3 | 4 | ||
+ | // --•-- | ||
+ | // y2 2 | 1 | ||
+ | var p1 = (dx2-mx)*(dy2-my); | ||
+ | var p2 = (mx-dx1)*(dy2-my); | ||
+ | var p3 = (dx2-mx)*(my-dy1); | ||
+ | var p4 = (mx-dx1)*(my-dy1); | ||
+ | var pj = [p1, p2, p3, p4, 0, 0, 0, 0]; | ||
+ | if((0 <= dir && dir < 90) || (180 <= dir && dir < 270)) | ||
+ | { | ||
+ | y[4] = y2; | ||
+ | y[5] = y2+1; | ||
+ | y[6] = y1-1; | ||
+ | y[7] = y1; | ||
+ | pj[4] = p2*overEat; | ||
+ | pj[5] = p2*overEat; | ||
+ | pj[6] = p4*overEat; | ||
+ | pj[7] = p4*overEat; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | y[4] = y1; | ||
+ | y[5] = y1-1; | ||
+ | y[6] = y2+1; | ||
+ | y[7] = y2; | ||
+ | pj[4] = p3*overEat; | ||
+ | pj[5] = p3*overEat; | ||
+ | pj[6] = p1*overEat; | ||
+ | pj[7] = p1*overEat; | ||
+ | } | ||
+ | if(!antialias) | ||
+ | { | ||
+ | var ps = new Array(); | ||
+ | for(var j = 0; j < 4; j++) | ||
+ | ps.push(pj[j]); | ||
+ | ps.sort(); | ||
+ | for(var j = 0; j < 4; j++) | ||
+ | if(pj[j] == ps[3]) | ||
+ | pj[j] = 1.0; | ||
+ | else | ||
+ | pj[j] = 0.0; | ||
+ | } | ||
+ | var rgb = new Array(); | ||
+ | var wd = 0.0; | ||
+ | var wp = 0.0; | ||
+ | if(ref == null) | ||
+ | { | ||
+ | rgb.push(food.getImageData(x2, y2, 1, 1).data); | ||
+ | rgb.push(food.getImageData(x1, y2, 1, 1).data); | ||
+ | rgb.push(food.getImageData(x1, y1, 1, 1).data); | ||
+ | rgb.push(food.getImageData(x2, y1, 1, 1).data); | ||
+ | var hue = 0; | ||
+ | var saturation = 0; | ||
+ | var brightness = 0; | ||
+ | for(var j = 0; j < 4; j++) | ||
+ | { | ||
+ | var hsb = RGBtoHSB(rgb[j]); | ||
+ | hue += hsb[0]*pj[j]; | ||
+ | saturation += hsb[1]*pj[j]; | ||
+ | brightness += hsb[2]*pj[j]; | ||
+ | } | ||
+ | |||
+ | rets[2] = hue; | ||
+ | rets[3] = saturation; | ||
+ | rets[4] = brightness; | ||
+ | |||
+ | var dr = 0; | ||
+ | var dg = 0; | ||
+ | var db = 0; | ||
+ | for(var j = 0; j < 4; j++) | ||
+ | { | ||
+ | dr += pj[j]*Math.floor(c[j].getRed()); | ||
+ | dg += pj[j]*Math.floor(c[j].getGreen()); | ||
+ | db += pj[j]*Math.floor(c[j].getBlue()); | ||
+ | } | ||
+ | var r = Math.floor(dr); | ||
+ | var g = Math.floor(dg); | ||
+ | var b = Math.floor(db); | ||
+ | |||
+ | wd = Math.min(256.0, Math.floor(((r + g + b)/3)) + 25.6); | ||
+ | wp = wd/256.0; | ||
+ | |||
+ | if(false) wp = 1.0 - wp; //invertFood | ||
+ | } | ||
+ | |||
+ | var inside = new Array(8); | ||
+ | for(var j = 0; j < 8; j++) | ||
+ | { | ||
+ | inside[j] = x[j] < w && y[j] < h; | ||
+ | inside[j] = inside[j] && x[j] >= 0 && y[j] >= 0; | ||
+ | |||
+ | if(inside[j]) | ||
+ | { | ||
+ | if(ref == null) // if this is a strand-drawing call | ||
+ | { | ||
+ | var origColor = food.getImageData(x[j], y[j], 1, 1).data; | ||
+ | //Color origColor = new Color(food.getRGB(x[j], y[j])); | ||
+ | // if(true) //invertMyc | ||
+ | // { | ||
+ | var addColor = addRGB(origColor, myc, pj[j]); | ||
+ | var addedColor = subRGB(addColor, origColor, 1.0); | ||
+ | var imgd = food.getImageData(x[j], y[j], 1, 1); | ||
+ | imgd.data.splice(0, 3, addColor[0], addColor[1], addColor[2]); | ||
+ | food.putImageData(imgd); | ||
+ | //Color addColor = addRGB(origColor, myc, pj[j]); | ||
+ | //Color addedColor = subRGB(addColor, origColor, 1.0); | ||
+ | //food.setRGB(x[j], y[j], addColor.getRGB()); | ||
+ | if(j < 5) | ||
+ | { | ||
+ | imgd = draw.getImageData(x[j], y[j], 1, 1); | ||
+ | var subbedColor = subRGB(imgd.data, addedColor, 1.0); | ||
+ | imgd.data.splice(0, 3, subbedColor[0], subbedColor[1], subbedColor[2]); | ||
+ | draw.putImageData(imgd); | ||
+ | } | ||
+ | //draw.setRGB(x[j], y[j], subRGB(new Color(draw.getRGB(x[j], y[j])), addedColor, 1.0).getRGB()); | ||
+ | // } | ||
+ | //else | ||
+ | //{ | ||
+ | // Color subColor = subRGB(origColor, myc, pj[j]); | ||
+ | // Color subbedColor = subRGB(origColor, subColor, 1.0); | ||
+ | // food.setRGB(x[j], y[j], subColor.getRGB()); | ||
+ | // if(j < 5) | ||
+ | // draw.setRGB(x[j], y[j], addRGB(new Color(draw.getRGB(x[j], y[j])), subbedColor, 1.0).getRGB()); | ||
+ | //} | ||
+ | } | ||
+ | else //if this is a trail-drawing call | ||
+ | { | ||
+ | var imgd = draw.getImageData(x[j], y[j], 1, 1); | ||
+ | var addedColor = addHSB(imgd.data, ref, strength); | ||
+ | imgd.data.splice(0,3, addedColor[0], addedColor[1], addedColor[2]); | ||
+ | |||
+ | //draw.setRGB(x[j], y[j], addHSB( | ||
+ | // new Color(image.getRGB(x[j],y[j])), | ||
+ | // new Color(food.getRGB(x[j],y[j])), | ||
+ | // new Color(draw.getRGB(x[j],y[j])), | ||
+ | // ref, | ||
+ | // strength).getRGB()); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | var out = 0; | ||
+ | for(var j = 0; j < 4; j++) | ||
+ | if(!inside[j]) out += 0.25; | ||
+ | rets[0] = out; | ||
+ | rets[1] = wp; | ||
+ | return rets; | ||
+ | } | ||
+ | |||
+ | function addRGB(c1, c2, weight) | ||
+ | { | ||
+ | return [Math.min(c1[0] + Math.floor(c2[0]*weight + 0.5), 0xFF), | ||
+ | Math.min(c1[1] + Math.floor(c2[1]*weight + 0.5), 0xFF), | ||
+ | Math.min(c1[2] + Math.floor(c2[2]*weight + 0.5), 0xFF)]; | ||
+ | |||
+ | // return new Color( | ||
+ | // Math.min(c1.getRed()+ (int)(c2.getRed()*weight + 0.5) , 0xFF), | ||
+ | // Math.min(c1.getGreen()+ (int)(c2.getGreen()*weight + 0.5) , 0xFF), | ||
+ | // Math.min(c1.getBlue()+ (int)(c2.getBlue()*weight + 0.5) , 0xFF)); | ||
+ | |||
+ | } | ||
+ | |||
+ | function subRGB(c1, c2, weight) | ||
+ | { | ||
+ | return [Math.min(c1[0] - Math.floor(c2[0]*weight + 0.5), 0xFF), | ||
+ | Math.min(c1[1] - Math.floor(c2[1]*weight + 0.5), 0xFF), | ||
+ | Math.min(c1[2] - Math.floor(c2[2]*weight + 0.5), 0xFF)]; | ||
+ | |||
+ | // return new Color( | ||
+ | // Math.max(c1.getRed()- (int)(c2.getRed()*weight + 0.5) , 0x00), | ||
+ | // Math.max(c1.getGreen()- (int)(c2.getGreen()*weight + 0.5) , 0x00), | ||
+ | // Math.max(c1.getBlue()- (int)(c2.getBlue()*weight + 0.5) , 0x00)); | ||
+ | |||
+ | } | ||
+ | |||
+ | function addHSB(cd, cr, weight) | ||
+ | { | ||
+ | hd = RGBtoHSB(c1); | ||
+ | hr = RGBtoHSB(c2); | ||
+ | return HSBtoRGB(0, | ||
+ | Math.max((hd[1] + hr[1]*weight)/(1.0+weight), hd[1]), | ||
+ | hd[2]); | ||
+ | |||
+ | // float[] hsbDraw = Color.RGBtoHSB(draw.getRed(), draw.getGreen(), draw.getBlue(), null); | ||
+ | // float[] hsbRef = Color.RGBtoHSB(ref.getRed(), ref.getGreen(), ref.getBlue(), null); | ||
+ | // return Color.getHSBColor(bleedHue, | ||
+ | // Math.max((float)((hsbDraw[1] + hsbRef[1]*weight)/(1.0+weight)), hsbDraw[1]), //adds weight of the ref to saturation | ||
+ | // hsbDraw[2]); | ||
+ | |||
+ | } | ||
+ | |||
+ | function RGBtoHSB(rgb) | ||
+ | { | ||
+ | var r = rgb[0]/255; | ||
+ | var g = rgb[1]/255; | ||
+ | var b = rgb[2]/255; | ||
+ | var min = Math.min(r, g, b); | ||
+ | var max = Math.max(r, g, b); | ||
+ | var del = max - min; | ||
+ | var hsb = new Array(3); | ||
+ | hsb[2] = max; | ||
+ | if(del == 0) | ||
+ | { | ||
+ | hsb[0] = 0; | ||
+ | hsb[1] = 0; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | hsb[1] = del/max; | ||
+ | |||
+ | var delR = (((max - r)/6) + (del/2))/del | ||
+ | var delG = (((max - g)/6) + (del/2))/del | ||
+ | var delB = (((max - b)/6) + (del/2))/del | ||
+ | |||
+ | if(r == max) hsb[0] = delB - delG; | ||
+ | else if(g == max) hsb[0] = (1/3) + delR - delB; | ||
+ | else if(b == max) hsb [0] = (2/3) + delG + delR; | ||
+ | |||
+ | if(hsb[0] < 0) hsb[0] = hsb[0] + 1; | ||
+ | if(hsb[0] > 1) hsb[0] = hsb[0] - 1; | ||
+ | } | ||
+ | return hsb; | ||
+ | } | ||
+ | |||
+ | function HSBtoRGB(hsb) | ||
+ | { | ||
+ | var h = hsb[0]; | ||
+ | var s = hsb[1]; | ||
+ | var v = hsb[2]; | ||
+ | |||
+ | var r = v; | ||
+ | var g = v; | ||
+ | var b = v; | ||
+ | |||
+ | if(s != 0) | ||
+ | { | ||
+ | var sh = h*6; | ||
+ | if(sh == 6) sh = 0; | ||
+ | var hi = Math.floor(sh); | ||
+ | var v1 = v * (1 - s); | ||
+ | var v2 = v * (1 - s * (sh - hi)); | ||
+ | var v3 = v * (1 - s * (1 - (sh - hi))); | ||
+ | |||
+ | if ( hi == 0 ) {r = v; g = v3; b = v1; } | ||
+ | else if ( hi == 1 ) {r = v2; g = v; b = v1; } | ||
+ | else if ( hi == 2 ) {r = v1; g = v; b = v3; } | ||
+ | else if ( hi == 3 ) {r = v1; g = v2; b = v; } | ||
+ | else if ( hi == 4 ) {r = v3; g = v1; b = v; } | ||
+ | else {r = v; g = v1; b = v2; } | ||
+ | } | ||
+ | |||
+ | return [Math.floor(r*255), Math.floor(g*255), Math.floor(b*255)]; | ||
+ | } | ||
+ | |||
+ | function pausecomp(ms) | ||
+ | { | ||
+ | ms += new Date().getTime(); | ||
+ | while (new Date() < ms){} | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | //function mycoDraw(canvas) | ||
+ | //{ | ||
+ | // var canvas = document.getElementById("mycodraw"); | ||
+ | // var img = canvas.children[0]; | ||
+ | // canvas.width = img.width; | ||
+ | // canvas.height = img.height; | ||
+ | // var context = canvas.getContext("2d"); | ||
+ | // alert(img.src); | ||
+ | // context.drawImage(img, 0, 0); | ||
+ | // alert(img.src); | ||
+ | //} |
Revision as of 06:07, 17 June 2013
var P_TURN = 0.1; var P_SPLIT = 0.1/256; var P_TRAIL = 1.0; var P_DIE = 0.01; var mc = 0x44; var myc = [mc, mc, mc]; var invertFood = false; var invertMyc = true; var antialias = true; var l = 50; var bleedHue = 0; var overEat = 1; //var alive = true; //var started = false;
var w; var h; var food; var draw; var cx; var cy;
var tips; var trls; var dirs; var trns; var spts; var jins; var tins; var trqs; var trcs; var trailCounts;
function mycoDraw() { var src_canvas = document.getElementById("mycosource"); w = src_canvas.children[0].width; h = src_canvas.children[0].height; src_canvas.width = w; src_canvas.height = h; food = src_canvas.getContext("2d"); food.drawImage(src_canvas.children[0], 0, 0);
var canvas = document.getElementById("mycodraw"); canvas.width = w; canvas.height = h; draw = canvas.getContext("2d"); draw.fillStyle = "#F2F2F2"; draw.fillRect(0, 0, canvas.width, canvas.height);
cx = width/2; cy = height/2;
tips = new Array(); trls = new Array(); dirs = new Array(); trns = new Array(); spts = new Array(); jins = new Array(); tins = new Array(); trqs = new Array(); trcs = new Array(); trailCounts = new Array();
for(var i = 0; i < 100; i++) { tips.push([Math.random()*w,Math.random()*h]); trls.push(new Array(l)); dirs.push(Math.floor(Math.random()*360)); trns.push(Math.random() > 0.5); spts.push(10); trailCounts.push(0); }
var speed = 10; for(var t = 0; tips.length > 0; t = (l > 0 ? (t+1)%l : 0)) { for(var i = tips.length-1; i >= 0; i--) { var p = tips[i]; var trl = trls[i]; if(l > 0) trl[t] = p; spts[i] = spts[i] - 1;
var vals = colorPovar(p, null, 1.0, dirs[i]); //the main strand-coloring call var out = vals[0]; if(out > 0.45) //turns the tips around if they hit the edge { var dx = p[0] - cx; var dy = p[1] - cy; var theta = Math.floor(Math.abs((Math.atan(dy/dx)/Math.PI)*180)); if(dx > 0 == dy < 0) { theta = 180*(dx > 0 ? 1 : 2) - theta; } if(dx > 0 && dy > 0) { theta = theta + 180; } dirs[i] = theta; } var wp = vals[1]; var ref = [vals[2], vals[3], vals[4]];
if(trailCounts[i] == 0 && Math.random() < P_TRAIL && vals[3] > 0.4 && vals[4] > 0.5 && ( Math.abs(vals[2] - bleedHue) < 0.05 || Math.abs(Math.abs(vals[2]-1.0) - bleedhue) < 0.05) )) { trailCounts[i] = l; jins.push(0); tins.push(t); trqs.push(trls[i].slice(0)) trcs.push(ref); } else { trailCounts[i] = Math.max(trailCounts[i]-1, 0); }
if(Math.random() < P_TURN*wp*wp*wp*wp) { trns[i] = !trns[i]; } if(Math.random() < P_SPLIT*(wp*256)/(tips.length/50) && spts[i] < 1) { spts[i] = 10; trls.push(trls[i].slice(0)); tips.push(p.slice(0)); dirs.push(dirs[i]); trns.push(!trns[i]); spts.push(10); trailCounts.push(0); } if(out < 0.1 && Math.random() < P_DIE*(1.0-wp)) { tips.splice(i, 1); trls.splice(i, 1); dirs.splice(i, 1); trns.splice(i, 1); spts.splice(i, 1); trailCounts.splice(i, 1); //original: prvar dead } else { var turn = Math.floor(Math.random()*5); dirs[i] = (dirs[i] + (trns[i] ? turn : -1*turn))%360; var xd = wp*Math.cos(((dirs[i])/180.0)*Math.PI); var yd = wp*Math.sin(((dirs[i])/180.0)*Math.PI); tips[i] = [p[0] + xd, p[1] + yd]; } } if(l > 0) //trail-coloring { for(var i = tins.length - 1; i >= 0; i--) { colorPovar(trqs[i][(tins[i]+(l-1)-jins[i])%l], trcs[i], trailStrength*(1.0-((1.0*jins[i])/(1.0*l))), 0); jins[i] = jins[i]+1; if(jins[i] == l) //this trail is completed { jins.splice(i, 1); tins.splice(i, 1); trqs.splice(i, 1); trcs.splice(i, 1); } } } if(speed > 1.0) { pausecomp(Math.floor(speed + 0.5)); speed = speed*0.999; } } }
function colorPovar(p, ref, strength, dir) { var rets = new Array(5); if(p == null) return rets; var dx1 = p[0]-0.5; var dx2 = p[0]+0.5; var dy1 = p[1]-0.5; var dy2 = p[1]+0.5; var x1 = Math.floor(dx1 - (dx1 < 0 ? 1 : 0)); var x2 = Math.floor(dx2 - (dx2 < 0 ? 1 : 0)); var y1 = Math.floor(dy1 - (dy1 < 0 ? 1 : 0)); var y2 = Math.floor(dy2 - (dy2 < 0 ? 1 : 0)); var x = [x2, x1, x1, x2, x1-1, x1, x2, x2+1]; var y = [y2, y2, y1, y1, 0, 0, 0, 0]; var mx = ((x1+x2)/2.0) + 0.5; var my = ((y1+y2)/2.0) + 0.5; //percentages in each nearby pixel, numbered in this fashion: // x1 x2 // y1 3 | 4 // --•-- // y2 2 | 1 var p1 = (dx2-mx)*(dy2-my); var p2 = (mx-dx1)*(dy2-my); var p3 = (dx2-mx)*(my-dy1); var p4 = (mx-dx1)*(my-dy1); var pj = [p1, p2, p3, p4, 0, 0, 0, 0]; if((0 <= dir && dir < 90) || (180 <= dir && dir < 270)) { y[4] = y2; y[5] = y2+1; y[6] = y1-1; y[7] = y1; pj[4] = p2*overEat; pj[5] = p2*overEat; pj[6] = p4*overEat; pj[7] = p4*overEat; } else { y[4] = y1; y[5] = y1-1; y[6] = y2+1; y[7] = y2; pj[4] = p3*overEat; pj[5] = p3*overEat; pj[6] = p1*overEat; pj[7] = p1*overEat; } if(!antialias) { var ps = new Array(); for(var j = 0; j < 4; j++) ps.push(pj[j]); ps.sort(); for(var j = 0; j < 4; j++) if(pj[j] == ps[3]) pj[j] = 1.0; else pj[j] = 0.0; } var rgb = new Array(); var wd = 0.0; var wp = 0.0; if(ref == null) { rgb.push(food.getImageData(x2, y2, 1, 1).data); rgb.push(food.getImageData(x1, y2, 1, 1).data); rgb.push(food.getImageData(x1, y1, 1, 1).data); rgb.push(food.getImageData(x2, y1, 1, 1).data); var hue = 0; var saturation = 0; var brightness = 0; for(var j = 0; j < 4; j++) { var hsb = RGBtoHSB(rgb[j]); hue += hsb[0]*pj[j]; saturation += hsb[1]*pj[j]; brightness += hsb[2]*pj[j]; }
rets[2] = hue; rets[3] = saturation; rets[4] = brightness;
var dr = 0; var dg = 0; var db = 0; for(var j = 0; j < 4; j++) { dr += pj[j]*Math.floor(c[j].getRed()); dg += pj[j]*Math.floor(c[j].getGreen()); db += pj[j]*Math.floor(c[j].getBlue()); } var r = Math.floor(dr); var g = Math.floor(dg); var b = Math.floor(db);
wd = Math.min(256.0, Math.floor(((r + g + b)/3)) + 25.6); wp = wd/256.0;
if(false) wp = 1.0 - wp; //invertFood }
var inside = new Array(8); for(var j = 0; j < 8; j++) { inside[j] = x[j] < w && y[j] < h; inside[j] = inside[j] && x[j] >= 0 && y[j] >= 0;
if(inside[j]) { if(ref == null) // if this is a strand-drawing call { var origColor = food.getImageData(x[j], y[j], 1, 1).data; //Color origColor = new Color(food.getRGB(x[j], y[j])); // if(true) //invertMyc // { var addColor = addRGB(origColor, myc, pj[j]); var addedColor = subRGB(addColor, origColor, 1.0); var imgd = food.getImageData(x[j], y[j], 1, 1); imgd.data.splice(0, 3, addColor[0], addColor[1], addColor[2]); food.putImageData(imgd); //Color addColor = addRGB(origColor, myc, pj[j]); //Color addedColor = subRGB(addColor, origColor, 1.0); //food.setRGB(x[j], y[j], addColor.getRGB()); if(j < 5) { imgd = draw.getImageData(x[j], y[j], 1, 1); var subbedColor = subRGB(imgd.data, addedColor, 1.0); imgd.data.splice(0, 3, subbedColor[0], subbedColor[1], subbedColor[2]); draw.putImageData(imgd); } //draw.setRGB(x[j], y[j], subRGB(new Color(draw.getRGB(x[j], y[j])), addedColor, 1.0).getRGB()); // } //else //{ // Color subColor = subRGB(origColor, myc, pj[j]); // Color subbedColor = subRGB(origColor, subColor, 1.0); // food.setRGB(x[j], y[j], subColor.getRGB()); // if(j < 5) // draw.setRGB(x[j], y[j], addRGB(new Color(draw.getRGB(x[j], y[j])), subbedColor, 1.0).getRGB()); //} } else //if this is a trail-drawing call { var imgd = draw.getImageData(x[j], y[j], 1, 1); var addedColor = addHSB(imgd.data, ref, strength); imgd.data.splice(0,3, addedColor[0], addedColor[1], addedColor[2]);
//draw.setRGB(x[j], y[j], addHSB( // new Color(image.getRGB(x[j],y[j])), // new Color(food.getRGB(x[j],y[j])), // new Color(draw.getRGB(x[j],y[j])), // ref, // strength).getRGB()); } } } var out = 0; for(var j = 0; j < 4; j++) if(!inside[j]) out += 0.25; rets[0] = out; rets[1] = wp; return rets; }
function addRGB(c1, c2, weight) { return [Math.min(c1[0] + Math.floor(c2[0]*weight + 0.5), 0xFF), Math.min(c1[1] + Math.floor(c2[1]*weight + 0.5), 0xFF), Math.min(c1[2] + Math.floor(c2[2]*weight + 0.5), 0xFF)];
// return new Color( // Math.min(c1.getRed()+ (int)(c2.getRed()*weight + 0.5) , 0xFF), // Math.min(c1.getGreen()+ (int)(c2.getGreen()*weight + 0.5) , 0xFF), // Math.min(c1.getBlue()+ (int)(c2.getBlue()*weight + 0.5) , 0xFF));
}
function subRGB(c1, c2, weight) { return [Math.min(c1[0] - Math.floor(c2[0]*weight + 0.5), 0xFF), Math.min(c1[1] - Math.floor(c2[1]*weight + 0.5), 0xFF), Math.min(c1[2] - Math.floor(c2[2]*weight + 0.5), 0xFF)];
// return new Color( // Math.max(c1.getRed()- (int)(c2.getRed()*weight + 0.5) , 0x00), // Math.max(c1.getGreen()- (int)(c2.getGreen()*weight + 0.5) , 0x00), // Math.max(c1.getBlue()- (int)(c2.getBlue()*weight + 0.5) , 0x00));
}
function addHSB(cd, cr, weight) { hd = RGBtoHSB(c1); hr = RGBtoHSB(c2); return HSBtoRGB(0, Math.max((hd[1] + hr[1]*weight)/(1.0+weight), hd[1]), hd[2]);
// float[] hsbDraw = Color.RGBtoHSB(draw.getRed(), draw.getGreen(), draw.getBlue(), null); // float[] hsbRef = Color.RGBtoHSB(ref.getRed(), ref.getGreen(), ref.getBlue(), null); // return Color.getHSBColor(bleedHue, // Math.max((float)((hsbDraw[1] + hsbRef[1]*weight)/(1.0+weight)), hsbDraw[1]), //adds weight of the ref to saturation // hsbDraw[2]);
}
function RGBtoHSB(rgb) { var r = rgb[0]/255; var g = rgb[1]/255; var b = rgb[2]/255; var min = Math.min(r, g, b); var max = Math.max(r, g, b); var del = max - min; var hsb = new Array(3); hsb[2] = max; if(del == 0) { hsb[0] = 0; hsb[1] = 0; } else { hsb[1] = del/max;
var delR = (((max - r)/6) + (del/2))/del var delG = (((max - g)/6) + (del/2))/del var delB = (((max - b)/6) + (del/2))/del
if(r == max) hsb[0] = delB - delG; else if(g == max) hsb[0] = (1/3) + delR - delB; else if(b == max) hsb [0] = (2/3) + delG + delR;
if(hsb[0] < 0) hsb[0] = hsb[0] + 1; if(hsb[0] > 1) hsb[0] = hsb[0] - 1; } return hsb; }
function HSBtoRGB(hsb) { var h = hsb[0]; var s = hsb[1]; var v = hsb[2];
var r = v; var g = v; var b = v;
if(s != 0) { var sh = h*6; if(sh == 6) sh = 0; var hi = Math.floor(sh); var v1 = v * (1 - s); var v2 = v * (1 - s * (sh - hi)); var v3 = v * (1 - s * (1 - (sh - hi)));
if ( hi == 0 ) {r = v; g = v3; b = v1; } else if ( hi == 1 ) {r = v2; g = v; b = v1; } else if ( hi == 2 ) {r = v1; g = v; b = v3; } else if ( hi == 3 ) {r = v1; g = v2; b = v; } else if ( hi == 4 ) {r = v3; g = v1; b = v; } else {r = v; g = v1; b = v2; } }
return [Math.floor(r*255), Math.floor(g*255), Math.floor(b*255)]; }
function pausecomp(ms) { ms += new Date().getTime(); while (new Date() < ms){} }
//function mycoDraw(canvas) //{ // var canvas = document.getElementById("mycodraw"); // var img = canvas.children[0]; // canvas.width = img.width; // canvas.height = img.height; // var context = canvas.getContext("2d"); // alert(img.src); // context.drawImage(img, 0, 0); // alert(img.src); //}