This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,6 @@
Generate and draw a fractal tree.
To draw a fractal tree is simple:
# Draw the trunk
# At the end of the trunk, split by some angle and draw two branches
# Repeat at the end of each branch until a sufficient level of branching is reached

View file

@ -0,0 +1,7 @@
---
category:
- Raster graphics operations
- Recursion
note: Fractals
requires:
- Graphics

View file

@ -0,0 +1,45 @@
graphsize 300,300
level = 12 : len =63 # initial values
x = 230: y = 285
rotation = pi/2
A1 = pi/27 : A2 = pi/8 # constants which determine shape
C1 = 0.7 : C2 = 0.85
dim xs(level+1) : dim ys(level+1) # stacks
fastgraphics
color black
rect 0,0,graphwidth,graphheight
refresh
color green
gosub tree
refresh
imgsave "Fractal_tree_BASIC-256.png", "PNG"
end
tree:
xs[level] = x : ys[level] = y
gosub putline
if level>0 then
level = level - 1
len = len*C1
rotation = rotation - A1
gosub tree
len = len/C1*C2
rotation = rotation + A1 + A2
gosub tree
rotation = rotation - A2
len = len/C2
level = level + 1
end if
x = xs[level] : y = ys[level]
return
putline:
yn = -sin(rotation)*len + y
xn = cos(rotation)*len + x
line x,y,xn,yn
x = xn : y = yn
return

View file

@ -0,0 +1,22 @@
Spread = 25
Scale = 0.76
SizeX% = 400
SizeY% = 300
Depth% = 10
VDU 23,22,SizeX%;SizeY%;8,16,16,128
PROCbranch(SizeX%, 0, SizeY%/2, 90, Depth%)
END
DEF PROCbranch(x1, y1, size, angle, depth%)
LOCAL x2, y2
x2 = x1 + size * COSRAD(angle)
y2 = y1 + size * SINRAD(angle)
VDU 23,23,depth%;0;0;0;
LINE x1, y1, x2, y2
IF depth% > 0 THEN
PROCbranch(x2, y2, size * Scale, angle - Spread, depth% - 1)
PROCbranch(x2, y2, size * Scale, angle + Spread, depth% - 1)
ENDIF
ENDPROC

View file

@ -0,0 +1,101 @@
#include <SDL/SDL.h>
#ifdef WITH_CAIRO
#include <cairo.h>
#else
#include <SDL/sge.h>
#endif
#include <cairo.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#ifdef WITH_CAIRO
#define PI 3.1415926535
#endif
#define SIZE 800 // determines size of window
#define SCALE 5 // determines how quickly branches shrink (higher value means faster shrinking)
#define BRANCHES 14 // number of branches
#define ROTATION_SCALE 0.75 // determines how slowly the angle between branches shrinks (higher value means slower shrinking)
#define INITIAL_LENGTH 50 // length of first branch
double rand_fl(){
return (double)rand() / (double)RAND_MAX;
}
void draw_tree(SDL_Surface * surface, double offsetx, double offsety,
double directionx, double directiony, double size,
double rotation, int depth) {
#ifdef WITH_CAIRO
cairo_surface_t *surf = cairo_image_surface_create_for_data( surface->pixels,
CAIRO_FORMAT_RGB24,
surface->w, surface->h,
surface->pitch );
cairo_t *ct = cairo_create(surf);
cairo_set_line_width(ct, 1);
cairo_set_source_rgba(ct, 0,0,0,1);
cairo_move_to(ct, (int)offsetx, (int)offsety);
cairo_line_to(ct, (int)(offsetx + directionx * size), (int)(offsety + directiony * size));
cairo_stroke(ct);
#else
sge_AALine(surface,
(int)offsetx, (int)offsety,
(int)(offsetx + directionx * size), (int)(offsety + directiony * size),
SDL_MapRGB(surface->format, 0, 0, 0));
#endif
if (depth > 0){
// draw left branch
draw_tree(surface,
offsetx + directionx * size,
offsety + directiony * size,
directionx * cos(rotation) + directiony * sin(rotation),
directionx * -sin(rotation) + directiony * cos(rotation),
size * rand_fl() / SCALE + size * (SCALE - 1) / SCALE,
rotation * ROTATION_SCALE,
depth - 1);
// draw right branch
draw_tree(surface,
offsetx + directionx * size,
offsety + directiony * size,
directionx * cos(-rotation) + directiony * sin(-rotation),
directionx * -sin(-rotation) + directiony * cos(-rotation),
size * rand_fl() / SCALE + size * (SCALE - 1) / SCALE,
rotation * ROTATION_SCALE,
depth - 1);
}
}
void render(SDL_Surface * surface){
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255));
draw_tree(surface,
surface->w / 2.0,
surface->h - 10.0,
0.0, -1.0,
INITIAL_LENGTH,
PI / 8,
BRANCHES);
SDL_UpdateRect(surface, 0, 0, 0, 0);
}
int main(){
SDL_Surface * screen;
SDL_Event evt;
SDL_Init(SDL_INIT_VIDEO);
srand((unsigned)time(NULL));
screen = SDL_SetVideoMode(SIZE, SIZE, 32, SDL_HWSURFACE);
render(screen);
while(1){
if (SDL_PollEvent(&evt)){
if(evt.type == SDL_QUIT) break;
}
SDL_Delay(1);
}
SDL_Quit();
return 0;
}

View file

@ -0,0 +1,26 @@
(import '[java.awt Color Graphics]
'javax.swing.JFrame)
(defn deg-to-radian [deg] (* deg Math/PI 1/180))
(defn cos-deg [angle] (Math/cos (deg-to-radian angle)))
(defn sin-deg [angle] (Math/sin (deg-to-radian angle)))
(defn draw-tree [^Graphics g, x y angle depth]
(when (pos? depth)
(let [x2 (+ x (int (* depth 10 (cos-deg angle))))
y2 (+ y (int (* depth 10 (sin-deg angle))))]
(.drawLine g x y x2 y2)
(draw-tree g x2 y2 (- angle 20) (dec depth))
(recur g x2 y2 (+ angle 20) (dec depth)))))
(defn fractal-tree [depth]
(doto (proxy [JFrame] []
(paint [g]
(.setColor g Color/BLACK)
(draw-tree g 400 500 -90 depth)))
(.setBounds 100 100 800 600)
(.setResizable false)
(.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
(.show)))
(fractal-tree 9)

View file

@ -0,0 +1,43 @@
import dfl.all;
import std.math;
class FractalTree: Form {
private const double DEG_TO_RAD = PI / 180.0;
this() {
width = 600;
height = 500;
text = "Fractal Tree";
backColor = Color(0xFF, 0xFF, 0xFF);
startPosition = FormStartPosition.CENTER_SCREEN;
formBorderStyle = FormBorderStyle.FIXED_DIALOG;
maximizeBox = false;
}
private void drawTree(Graphics g, Pen p, int x1, int y1, double angle, int depth) {
if (depth == 0) return;
int x2 = x1 + cast(int) (cos(angle * DEG_TO_RAD) * depth * 10.0);
int y2 = y1 + cast(int) (sin(angle * DEG_TO_RAD) * depth * 10.0);
g.drawLine(p, x1, y1, x2, y2);
drawTree(g, p, x2, y2, angle - 20, depth - 1);
drawTree(g, p, x2, y2, angle + 20, depth - 1);
}
protected override void onPaint(PaintEventArgs ea){
super.onPaint(ea);
Pen p = new Pen(Color(0, 0xAA, 0));
drawTree(ea.graphics, p, 300, 450, -90, 9);
}
}
int main() {
int result = 0;
try {
Application.run(new FractalTree);
} catch(Object o) {
msgBox(o.toString(), "Fatal Error", MsgBoxButtons.OK, MsgBoxIcon.ERROR);
result = 1;
}
return result;
}

View file

@ -0,0 +1,35 @@
using fwt
using gfx
class FractalCanvas : Canvas
{
new make () : super() {}
Void drawTree (Graphics g, Int x1, Int y1, Int angle, Int depth)
{
if (depth == 0) return
Int x2 := x1 + (angle.toFloat.toRadians.cos * depth * 10.0).toInt;
Int y2 := y1 + (angle.toFloat.toRadians.sin * depth * 10.0).toInt;
g.drawLine(x1, y1, x2, y2);
drawTree(g, x2, y2, angle - 20, depth - 1);
drawTree(g, x2, y2, angle + 20, depth - 1);
}
override Void onPaint (Graphics g)
{
drawTree (g, 400, 500, -90, 9)
}
}
class FractalTree
{
public static Void main ()
{
Window
{
title = "Fractal Tree"
size = Size(800, 600)
FractalCanvas(),
}.open
}
}

View file

@ -0,0 +1,37 @@
package main
// Files required to build supporting package raster are found in:
// * Bitmap
// * Grayscale image
// * Xiaolin Wu's line algorithm
// * Write a PPM file
import (
"math"
"raster"
)
const (
width = 400
height = 300
depth = 8
angle = 12
length = 50
frac = .8
)
func main() {
g := raster.NewGrmap(width, height)
ftree(g, width/2, height*9/10, length, 0, depth)
g.Bitmap().WritePpmFile("ftree.ppm")
}
func ftree(g *raster.Grmap, x, y, distance, direction float64, depth int) {
x2 := x + distance*math.Sin(direction*math.Pi/180)
y2 := y - distance*math.Cos(direction*math.Pi/180)
g.AaLine(x, y, x2, y2)
if depth > 0 {
ftree(g, x2, y2, distance*frac, direction-angle, depth-1)
ftree(g, x2, y2, distance*frac, direction+angle, depth-1)
}
}

View file

@ -0,0 +1,29 @@
import Graphics.HGL.Window
import Graphics.HGL.Run
import Control.Arrow
import Control.Monad
import Data.List
enumBase :: Int -> Int -> [[Int]]
enumBase n = mapM (enumFromTo 0). replicate n. pred
psPlus (a,b) (p,q) = (a+p, b+q)
toInt :: Double -> Int
toInt = fromIntegral.round
intPoint = toInt *** toInt
pts n =
map (map (intPoint.psPlus (100,0)). ((0,300):). scanl1 psPlus. ((r,300):). zipWith (\h a -> (h*cos a, h*sin a)) rs) hs
where
[r,h,sr,sh] = [50, pi/5, 0.9, 0.75]
rs = take n $ map (r*) $ iterate(*sr) sr
lhs = map (map (((-1)**).fromIntegral)) $ enumBase n 2
rhs = take n $ map (h*) $ iterate(*sh) 1
hs = map (scanl1 (+). zipWith (*)rhs) lhs
fractalTree :: Int -> IO ()
fractalTree n =
runWindow "Fractal Tree" (500,600)
(\w -> setGraphic w (overGraphics ( map polyline $ pts (n-1))) >> getKey w)

View file

@ -0,0 +1,18 @@
procedure main()
WOpen("size=800,600", "bg=black", "fg=white") | stop("*** cannot open window")
drawtree(400,500,-90,9)
WDone()
end
link WOpen
procedure drawtree(x,y,angle,depth)
if depth > 0 then {
x2 := integer(x + cos(dtor(angle)) * depth * 10)
y2 := integer(y + sin(dtor(angle)) * depth * 10)
DrawLine(x,y,x2,y2)
drawtree(x2,y2,angle-20, depth-1)
drawtree(x2,y2,angle+20, depth-1)
}
return
end

View file

@ -0,0 +1,24 @@
require'gl2'
L0=: 50 NB. initial length
A0=: 1r8p1 NB. initial angle: pi divided by 8
dL=: 0.9 NB. shrink factor for length
dA=: 0.75 NB. shrink factor for angle
N=: 14 NB. number of branches
L=: L0*dL^1+i.N NB. lengths of line segments
NB. relative angles of successive line segments
A=: A0*(dA^i.N) +/\@:*("1) _1 ^ #:i.2 ^ N
NB. end points for each line segment
P=: 0 0+/\@,"2 +.*.inv (L0,0),"2 L,"0"1 A
P_C_paint=: gllines_jgl2_ bind (10 + ,/"2 P-"1<./,/P)
wd 0 :0
pc P closeok;
xywh 0 0 250 300;
cc C isigraph rightmove bottommove;
pas 0 0;
pshow;
)

View file

@ -0,0 +1,32 @@
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class FractalTree extends JFrame {
public FractalTree() {
super("Fractal Tree");
setBounds(100, 100, 800, 600);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void drawTree(Graphics g, int x1, int y1, double angle, int depth) {
if (depth == 0) return;
int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 10.0);
int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 10.0);
g.drawLine(x1, y1, x2, y2);
drawTree(g, x2, y2, angle - 20, depth - 1);
drawTree(g, x2, y2, angle + 20, depth - 1);
}
@Override
public void paint(Graphics g) {
g.setColor(Color.BLACK);
drawTree(g, 400, 500, -90, 9);
}
public static void main(String[] args) {
new FractalTree().setVisible(true);
}
}

View file

@ -0,0 +1,33 @@
<html>
<body>
<canvas id="canvas" width="600" height="500"></canvas>
<script type="text/javascript">
var elem = document.getElementById('canvas');
var context = elem.getContext('2d');
context.fillStyle = '#000';
context.lineWidth = 1;
var deg_to_rad = Math.PI / 180.0;
var depth = 9;
function drawLine(x1, y1, x2, y2, brightness){
context.moveTo(x1, y1);
context.lineTo(x2, y2);
}
function drawTree(x1, y1, angle, depth){
if (depth != 0){
var x2 = x1 + (Math.cos(angle * deg_to_rad) * depth * 10.0);
var y2 = y1 + (Math.sin(angle * deg_to_rad) * depth * 10.0);
drawLine(x1, y1, x2, y2, depth);
drawTree(x2, y2, angle - 20, depth - 1);
drawTree(x2, y2, angle + 20, depth - 1);
}
}
context.beginPath();
drawTree(300, 500, -90, depth);
context.closePath();
context.stroke();
</script>
</body>
</html>

View file

@ -0,0 +1,36 @@
NoMainWin
sw = 640 : sh = 480
WindowWidth = sw+8 : WindowHeight = sh+31
UpperLeftX = (DisplayWidth -sw)/2
UpperLeftY = (DisplayHeight-sh)/2
Open"Fractal Tree" For Graphics_nf_nsb As #g
#g "Down; Color darkgreen; TrapClose halt"
h$ = "#g"
'initial assignments
initAngle = Acs(-1)*1.5 'radian equivalent of 270 degrees
theta = 29 * (Acs(-1)/180) 'convert 29 degrees to radians
length = 110 'length in pixels
depth = 25 'max recursion depth
'draw the tree
Call tree h$, 320, 470, initAngle, theta, length, depth
#g "Flush; when leftButtonDown halt" 'L-click to exit
Wait
Sub halt handle$
Close #handle$
End
End Sub
Sub tree h$, x, y, initAngle, theta, length, depth
Scan
newX = Cos(initAngle) * length + x
newY = Sin(initAngle) * length + y
#h$ "Line ";x;" ";y;" ";newX;" ";newY
length = length * .78
depth = depth - 1
If depth > 0 Then
Call tree h$, newX, newY, initAngle-theta, theta, length, depth
Call tree h$, newX, newY, initAngle+theta, theta, length, depth
End If
End Sub

View file

@ -0,0 +1,14 @@
to tree :depth :length :scale :angle
if :depth=0 [stop]
setpensize round :depth/2
forward :length
right :angle
tree :depth-1 :length*:scale :scale :angle
left 2*:angle
tree :depth-1 :length*:scale :scale :angle
right :angle
back :length
end
clearscreen
tree 10 80 0.7 30

View file

@ -0,0 +1,17 @@
fractalTree[
pt : {_, _}, \[Theta]orient_: \[Pi]/2, \[Theta]sep_: \[Pi]/9,
depth_Integer: 9] := Module[{pt2},
If[depth == 0, Return[]];
pt2 = pt + {Cos[\[Theta]orient], Sin[\[Theta]orient]}*depth;
DeleteCases[
Flatten@{
Line[{pt, pt2}],
fractalTree[pt2, \[Theta]orient - \[Theta]sep, \[Theta]sep,
depth - 1],
fractalTree[pt2, \[Theta]orient + \[Theta]sep, \[Theta]sep,
depth - 1]
},
Null
]
]
Graphics[fractalTree[{0, 0}, \[Pi]/2, \[Pi]/9]]

View file

@ -0,0 +1,30 @@
<?php
header("Content-type: image/png");
$width = 512;
$height = 512;
$img = imagecreatetruecolor($width,$height);
$bg = imagecolorallocate($img,255,255,255);
imagefilledrectangle($img, 0, 0, $width, $width, $bg);
$depth = 8;
function drawTree($x1, $y1, $angle, $depth){
global $img;
if ($depth != 0){
$x2 = $x1 + (int)(cos(deg2rad($angle)) * $depth * 10.0);
$y2 = $y1 + (int)(sin(deg2rad($angle)) * $depth * 10.0);
imageline($img, $x1, $y1, $x2, $y2, imagecolorallocate($img,0,0,0));
drawTree($x2, $y2, $angle - 20, $depth - 1);
drawTree($x2, $y2, $angle + 20, $depth - 1);
}
}
drawTree($width/2, $height, -90, $depth);
imagepng($img);
imagedestroy($img);
?>

View file

@ -0,0 +1,30 @@
use GD::Simple;
my ($width, $height) = (1000,1000); # image dimension
my $scale = 6/10; # branch scale relative to trunk
my $length = 400; # trunk size
my $img = GD::Simple->new($width,$height);
$img->fgcolor('black');
$img->penSize(1,1);
tree($width/2, $height, $length, 270);
print $img->png;
sub tree
{
my ($x, $y, $len, $angle) = @_;
return if $len < 1;
$img->moveTo($x,$y);
$img->angle($angle);
$img->line($len);
($x, $y) = $img->curPos();
tree($x, $y, $len*$scale, $angle+35);
tree($x, $y, $len*$scale, $angle-35);
}

View file

@ -0,0 +1,15 @@
(load "@lib/math.l")
(de fractalTree (Img X Y A D)
(unless (=0 D)
(let (R (*/ A pi 180.0) DX (*/ (cos R) D 0.2) DY (*/ (sin R) D 0.2))
(brez Img X Y DX DY)
(fractalTree Img (+ X DX) (+ Y DY) (+ A 30.0) (dec D))
(fractalTree Img (+ X DX) (+ Y DY) (- A 30.0) (dec D)) ) ) )
(let Img (make (do 300 (link (need 400 0)))) # Create image 400 x 300
(fractalTree Img 200 300 -90.0 10) # Draw tree
(out "img.pbm" # Write to bitmap file
(prinl "P1")
(prinl 400 " " 300)
(mapc prinl Img) ) )

View file

@ -0,0 +1,19 @@
fractal :-
new(D, window('Fractal')),
send(D, size, size(800, 600)),
drawTree(D, 400, 500, -90, 9),
send(D, open).
drawTree(_D, _X, _Y, _Angle, 0).
drawTree(D, X1, Y1, Angle, Depth) :-
X2 is X1 + cos(Angle * pi / 180.0) * Depth * 10.0,
Y2 is Y1 + sin(Angle * pi / 180.0) * Depth * 10.0,
new(Line, line(X1, Y1, X2, Y2, none)),
send(D, display, Line),
A1 is Angle - 30,
A2 is Angle + 30,
De is Depth - 1,
drawTree(D, X2, Y2, A1, De),
drawTree(D, X2, Y2, A2, De).

View file

@ -0,0 +1,23 @@
import pygame, math
pygame.init()
window = pygame.display.set_mode((600, 600))
pygame.display.set_caption("Fractal Tree")
screen = pygame.display.get_surface()
def drawTree(x1, y1, angle, depth):
if depth:
x2 = x1 + int(math.cos(math.radians(angle)) * depth * 10.0)
y2 = y1 + int(math.sin(math.radians(angle)) * depth * 10.0)
pygame.draw.line(screen, (255,255,255), (x1, y1), (x2, y2), 2)
drawTree(x2, y2, angle - 20, depth - 1)
drawTree(x2, y2, angle + 20, depth - 1)
def input(event):
if event.type == pygame.QUIT:
exit(0)
drawTree(300, 550, -90, 9)
pygame.display.flip()
while True:
input(pygame.event.wait())

View file

@ -0,0 +1,19 @@
Shoes.app(:title => "Fractal Tree", :width => 600, :height => 600) do
background "#fff"
stroke "#000"
@deg_to_rad = Math::PI / 180.0
def drawTree(x1, y1, angle, depth)
if depth != 0
x2 = x1 + (Math.cos(angle * @deg_to_rad) * depth * 10.0).to_i
y2 = y1 + (Math.sin(angle * @deg_to_rad) * depth * 10.0).to_i
line x1, y1, x2, y2
drawTree(x2, y2, angle - 20, depth - 1)
drawTree(x2, y2, angle + 20, depth - 1)
end
end
drawTree(300,550,-90,9)
end

View file

@ -0,0 +1,31 @@
import swing._
import java.awt.{RenderingHints, BasicStroke, Color}
object FractalTree extends SimpleSwingApplication {
val DEPTH = 9
def top = new MainFrame {
contents = new Panel {
preferredSize = new Dimension(600, 500)
override def paintComponent(g: Graphics2D) {
draw(300, 460, -90, DEPTH)
def draw(x1: Int, y1: Int, angle: Double, depth: Int) {
if (depth > 0) {
val x2 = x1 + (math.cos(angle.toRadians) * depth * 10).toInt
val y2 = y1 + (math.sin(angle.toRadians) * depth * 10).toInt
g.setColor(Color.getHSBColor(0.25f - depth * 0.125f / DEPTH, 0.9f, 0.6f))
g.setStroke(new BasicStroke(depth))
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g.drawLine(x1, y1, x2, y2)
draw(x2, y2, angle - 20, depth - 1)
draw(x2, y2, angle + 20, depth - 1)
}
}
}
}
}
}

View file

@ -0,0 +1,32 @@
package require Tk
set SIZE 800
set SCALE 4.0
set BRANCHES 14
set ROTATION_SCALE 0.85
set INITIAL_LENGTH 50.0
proc draw_tree {w x y dx dy size theta depth} {
global SCALE ROTATION_SCALE
$w create line $x $y [expr {$x + $dx*$size}] [expr {$y + $dy*$size}]
if {[incr depth -1] >= 0} {
set x [expr {$x + $dx*$size}]
set y [expr {$y + $dy*$size}]
set ntheta [expr {$theta * $ROTATION_SCALE}]
# Draw left branch
draw_tree $w $x $y \
[expr {$dx*cos($theta) + $dy*sin($theta)}] \
[expr {$dy*cos($theta) - $dx*sin($theta)}] \
[expr {$size * (rand() + $SCALE - 1) / $SCALE}] $ntheta $depth
# Draw right branch
draw_tree $w $x $y \
[expr {$dx*cos(-$theta) + $dy*sin(-$theta)}] \
[expr {$dy*cos(-$theta) - $dx*sin(-$theta)}] \
[expr {$size * (rand() + $SCALE - 1) / $SCALE}] $ntheta $depth
}
}
pack [canvas .c -width $SIZE -height $SIZE]
draw_tree .c [expr {$SIZE/2}] [expr {$SIZE-10}] 0.0 -1.0 $INITIAL_LENGTH \
[expr {3.1415927 / 8}] $BRANCHES