Last active
December 11, 2015 19:30
-
-
Save alexkuhl/caaa3c63020b980165eb to your computer and use it in GitHub Desktop.
Pythagorean Tree - draw a PTree using HTML5 canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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