Pythagorean Tree - draw a PTree using HTML5 canvas
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
</head> | |
<body> | |
<canvas id="ptcanvas" width="400" height="400" style="border:1px dotted;float:left"></canvas> | |
<script> | |
function draw_square( ctx, x1, y1, x2, y2, x3, y3, x4, y4 ) | |
{ | |
ctx.beginPath( ) ; | |
ctx.moveTo( x1, y1 ) ; | |
ctx.lineTo( x2, y2 ) ; | |
ctx.lineTo( x3, y3 ) ; | |
ctx.lineTo( x4, y4 ) ; | |
ctx.lineTo( x1, y1 ) ; | |
ctx.fill( ) ; | |
ctx.closePath( ) ; | |
} | |
// Squares should always have vertices 1 and 4 as the base, with 1 always being the left of the base. | |
// The base of a child square is the one sitting on the isosceles right triangle formed with the parent. | |
// For example, the left child's 1 and 4 vertices match up with the 2 vertex of the parent | |
// and the top of the isosceles triangle. The right child's 1 and 4 are the top of the | |
// triangle and vertex 3 of the parent. | |
// /\ | |
// / \ <-- bases of children, the rays (1-2 and 4-3) calculated below shoot up to form the diagonal of the child | |
// 2 -- 3 | |
// | | | |
// 1 -- 4 | |
function recurse_tree( ctx, x1, y1, x3, y3, swap, level, MAXLEVEL ) | |
{ | |
// TRUNK | |
var xc, xd, x2, y2, x4, y4 ; | |
xc = (x1 + x3)/2.0 ; yc = (y1 + y3)/2.0 ; // center point of square - credit to http://math.stackexchange.com/a/506853 | |
xd = (x1 - x3)/2.0 ; yd = (y1 - y3)/2.0 ; // rays representing the half-diagonals | |
x2 = xc - yd ; y2 = yc + xd ; // corner 2 | |
x4 = xc + yd ; y4 = yc - xd ; // corner 4 | |
if( swap ) // this was the "rightward" child (base formed by top and vertex 3 above), | |
// meaning the 1 & 3 points passed should actually be 4 & 2 so the diagonal is the correct one: | |
// the "leftward" child's diagonal goes from its 1 to 3 vertex and is formed from the parent's 1->2 ray, | |
// so the "rightward" child must be adjusted so the diagonal runs 1->3 similarly instead of between 4->2 | |
{ | |
var tx = x4 ; var ty = y4 ; | |
x4 = x1 ; y4 = y1 ; | |
x1 = x2 ; y1 = y2 ; | |
x2 = x3 ; y2 = y3 ; | |
x3 = tx ; y3 = ty ; | |
} | |
draw_square( ctx, x1, y1, x2, y2, x3, y3, x4, y4 ) ; | |
// only draw the leaves if we need to go another level deeper | |
level++; | |
if( level >= MAXLEVEL ) | |
return ; | |
// LEAVES | |
// draw these by shooting rays from the two base corners in the direction of the child to form their hypotenuses | |
// the child hypotenuses are the same length as the sides of the parent | |
var rayX = x2-x1 ; var rayY = y2-y1 ; | |
recurse_tree( ctx, x2, y2, x2+rayX, y2+rayY, false, level, MAXLEVEL ) ; | |
var rayX = x3-x4 ; var rayY = y3-y4 ; | |
// this diagonal is the wrong diagonal based on the assumption of the function, set swap to true to switch them; see if comment above | |
recurse_tree( ctx, x3, y3, x3+rayX, y3+rayY, true, level, MAXLEVEL) ; | |
} | |
// (x,y) is the base of the square, the BOTTOM side | |
function draw_pythagoras_tree( canvas, x, y, slength, maxLevel ) | |
{ | |
var ctx = canvas.getContext( "2d" ) ; | |
ctx.fillStyle = "#FF0000" ; | |
recurse_tree( ctx, x, y, x+slength, y-slength, false, 0, maxLevel ) ; | |
} | |
draw_pythagoras_tree( document.getElementById( "ptcanvas" ), 175, 350, 50, 12 ) ; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment