SHOW:
|
|
- or go back to the newest paste.
1 | import Image | |
2 | import random | |
3 | import math | |
4 | import itertools | |
5 | import copy | |
6 | ||
7 | ||
8 | ||
9 | def line_pixels(ord1,ord2): | |
10 | # Bresenham's line algorithm | |
11 | # useful function for plotting a 2d line from 2 co-ordinates - ord1 to ord2 | |
12 | # ord1 and ord2 must be tuples in the form (x,y) | |
13 | ||
14 | x0 = int(ord1[0]); y0 = int(ord1[1]) | |
15 | x1 = int(ord2[0]); y1 = int(ord2[1]) | |
16 | dx = abs(x1 - x0) | |
17 | dy = abs(y1 - y0) | |
18 | x, y = x0, y0 | |
19 | sx = -1 if x0 > x1 else 1 | |
20 | sy = -1 if y0 > y1 else 1 | |
21 | ||
22 | pixlist = [(x0,y0)] | |
23 | if dx > dy: | |
24 | err = dx / 2.0 | |
25 | while x != x1: | |
26 | pixlist.append((x, y)) | |
27 | err -= dy | |
28 | if err < 0: | |
29 | y += sy | |
30 | err += dx | |
31 | x += sx | |
32 | else: | |
33 | err = dy / 2.0 | |
34 | while y != y1: | |
35 | pixlist.append((x, y)) | |
36 | err -= dx | |
37 | if err < 0: | |
38 | x += sx | |
39 | err += dy | |
40 | y += sy | |
41 | pixlist.append((x, y)) | |
42 | return pixlist | |
43 | ||
44 | ||
45 | i = 0 | |
46 | ||
47 | width = 26 # width/height/breadth of the" box" | |
48 | # (i.e, the number of discrete steps) | |
49 | ||
50 | hooke = 0.14444444 # a spring-like constant that scales down the force | |
51 | # on adjacent points in the field | |
52 | ||
53 | xsize, ysize = (400,400) # image size in pixels | |
54 | ||
55 | points = [[[[0.0,0.0] for x in xrange(width)] for y in xrange(width)] for z in xrange(width)] | |
56 | # nested lists representing a 3d field with values | |
57 | # at discrete points, accessible by "points[z][y][x]" | |
58 | ||
59 | ||
60 | for bbb in xrange(210000): | |
61 | ||
62 | ||
63 | im = Image.new("RGB",(xsize,ysize)) | |
64 | loadobject = im.load() | |
65 | ||
66 | ||
67 | for z0, l0 in enumerate(points): | |
68 | for y0, c0 in enumerate(l0): | |
69 | for x0, p0 in enumerate(c0): | |
70 | # a bunch of 3d-projection type stuff, projects the 3d | |
71 | # co-ordinate onto the 2d image plane, mess around with | |
72 | # the scale_factors and k_constant to work with larger fields/ | |
73 | # different levels of perspective | |
74 | scale_fact = 5 | |
75 | k_constant = 0.013 | |
76 | ||
77 | ||
78 | y1 = y0 - (width/2.0) | |
79 | x1 = (x0 - (width/2.0))*(1 + (k_constant*y1)) | |
80 | y1 += -(z0-width/2)*(1 + (k_constant*y1)) | |
81 | ||
82 | x1 *= scale_fact*1.5 | |
83 | y1 *= scale_fact | |
84 | ||
85 | x1 += (xsize/2) | |
86 | y1 += (ysize/2) | |
87 | ||
88 | x1 = int(x1) | |
89 | y1 = int(y1) | |
90 | ||
91 | try: | |
92 | """ | |
93 | these conditions determine whether a point is plotted | |
94 | depending on the displacement value of the field. the first | |
95 | 2 frames always contain the full cube plotted as a reference | |
96 | ||
97 | the second conditional means that only points in the | |
98 | field with values greater than positive 6 are plotted, | |
99 | negative values are ignored. | |
100 | """ | |
101 | if i > 2: | |
102 | if p0[0] < 6: | |
103 | continue | |
104 | ||
105 | scalecol = (100/width) | |
106 | ||
107 | col = (128+(y0*scalecol),128-(x0*scalecol),128-(z0*scalecol)) | |
108 | loadobject[x1,y1] = col | |
109 | loadobject[x1+1,y1] = col | |
110 | loadobject[x1-1,y1] = col | |
111 | loadobject[x1,y1+1] = col | |
112 | loadobject[x1,y1-1] = col | |
113 | except: | |
114 | pass | |
115 | ||
116 | # save the image and increment i | |
117 | im.save("test//TEST3_%05d.png" % i) | |
118 | i += 1 | |
119 | ||
120 | ||
121 | #update all of the new points based on previous positions | |
122 | points = copy.deepcopy(newpoints) | |
123 | ||
124 | for np_z, l0 in enumerate(points): | |
125 | for np_y, c0 in enumerate(l0): | |
126 | for np_x, p0 in enumerate(c0): | |
127 | # all this stuff means that the velocity and displacement of the | |
128 | # field are calculated from current differences in poision | |
129 | ||
130 | vel = p0[1] | |
131 | adj_force = 0.0 | |
132 | ||
133 | a1 = points[np_z][np_y][(np_x-1)%len(l0)][0] | |
134 | a2 = points[np_z][np_y][(np_x+1)%len(l0)][0] | |
135 | a3 = points[np_z][(np_y+1)%len(points)][(np_x)%len(points)][0] | |
136 | a4 = points[np_z][(np_y-1)%len(points)][(np_x)%len(points)][0] | |
137 | a5 = points[(np_z+1)%width][(np_y)][(np_x)][0] | |
138 | a6 = points[(np_z-1)%width][(np_y)][(np_x)][0] | |
139 | ||
140 | adj_force = float(-6*p0[0]) + a1 + a2 + a3 + a4 + a5 + a6 | |
141 | ||
142 | vel += adj_force * hooke | |
143 | ||
144 | ||
145 | disp = p0[0] + vel | |
146 | newpoints[np_z][np_y][np_x] = [disp,vel] | |
147 | ||
148 | print i, | |
149 | ||
150 | - | points = copy.deepcopy(points) |
150 | + | |
151 | ||
152 | close_edges = False ### when set to true, this ensures that | |
153 | ### all boundaries are set to 0 displacement | |
154 | if close_edges: | |
155 | for x0 in xrange(width): | |
156 | for y0 in xrange(width): | |
157 | for z0 in xrange(width): | |
158 | if x0 == 0 or x0 == width-1: | |
159 | points[x0][y0][z0] == [0.0,0.0] | |
160 | if y0 == 0 or y0 == width-1: | |
161 | points[x0][y0][z0] == [0.0,0.0] | |
162 | if z0 == 0 or z0 == width-1: | |
163 | points[x0][y0][z0] == [0.0,0.0] | |
164 | """ | |
165 | for the first 199 frames there will be 2x points orbiting with a radius | |
166 | of 1/9 of the width, with a positive and negative displacement | |
167 | ||
168 | """ | |
169 | upper_limit = 199 | |
170 | if i < upper_limit: | |
171 | radius = width/9 | |
172 | theta = i*(math.pi/15) | |
173 | points[int((width/2)+(math.sin(theta)*0.2*radius))][int((width/2)+(math.sin(theta)*radius))][int((width/2)+(math.cos(theta)*radius))] = [26,26] | |
174 | points[int((width/2)-(math.sin(theta)*0.2*radius))][int((width/2)-(math.sin(theta)*radius))][int((width/2)-(math.cos(theta)*radius))] = [-26,-26] |