1
00:00:04,120 --> 00:00:06,580
Hi, welcome to this new video.

2
00:00:06,580 --> 00:00:08,790
We're continuing our
work in project 1,

3
00:00:08,790 --> 00:00:10,575
which is a particle system.

4
00:00:10,575 --> 00:00:13,340
In this video, we're
going to be working

5
00:00:13,340 --> 00:00:16,600
on adding a trail system
to our particles.

6
00:00:16,600 --> 00:00:20,260
So what I mean by a trail
is that at certain point,

7
00:00:20,260 --> 00:00:23,360
we might want to
see the movement of

8
00:00:23,360 --> 00:00:25,440
a particle and basically have

9
00:00:25,440 --> 00:00:28,295
a sense of the history
of particle position.

10
00:00:28,295 --> 00:00:31,920
So trails, it's kind of a
visual effect that allows us to

11
00:00:31,920 --> 00:00:33,880
see maybe the past points

12
00:00:33,880 --> 00:00:36,390
of each one of these
particles over time.

13
00:00:36,390 --> 00:00:38,400
We could do that
for every frame,

14
00:00:38,400 --> 00:00:41,120
and that would be an incredible
amount of data where

15
00:00:41,120 --> 00:00:45,180
every particle is keeping track
of every point it's been.

16
00:00:45,180 --> 00:00:49,220
But often what we're going
to do is this trail is

17
00:00:49,220 --> 00:00:51,680
just keep maybe the last 20

18
00:00:51,680 --> 00:00:53,820
or store like maybe
20 positions.

19
00:00:53,820 --> 00:00:55,340
So that gives us
some indication,

20
00:00:55,340 --> 00:00:57,810
like a ghosting effect of
where the particle has been.

21
00:00:57,810 --> 00:01:00,820
How are we going to do that?

22
00:01:00,820 --> 00:01:03,160
Is we're going to be dropping

23
00:01:03,160 --> 00:01:05,645
basically making a
copy of the position.

24
00:01:05,645 --> 00:01:07,340
As we're moving along,
we're going to creating

25
00:01:07,340 --> 00:01:09,200
a copy of the position,
which is a vector,

26
00:01:09,200 --> 00:01:10,500
that's going to be saving an

27
00:01:10,500 --> 00:01:13,605
internal list within
the particle.

28
00:01:13,605 --> 00:01:17,270
So we're going to be storing
those previous positions,

29
00:01:17,270 --> 00:01:19,230
if you want, history
of positions,

30
00:01:19,230 --> 00:01:21,890
and then eventually, let's say,

31
00:01:21,890 --> 00:01:23,600
if we want our trail to be of

32
00:01:23,600 --> 00:01:28,230
10 iterations or 10 particles

33
00:01:28,230 --> 00:01:31,155
or 10 trail points, if you want.

34
00:01:31,155 --> 00:01:34,650
We can actually remove the
last element of that list,

35
00:01:34,650 --> 00:01:39,780
and that would actually look
like the last 20 points

36
00:01:39,780 --> 00:01:42,240
or the last 10 points
are the last points that

37
00:01:42,240 --> 00:01:45,750
are showing the past
position of the particle.

38
00:01:45,750 --> 00:01:48,550
If that's not making
too much sense,

39
00:01:48,550 --> 00:01:50,310
we can actually look in code.

40
00:01:50,310 --> 00:01:52,570
One important thing is
that we don't have to

41
00:01:52,570 --> 00:01:56,110
also store the
position every frame.

42
00:01:56,110 --> 00:01:57,790
We can do it every other frame

43
00:01:57,790 --> 00:01:59,490
or we can do it
every five frames.

44
00:01:59,490 --> 00:02:01,590
So as you can see in the
example code in the right,

45
00:02:01,590 --> 00:02:04,250
we're using something
called the frame count and

46
00:02:04,250 --> 00:02:05,890
the module operator with

47
00:02:05,890 --> 00:02:07,910
a five saying, every five frame.

48
00:02:07,910 --> 00:02:09,230
So if the remainder of

49
00:02:09,230 --> 00:02:11,970
this operation is
zero, at that point,

50
00:02:11,970 --> 00:02:13,410
let's create a copy of

51
00:02:13,410 --> 00:02:15,290
the particles position
and add it to

52
00:02:15,290 --> 00:02:17,370
our trail so that we can

53
00:02:17,370 --> 00:02:19,745
actually maybe create a gap or

54
00:02:19,745 --> 00:02:23,320
sample every five frames
the position of a particle.

55
00:02:23,320 --> 00:02:25,390
So we'll create this
ghosting effect

56
00:02:25,390 --> 00:02:28,060
or a sense of where
particle has been.

57
00:02:28,060 --> 00:02:32,050
So let's write it in processing
and understand a bit

58
00:02:32,050 --> 00:02:36,115
further how this would work.

59
00:02:36,115 --> 00:02:38,970
The first thing I
would like to do here,

60
00:02:38,970 --> 00:02:40,910
if you remember, I'm continuing

61
00:02:40,910 --> 00:02:43,750
with the script that
we did last week.

62
00:02:45,500 --> 00:02:51,115
We have this particle system
going from the mouse.

63
00:02:51,115 --> 00:02:54,850
I'm going to restore
this part of the code.

64
00:02:54,850 --> 00:02:57,910
This time, bring it
back to our setup.

65
00:02:57,910 --> 00:03:02,610
So I just want to have a
bit of code that initiates

66
00:03:02,610 --> 00:03:06,170
the particles from the position

67
00:03:06,170 --> 00:03:10,050
of the middle of the
screen, not from the mouse.

68
00:03:10,050 --> 00:03:12,750
Because what I like
doing when I'm learning

69
00:03:12,750 --> 00:03:14,330
a particular subject is

70
00:03:14,330 --> 00:03:17,800
isolating the variables
that we want to look at.

71
00:03:17,800 --> 00:03:22,490
Let's say we want to create
something like 50 articles,

72
00:03:22,490 --> 00:03:25,350
and all of them will
start from the middle of

73
00:03:25,350 --> 00:03:28,295
the screen, not too many.

74
00:03:28,295 --> 00:03:30,360
They're dying pretty quickly.

75
00:03:30,360 --> 00:03:35,815
So let's just also make sure
that we in our lifespan,

76
00:03:35,815 --> 00:03:39,820
let's give them enough
lifespan, maybe 300.

77
00:03:39,820 --> 00:03:44,505
So that we can actually
see what they're doing.

78
00:03:44,505 --> 00:03:49,030
So we have 50 particles,

79
00:03:49,030 --> 00:03:50,830
they have a reasonable lifespan,

80
00:03:50,830 --> 00:03:53,370
so it's a little bit going
back to what we had.

81
00:03:53,370 --> 00:03:57,290
But we now have a
clear canvas to

82
00:03:57,290 --> 00:04:01,130
work on the trails.
What will be the trail?

83
00:04:01,130 --> 00:04:02,530
The trail will be
another kind of

84
00:04:02,530 --> 00:04:04,430
variable that we're going
to add to this particles.

85
00:04:04,430 --> 00:04:07,150
So let's do self.trail,

86
00:04:07,460 --> 00:04:10,335
and it's going to
be an empty list.

87
00:04:10,335 --> 00:04:13,560
This is going to
be an empty list,

88
00:04:13,560 --> 00:04:15,300
and we're going to start
populating this list

89
00:04:15,300 --> 00:04:18,000
with copies of the position.

90
00:04:18,000 --> 00:04:22,260
So we can write a
new function here.

91
00:04:23,020 --> 00:04:28,820
So the definition of update
trail is going to be

92
00:04:28,820 --> 00:04:33,220
a function for updating

93
00:04:33,220 --> 00:04:36,780
the trail or basically
constructing the trail in a way.

94
00:04:38,340 --> 00:04:41,020
We could do it every
frame, but let's just do

95
00:04:41,020 --> 00:04:43,160
this short line of
code that would

96
00:04:43,160 --> 00:04:45,480
allow us to do it every
handful of frame.

97
00:04:45,480 --> 00:04:53,475
So if the frame count
modular operator.

98
00:04:53,475 --> 00:04:55,240
Meaning, the remainder

99
00:04:55,240 --> 00:04:59,485
between eight and the
frame count equals zero,

100
00:04:59,485 --> 00:05:01,860
eight is an arbitrary number.

101
00:05:01,860 --> 00:05:03,540
I'm saying every eight frames.

102
00:05:03,540 --> 00:05:05,120
But if you want to do
it every other frame,

103
00:05:05,120 --> 00:05:06,270
you would put a two.

104
00:05:06,270 --> 00:05:09,010
Every five frames,
you would do a five.

105
00:05:09,360 --> 00:05:13,585
Let's say every five frames,

106
00:05:13,585 --> 00:05:17,035
we're going to be
storing in the trail

107
00:05:17,035 --> 00:05:20,990
so self.trail which is a list.

108
00:05:24,180 --> 00:05:27,625
Self.trail.append.

109
00:05:27,625 --> 00:05:29,800
What do we want to append?

110
00:05:29,800 --> 00:05:32,020
We want to add a copy of

111
00:05:32,020 --> 00:05:35,900
our position, so
self.position.copy.

112
00:05:40,320 --> 00:05:42,955
If we just put position,

113
00:05:42,955 --> 00:05:44,980
it will basically store

114
00:05:44,980 --> 00:05:48,445
the actual position so
that would basically move.

115
00:05:48,445 --> 00:05:49,600
That trial will be moving

116
00:05:49,600 --> 00:05:51,040
with the position
of the particle.

117
00:05:51,040 --> 00:05:53,800
We don't want a reference to
the position we want a copy,

118
00:05:53,800 --> 00:05:56,290
which is a completely new piece

119
00:05:56,290 --> 00:05:58,030
of information that is frozen in

120
00:05:58,030 --> 00:06:03,350
time when that position
was actually saved.

121
00:06:07,230 --> 00:06:09,925
At this point, if
we keep doing this,

122
00:06:09,925 --> 00:06:11,470
this list will go forever,

123
00:06:11,470 --> 00:06:14,770
so we could run

124
00:06:14,770 --> 00:06:17,780
out of memory because the
trails would be too long.

125
00:06:18,170 --> 00:06:20,790
In some cases, we might want to

126
00:06:20,790 --> 00:06:22,575
allow the program to go slower,

127
00:06:22,575 --> 00:06:23,970
and if we're recording frames

128
00:06:23,970 --> 00:06:25,530
and the computation
starts getting slow,

129
00:06:25,530 --> 00:06:27,120
we might still be
able to restore

130
00:06:27,120 --> 00:06:30,615
its full frame by doing
an animation of it.

131
00:06:30,615 --> 00:06:32,280
You can decide if you want

132
00:06:32,280 --> 00:06:34,080
your animation to run real time,

133
00:06:34,080 --> 00:06:35,595
you can keep it light.

134
00:06:35,595 --> 00:06:38,850
But if you don't care for it
to run slow and you want to

135
00:06:38,850 --> 00:06:40,920
do say a beautiful animation

136
00:06:40,920 --> 00:06:43,675
that might take some
time to compute,

137
00:06:43,675 --> 00:06:45,640
by all means, you can
leave more trials

138
00:06:45,640 --> 00:06:47,350
on and you can create

139
00:06:47,350 --> 00:06:50,450
some beautiful
drawings in that way.

140
00:06:50,580 --> 00:06:54,220
If we're going to in this case,

141
00:06:54,220 --> 00:06:56,770
limit the size of this trial,

142
00:06:56,770 --> 00:07:00,860
if the length of the trail,

143
00:07:07,830 --> 00:07:10,135
it's bigger than,

144
00:07:10,135 --> 00:07:12,100
let's do 15 as

145
00:07:12,100 --> 00:07:13,810
an arbitrary number that

146
00:07:13,810 --> 00:07:16,930
represents how long do
we want the trail to be.

147
00:07:16,930 --> 00:07:21,190
Again, this could be a
variable that you create

148
00:07:21,190 --> 00:07:24,190
for the particle so you
have more control over

149
00:07:24,190 --> 00:07:28,010
the particle's trail length.

150
00:07:29,910 --> 00:07:39,550
Self.trail. We're
going to pop zero.

151
00:07:39,550 --> 00:07:42,460
Zero here is the index.

152
00:07:42,460 --> 00:07:44,155
If you remember
the pop function,

153
00:07:44,155 --> 00:07:45,850
the pop function is
going to be a way

154
00:07:45,850 --> 00:07:47,650
of extracting or removing from

155
00:07:47,650 --> 00:07:51,670
this list an index
based on an index.

156
00:07:51,670 --> 00:07:54,070
We're going to pop
the first entry.

157
00:07:54,070 --> 00:07:56,005
If you think about
it, as we keep

158
00:07:56,005 --> 00:07:58,375
adding elements to the list,

159
00:07:58,375 --> 00:07:59,800
the last one would be

160
00:07:59,800 --> 00:08:01,900
the most recent position
of the particle.

161
00:08:01,900 --> 00:08:03,385
The first entry of the least is

162
00:08:03,385 --> 00:08:05,410
the oldest position
of the particle.

163
00:08:05,410 --> 00:08:08,215
If we pop zero, meaning at
the beginning of the list,

164
00:08:08,215 --> 00:08:10,330
that would be the oldest
position we have.

165
00:08:10,330 --> 00:08:14,185
We're going to remain
with the closest,

166
00:08:14,185 --> 00:08:16,780
let's say, 15 points
in this case that

167
00:08:16,780 --> 00:08:20,090
have been recorded
for the particle.

168
00:08:25,350 --> 00:08:28,330
Update trail. There we go.

169
00:08:28,330 --> 00:08:29,950
I think we are trying
to make sure that

170
00:08:29,950 --> 00:08:32,635
that function is written well.

171
00:08:32,635 --> 00:08:37,250
We have that function. We
could execute that function.

172
00:08:41,910 --> 00:08:52,195
We can put it all the
way here. Update trail.

173
00:08:52,195 --> 00:08:53,845
But you can see here,

174
00:08:53,845 --> 00:08:56,125
we're actually
creating the trails.

175
00:08:56,125 --> 00:08:58,940
If we actually re-run this,

176
00:08:58,980 --> 00:09:01,870
it's running, but we
cannot see anything.

177
00:09:01,870 --> 00:09:04,975
There's no change to our system.

178
00:09:04,975 --> 00:09:07,060
That's because we created data,

179
00:09:07,060 --> 00:09:08,800
but we haven't
visualized that data.

180
00:09:08,800 --> 00:09:10,720
We created data,
which is the history

181
00:09:10,720 --> 00:09:12,880
of the particle in
the form of a trail.

182
00:09:12,880 --> 00:09:14,920
But if you can go to
our Display function,

183
00:09:14,920 --> 00:09:17,230
which controls the graphics.

184
00:09:17,230 --> 00:09:19,405
Let's create a bit of room here.

185
00:09:19,405 --> 00:09:25,130
We could do it as a function.
Let's do it as a function.

186
00:09:26,460 --> 00:09:28,960
You seen some of our examples,

187
00:09:28,960 --> 00:09:30,670
we're going to maybe
write a longer function

188
00:09:30,670 --> 00:09:32,080
for display that
includes the trails,

189
00:09:32,080 --> 00:09:34,765
but you could separate
it, again modularity.

190
00:09:34,765 --> 00:09:36,580
It's always better.

191
00:09:36,580 --> 00:09:38,570
Display_trails.

192
00:09:46,080 --> 00:09:47,935
What we want to do,

193
00:09:47,935 --> 00:09:51,470
let's just create a four loop

194
00:09:52,850 --> 00:09:59,330
for t in self.trails.

195
00:09:59,330 --> 00:10:03,670
T is going to be one
of the trail points,

196
00:10:03,670 --> 00:10:10,465
and we could say we want
an ellipse, that is t.x.

197
00:10:10,465 --> 00:10:11,935
We know this is a vector.

198
00:10:11,935 --> 00:10:15,220
Use a copy of position, t.y.

199
00:10:15,220 --> 00:10:18,640
It has an X and Y, and
let's just give it

200
00:10:18,640 --> 00:10:23,380
a very small size.

201
00:10:23,380 --> 00:10:27,415
To differentiate it from
the particle itself,

202
00:10:27,415 --> 00:10:29,810
I'm going to say no stroke,

203
00:10:29,880 --> 00:10:35,510
and feel it's going to be red.

204
00:10:39,000 --> 00:10:41,395
That's all good.

205
00:10:41,395 --> 00:10:43,780
We have a new function
that displays the trails.

206
00:10:43,780 --> 00:10:46,120
It goes through how
long the trails is.

207
00:10:46,120 --> 00:10:49,945
It's like it might have
one entity up to 15,

208
00:10:49,945 --> 00:10:52,585
and it's going to
display them as

209
00:10:52,585 --> 00:10:56,125
also ellipses that are
in this case, red.

210
00:10:56,125 --> 00:10:58,720
Let's just copy the
name of this function,

211
00:10:58,720 --> 00:11:03,830
and just after the display,

212
00:11:06,270 --> 00:11:08,845
we're going to
display the trails.

213
00:11:08,845 --> 00:11:11,050
The good thing about
this kind of doing

214
00:11:11,050 --> 00:11:13,120
it as a function is that if
you don't want the trails,

215
00:11:13,120 --> 00:11:14,305
you can always comment it off.

216
00:11:14,305 --> 00:11:15,925
You can always turn on and off,

217
00:11:15,925 --> 00:11:19,855
some of these functions
that might not work.

218
00:11:19,855 --> 00:11:23,305
Let's see what are the errors
that we have right now.

219
00:11:23,305 --> 00:11:25,495
We were running into an error,

220
00:11:25,495 --> 00:11:27,340
and I think it's just that
we need to make sure that

221
00:11:27,340 --> 00:11:29,620
we're spelling things correctly.

222
00:11:29,620 --> 00:11:33,810
I think our variable
trails have been

223
00:11:33,810 --> 00:11:38,395
interchangingly using
trails, and trail.

224
00:11:38,395 --> 00:11:39,970
Let's just keep consistent.

225
00:11:39,970 --> 00:11:41,755
But most importantly, here,

226
00:11:41,755 --> 00:11:43,900
is self.trail is our variable.

227
00:11:43,900 --> 00:11:49,990
You can check here self.trail
and self.trail here.

228
00:11:49,990 --> 00:11:55,220
We're still running
into an error.

229
00:11:56,040 --> 00:11:58,990
Because we changed the
name of the function,

230
00:11:58,990 --> 00:12:00,790
so probably we have
to change the name of

231
00:12:00,790 --> 00:12:04,160
the function here too.
Let's see it now.

232
00:12:06,510 --> 00:12:10,750
There we go. You
can see now that

233
00:12:10,750 --> 00:12:15,415
these particles have
these kind of red trails.

234
00:12:15,415 --> 00:12:18,535
Let's just comment
out for a moment.

235
00:12:18,535 --> 00:12:21,400
They compute forces,
and let's give them

236
00:12:21,400 --> 00:12:25,700
a little bit of higher lifespan.

237
00:12:26,100 --> 00:12:28,570
We can see them a bit better.

238
00:12:28,570 --> 00:12:30,460
Now, you can see the lines.

239
00:12:30,460 --> 00:12:33,085
They look like lines, but
there are a series of points.

240
00:12:33,085 --> 00:12:35,440
What if you want these
kind of trails to be

241
00:12:35,440 --> 00:12:38,480
a bit longer or more scattered?

242
00:12:38,490 --> 00:12:41,455
Well, you can go into
this frame count,

243
00:12:41,455 --> 00:12:42,970
and this variable here, is five,

244
00:12:42,970 --> 00:12:44,395
which is, again, hard coded.

245
00:12:44,395 --> 00:12:48,940
You could give it a
trails gap like a name.

246
00:12:48,940 --> 00:12:51,985
Let's just do something like 10,

247
00:12:51,985 --> 00:12:53,995
and see what happens.

248
00:12:53,995 --> 00:12:56,800
We're not changing the
number of trail points,

249
00:12:56,800 --> 00:12:58,180
but you see that the
trail points now are

250
00:12:58,180 --> 00:13:00,620
a bit more scattered
from each other.

251
00:13:01,170 --> 00:13:04,675
We have a total
number of 15 points.

252
00:13:04,675 --> 00:13:10,120
This is because we
have a 15 here,

253
00:13:10,120 --> 00:13:12,430
but we could say the
number to be five.

254
00:13:12,430 --> 00:13:14,770
We want to make short trails

255
00:13:14,770 --> 00:13:19,150
or you see we have that effect.

256
00:13:19,150 --> 00:13:22,900
But maybe you want to have
maybe something like 40,

257
00:13:22,900 --> 00:13:24,460
a much larger number and

258
00:13:24,460 --> 00:13:30,650
maybe the distance
again, maybe tighter.

259
00:13:34,050 --> 00:13:38,065
You can see we could
have much longer trails.

260
00:13:38,065 --> 00:13:41,200
All of this comes with the
cost of adding more data,

261
00:13:41,200 --> 00:13:42,580
more memory to our program,

262
00:13:42,580 --> 00:13:45,070
and you know more computation
to what we're doing.

263
00:13:45,070 --> 00:13:47,170
But, it's good to know what are

264
00:13:47,170 --> 00:13:50,050
the kind of components that
we're adding to the mix here.

265
00:13:50,050 --> 00:13:52,705
I'm going to leave it
here with a number such

266
00:13:52,705 --> 00:13:55,600
as 15 and eight,

267
00:13:55,600 --> 00:14:01,135
which is what I've
calibrated to our intention.

268
00:14:01,135 --> 00:14:04,615
We have a new display
trail function.

269
00:14:04,615 --> 00:14:06,400
One final thing that
you might want to do,

270
00:14:06,400 --> 00:14:09,310
and I think some of our
examples show how to do,

271
00:14:09,310 --> 00:14:12,265
is that, instead of
drawing the dots,

272
00:14:12,265 --> 00:14:14,390
you might want to draw a line.

273
00:14:14,430 --> 00:14:18,640
I invite you to really try
to do that function yourself

274
00:14:18,640 --> 00:14:20,410
before looking at
the examples and

275
00:14:20,410 --> 00:14:22,450
how we've written that for you.

276
00:14:22,450 --> 00:14:25,720
But the way you would
do that, is that,

277
00:14:25,720 --> 00:14:28,405
starting from the second
point in the trail,

278
00:14:28,405 --> 00:14:30,505
you can always draw
a line between

279
00:14:30,505 --> 00:14:32,575
the second point and
the previous point.

280
00:14:32,575 --> 00:14:33,940
The first point you
wouldn't be able

281
00:14:33,940 --> 00:14:36,910
to do it because in the list,

282
00:14:36,910 --> 00:14:39,325
you wouldn't have
a previous point.

283
00:14:39,325 --> 00:14:41,095
You would run into an error.

284
00:14:41,095 --> 00:14:42,790
But from index 1,

285
00:14:42,790 --> 00:14:44,860
you can always write
a line between

286
00:14:44,860 --> 00:14:47,545
the trail point
index 1 to index 0,

287
00:14:47,545 --> 00:14:50,140
from index 2 to index
1, and so forth.

288
00:14:50,140 --> 00:14:52,665
You could do in this loop,

289
00:14:52,665 --> 00:14:55,200
you could do an
if-statement that would

290
00:14:55,200 --> 00:14:58,395
exclude the first point,

291
00:14:58,395 --> 00:15:01,740
and then basically,

292
00:15:01,740 --> 00:15:03,420
instead of an ellipse,
you would draw a line

293
00:15:03,420 --> 00:15:06,815
between a trail point
and another trail point.

294
00:15:06,815 --> 00:15:09,880
Again, that's an
invitation to explore

295
00:15:09,880 --> 00:15:14,020
yourself or look at the
examples that we have provided.

296
00:15:14,020 --> 00:15:17,180
But otherwise, I'll see
you in the next video.