Make a scalable Christmas Tree
Python
A fractal Christmas tree using the turtle package:
n = input()*1.
from turtle import *
speed("fastest")
left(90)
forward(3*n)
color("orange", "yellow")
begin_fill()
left(126)
for i in range(5):
forward(n/5)
right(144)
forward(n/5)
left(72)
end_fill()
right(126)
color("dark green")
backward(n*4.8)
def tree(d, s):
if d <= 0: return
forward(s)
tree(d-1, s*.8)
right(120)
tree(d-3, s*.5)
right(120)
tree(d-3, s*.5)
right(120)
backward(s)
tree(15, n)
backward(n/2)
import time
time.sleep(60)
n is the size parameter, the shown tree is for n=50. Takes a minute or two to draw.
JavaScript
Show the animated tree online.
var size = 400;
var canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
var p3d = [];
var p = [Math.random(), Math.random(), Math.random(), 0];
for (var i = 0; i < 100000; i++) {
p3d.push([p[0],p[1],p[2],p[3]]);
var t = Math.random();
if (t<0.4) {
_y = 0.4 * p[1];
_x = 0.1 * p[0];
_z = 0.6 * p[2];
var r = Math.floor(3*t/0.4)/3.0;
var rc = Math.cos(Math.PI*2.0*r);
var rs = Math.sin(Math.PI*2.0*r);
p[1] = _x+0.1*r+0.5*_y*_y;
p[0] = _y*rc+_z*rs;
p[2] = _z*rc-_y*rs;
p[3] = 0.2*t + 0.8*p[3];
} else {
p[1] = 0.2 + 0.8*p[1];
p[0] = 0.8 * p[0];
p[2] = 0.8 * p[2];
p[3] = 0.2 + 0.8*p[3];
}
}
var rot = 0.0;
function render() {
rot = rot + 0.1;
var rc = Math.cos(rot);
var rs = Math.sin(rot);
ctx.strokeStyle='#FF7F00';
ctx.lineWidth=2;
ctx.beginPath();
ctx.moveTo(size/2,size/8);
ctx.lineTo(size/2,size*15/16);
ctx.stroke();
var img = ctx.getImageData(0, 0, size, size);
for (var j = 0; j < size*size; j++) {
img.data[4*j+0] = 0.5*img.data[4*j+0];
img.data[4*j+1] = 0.5*img.data[4*j+1];
img.data[4*j+2] = 0.5*img.data[4*j+2];
img.data[4*j+3] = 255;
}
for (var i = 0; i < p3d.length; i++) {
var px = p3d[i][0];
var py = 0.5 - p3d[i][1];
var pz = p3d[i][2];
var col = Math.floor(128.0*p3d[i][3]);
var _x = rc*px + rs*pz;
var _z = rc*pz - rs*px;
var z = 3.0 * size / (_z + 4.0);
var x = size / 2 + Math.round(_x * z);
var y = size / 2 + Math.round(py * z);
if(x>=0&&y>=0&&x<size&&y<size) {
img.data[4 * (y * size + x) + 0] = col;
img.data[4 * (y * size + x) + 1] = 128+col;
img.data[4 * (y * size + x) + 2] = col;
img.data[4 * (y * size + x) + 3] = 255;
}
}
ctx.putImageData(img, 0, 0);
}
setInterval(render, 1000 / 30);
Yet another Mathematica / Wolfram Language tree based on Vitaliy's answer:
PD = .5;
s[t_, f_] := t^.6 - f
dt[cl_, ps_, sg_, hf_, dp_, f_, flag_] :=
Module[{sv, basePt},
{PointSize[ps],
sv = s[t, f];
Hue[cl (1 + Sin[.02 t])/2, 1, .3 + sg .3 Sin[hf sv]],
basePt = {-sg s[t, f] Sin[sv], -sg s[t, f] Cos[sv], dp + sv};
Point[basePt],
If[flag,
{Hue[cl (1 + Sin[.1 t])/2, 1, .6 + sg .4 Sin[hf sv]], PointSize[RandomReal[.01]],
Point[basePt + 1/2 RotationTransform[20 sv, {-Cos[sv], Sin[sv], 0}][{Sin[sv], Cos[sv], 0}]]},
{}]
}]
frames = ParallelTable[
Graphics3D[Table[{
dt[1, .01, -1, 1, 0, f, True], dt[.45, .01, 1, 1, 0, f, True],
dt[1, .005, -1, 4, .2, f, False], dt[.45, .005, 1, 4, .2, f, False]},
{t, 0, 200, PD}],
ViewPoint -> Left, BoxRatios -> {1, 1, 1.3},
ViewVertical -> {0, 0, -1},
ViewCenter -> {{0.5, 0.5, 0.5}, {0.5, 0.55}}, Boxed -> False,
PlotRange -> {{-20, 20}, {-20, 20}, {0, 20}}, Background -> Black],
{f, 0, 1, .01}];
Export["tree.gif", frames]