00001
00002
00003
00004 from __future__ import division
00005
00006 from math import pi
00007 from math import cos
00008 from math import sin
00009 from math import log
00010 from math import ceil
00011
00012 from enhanced_grid import Grid2D
00013 from image import greyscale_grid_to_rgb_grid
00014 from image import grid_to_rgb_image
00015 from perlin_noise import SmoothNoise1D
00016 from perlin_noise import perlin_noise_from_smoothnoise_1d
00017
00018 TWO_PI = 2 * pi
00019 LOG2 = log(2)
00020
00021
00022 def draw_circle(grid, centre, radius):
00023 circumference = TWO_PI * radius
00024 power = ceil(log(circumference) / LOG2)
00025 sample_count = pow(2, power)
00026 print sample_count
00027 x0, y0 = centre
00028
00029 for i in range(sample_count):
00030 angle = i / sample_count * TWO_PI
00031
00032 x = int(x0 + radius * cos(angle))
00033 y = int(y0 + radius * sin(angle))
00034
00035 grid[x,y] = 1
00036
00037
00038 def draw_ellipse(grid, centre, radius1, radius2, theta):
00039 circumference = pi * (radius1 + radius2)
00040 power = ceil(log(circumference) / LOG2)
00041 sample_count = pow(2, power)
00042 print sample_count
00043 x0, y0 = centre
00044
00045 sintheta = sin(theta)
00046 costheta = cos(theta)
00047
00048 for i in range(sample_count):
00049 angle = i / sample_count * TWO_PI
00050 cosangle = cos(angle)
00051 sinangle = sin(angle)
00052
00053 x = int(x0 + radius1 * cosangle*costheta - radius2*sinangle*sintheta)
00054 y = int(y0 + radius2 * sinangle*costheta + radius1*cosangle*sintheta)
00055
00056 grid[x,y] = 1
00057
00058
00059 def draw_perlin_ellipse(grid, centre, radius1, radius2, theta, displacement, noise=None):
00060
00061 x0, y0 = centre
00062
00063 if noise == None:
00064 circumference = TWO_PI * (radius1 + radius2 + displacement)
00065 power = ceil(log(circumference) / LOG2)
00066 sample_count = int(pow(2, power))
00067 print sample_count
00068 smooth_noise = SmoothNoise1D(sample_count)
00069 noise = perlin_noise_from_smoothnoise_1d(sample_count, 8, 0.5, smooth_noise)
00070 else:
00071 sample_count = len(noise)
00072
00073 sintheta = sin(theta)
00074 costheta = cos(theta)
00075
00076 for i in range(sample_count):
00077 angle = i / sample_count * TWO_PI
00078 cosangle = cos(angle)
00079 sinangle = sin(angle)
00080
00081 displaced_radius1 = radius1 + displacement*noise[i];
00082 displaced_radius2 = radius2 + displacement*noise[i];
00083
00084
00085 x = int(x0 + displaced_radius1 * cosangle*costheta - displaced_radius2 * sinangle*sintheta)
00086 y = int(y0 + displaced_radius2 * sinangle*costheta + displaced_radius1 * cosangle*sintheta)
00087
00088 grid[x,y] = 1
00089
00090
00091 def draw_perlin_circle(grid, centre, radius, displacement, noise=None):
00092 circumference = TWO_PI * (radius + 2*displacement)
00093 power = ceil(log(circumference) / LOG2)
00094 sample_count = int(pow(2, power))
00095
00096 x0, y0 = centre
00097 if noise == None:
00098 smooth_noise = SmoothNoise1D(sample_count)
00099 noise = perlin_noise_from_smoothnoise_1d(sample_count, 8, 0.5, smooth_noise)
00100
00101 for i in range(sample_count):
00102 angle = i / sample_count * TWO_PI
00103 displaced_radius = radius + displacement*noise[i]
00104 x = int(x0 + displaced_radius * cos(angle))
00105 y = int(y0 + displaced_radius * sin(angle))
00106
00107 grid[x,y] = 1
00108
00109
00110 def draw_circle_tree(grid, centre, radius, levels, branches):
00111 draw_circle(grid, centre, radius)
00112 x0, y0 = centre
00113 if levels > 1:
00114 for i in range(branches):
00115 angle = i * TWO_PI / branches
00116 x = x0 + radius * cos(angle)
00117 y = y0 + radius * sin(angle)
00118 draw_circle_tree(grid, (x, y), 0.4 * radius, levels - 1, branches)
00119
00120
00121 def draw_perlin_circle_tree(grid, centre, radius, levels, branches, subradius=None):
00122 displacement = radius
00123 if subradius == None:
00124 subradius = radius
00125 circumference = TWO_PI * (radius + 2*displacement)
00126 power = ceil(log(circumference) / LOG2)
00127 sample_count = int(pow(2, power))
00128
00129 smooth_noise = SmoothNoise1D(sample_count)
00130 noise = perlin_noise_from_smoothnoise_1d(sample_count, 8, 0.5, smooth_noise)
00131
00132 draw_perlin_circle(grid, centre, radius, displacement, noise)
00133 x0, y0 = centre
00134 if levels > 1:
00135 for i in range(branches):
00136 angle = i * TWO_PI / branches
00137 displaced_radius = subradius + displacement*noise[i*sample_count//branches]
00138
00139 x = x0 + displaced_radius * cos(angle)
00140 y = y0 + displaced_radius * sin(angle)
00141 draw_perlin_circle_tree(grid, (x, y), 0.4 * radius, levels - 1, branches, 0.4*subradius)
00142
00143
00144 def draw_perlin_ellipse_tree(grid, centre, radius1, radius2, theta, displacement, levels, branches, innerfactor=None):
00145 if innerfactor == None:
00146 innerfactor = 1
00147
00148 subradius1 = radius1 * innerfactor
00149 subradius2 = radius2 * innerfactor
00150
00151 sintheta = sin(theta)
00152 costheta = cos(theta)
00153
00154 circumference = 2 * pi * (radius1 + radius2 + displacement)
00155 power = ceil(log(circumference) / LOG2)
00156 sample_count = int(pow(2, power))
00157
00158 smooth_noise = SmoothNoise1D(sample_count)
00159 noise = perlin_noise_from_smoothnoise_1d(sample_count, 8, 0.5, smooth_noise)
00160
00161 draw_perlin_ellipse(grid, centre, radius1, radius2, theta, displacement, noise)
00162 draw_ellipse(grid, centre, radius1, radius2, theta)
00163
00164 x0, y0 = centre
00165 if levels > 1:
00166 for i in range(branches):
00167 angle = i * TWO_PI / branches
00168 noise_index = i*sample_count//branches
00169 cosangle = cos(angle)
00170 sinangle = sin(angle)
00171
00172 displaced_radius1 = subradius1 + displacement*noise[noise_index];
00173 displaced_radius2 = subradius2 + displacement*noise[noise_index];
00174
00175 x = int(x0 + displaced_radius1 * cosangle*costheta - displaced_radius2 * sinangle*sintheta)
00176 y = int(y0 + displaced_radius2 * sinangle*costheta + displaced_radius1 * cosangle*sintheta)
00177
00178
00179 draw_perlin_ellipse_tree(grid, (x, y), 0.4 * radius1, 0.4 * radius2, theta, 0.4*displacement, levels - 1, branches, innerfactor)
00180
00181
00182 def demo_draw():
00183
00184 grid = Grid2D((600, 600), 0)
00185
00186 draw_perlin_ellipse_tree(grid, (300, 300), 100, 70, pi/4, 70, 3, 4, 0.8)
00187
00188 grid = greyscale_grid_to_rgb_grid(grid, [1, 1, 1, 1])
00189 grid_to_rgb_image(grid, 'draw/perlin_ellipse_tree.png')
00190
00191 demo_draw();