-
Notifications
You must be signed in to change notification settings - Fork 0
/
routines.e
194 lines (170 loc) · 4.23 KB
/
routines.e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
-- insolor
include misc.e -- PI
include vector.e
include aconsts.e
global constant POS = 1, VEL = 2, COLOR = 3, MAS = 4, RAD = 5, LABEL = 6
-- global constant OMEGA = 7 -- öèêëè÷åñêàÿ ÷àñòîòà
global constant LAST = LABEL
global
function create_body(sequence params)
-- usage: body = create_body({{POS,{1,4,5}}, {VEL,{5,6,3}}, ... })
sequence body
body = repeat(0,LAST)
for i = 1 to length(params) do
body[params[i][1]] = params[i][2]
end for
return body
end function
global atom dt
dt = 512
--------------------------------------------------------------------------------
global
function accel(atom M, atom r)
return G * M / r*r
end function
global
function fst_space_vel(atom M, atom r)
return sqrt(G * M / r)
end function
global
function fst_space_vel2(atom a, atom r)
return sqrt(a/r)
end function
----------------------------------------------------------
constant prec = 1000
global
function circle(atom r)
integer d,ir
object val
ir = floor(r/prec) -- integer radius
d = floor(r*2/prec) -- integer diameter
if d = 0 then
return vector0
end if
val = 0
while atom(val) do
val = {rand(d)-ir,rand(d)-ir,0}*prec
if modulus3d(val) > r then
val = 0
end if
end while
return val
end function
global
function ring(atom r, atom width)
integer d, ir1, ir2
atom mod
object val
ir1 = floor(r/prec)
ir2 = floor((r+width)/prec)
d = floor((r+width)*2/prec)
if d = 0 then return vector0 end if
val = 0
while atom(val) do
val = {rand(d)-ir2, rand(d)-ir2,0}*prec
mod = modulus3d(val)
if mod > r + width or mod < r then
val = 0
end if
end while
return val
end function
global
constant DOUBLE_PI = 2*PI
global
function orbit(atom r) --> position {x,y}
atom alpha
alpha = rand(floor(DOUBLE_PI*r/prec))*prec
return r*{sin(alpha),cos(alpha),0}
end function
global
function explosion(atom r0, atom maxv) -- {POS,VEL}
sequence pos, vel
pos = circle(r0)
vel = circle(maxv)
return {pos,vel}
end function
global
function resolve_collisions(sequence body)
sequence delta_r
atom r
integer found
found = 1
while found do
found = 0
-- search for collsions
for i = 1 to length(body) do
for j = i+1 to length(body) do
delta_r = body[j][POS]-body[i][POS]
r = modulus3d(delta_r)
if r < body[i][RAD]+body[j][RAD] then
found = 1
delta_r *= (body[i][RAD] + body[j][RAD])/r
body[j][POS] += delta_r
end if
end for
end for
end while
return body
end function
global
function format_time(atom t)
sequence s
s = {}
s &= floor(t/day) -- days
t -= s[$]*day
s &= floor(t/hour) -- hours
t -= s[$]*hour
s &= floor(t/minute) -- minutes
t -= s[$]*minute
s &= t -- seconds
return s
end function
global
function zero_momentum(sequence body) --> body
sequence p,vel
atom mass
p = vector0
mass = 0
for n = 1 to length(body) do
if sequence(body[n]) then
mass += body[n][MAS]
p += body[n][MAS] * body[n][VEL]
end if
end for
vel = p / mass -- velocity of the system
for n = 1 to length(body) do
if sequence(body[n]) then
body[n][VEL] -= vel
end if
end for
return body
end function
global
function center_mass(sequence body) --> body
sequence cm -- center of mass vector
atom m
cm = vector0
m = 0
for n = 1 to length(body) do
if sequence(body[n]) then
cm += body[n][POS]*body[n][MAS]
m += body[n][MAS]
end if
end for
cm /= m
for n = 1 to length(body) do
if sequence(body[n]) then
body[n][POS] -= cm
end if
end for
return body
end function
global
function min(atom a, atom b)
if a>b then
return b
else
return a
end if
end function