1
00:00:05,330 --> 00:00:08,140
Hi. Welcome to this new video.

2
00:00:08,140 --> 00:00:09,820
We're going to
continue working on

3
00:00:09,820 --> 00:00:12,200
our particle system simulation,

4
00:00:12,200 --> 00:00:14,040
and we're going to
start addressing

5
00:00:14,040 --> 00:00:16,300
a calculation that is going
to become very handy.

6
00:00:16,300 --> 00:00:21,140
How do we calculate a closest
object out of a collection?

7
00:00:21,140 --> 00:00:23,180
Let's imagine that we have

8
00:00:23,180 --> 00:00:26,280
our particles scattered
in the world,

9
00:00:26,280 --> 00:00:28,700
but we have two forces to

10
00:00:28,700 --> 00:00:32,870
attractors or two forces
with an arbitrary vector.

11
00:00:32,870 --> 00:00:35,240
The closest object calculation

12
00:00:35,240 --> 00:00:38,850
will allow a particle to know,

13
00:00:38,850 --> 00:00:41,080
just by comparing distances,

14
00:00:41,080 --> 00:00:44,880
which is the object that
is closest to them.

15
00:00:44,880 --> 00:00:48,280
We're going to be using
this technique obviously,

16
00:00:48,280 --> 00:00:50,580
in a particle simulation,
you might have

17
00:00:50,580 --> 00:00:52,620
influence from two
forces at once,

18
00:00:52,620 --> 00:00:54,400
but we really want to bring

19
00:00:54,400 --> 00:00:56,120
forward this kind of
algorithm that is very

20
00:00:56,120 --> 00:00:59,200
useful to determine what

21
00:00:59,200 --> 00:01:01,335
is the closest object
in a collection.

22
00:01:01,335 --> 00:01:03,900
Let's look at the
algorithm itself.

23
00:01:03,900 --> 00:01:06,680
When we look at a
particular particle,

24
00:01:06,680 --> 00:01:09,860
we will be evaluating A,

25
00:01:09,860 --> 00:01:13,670
the distances of all
the forces around us,

26
00:01:13,670 --> 00:01:18,195
and we'll also identify
what is the ID.

27
00:01:18,195 --> 00:01:21,000
If we look through all
the forces around us,

28
00:01:21,000 --> 00:01:26,130
we would be storing the ID
of each one of those forces.

29
00:01:26,130 --> 00:01:28,530
As you can see in the
algorithm on the left,

30
00:01:28,530 --> 00:01:30,550
we will start with two
variables that are going to be

31
00:01:30,550 --> 00:01:32,730
key to understand
this calculation.

32
00:01:32,730 --> 00:01:34,990
We start with the
closest distance value,

33
00:01:34,990 --> 00:01:36,630
and we will start
with a very large

34
00:01:36,630 --> 00:01:38,410
number that would gradually be

35
00:01:38,410 --> 00:01:42,250
reduced as we find
closer objects,

36
00:01:42,250 --> 00:01:45,830
and the closest ID,
which also defaults to

37
00:01:45,830 --> 00:01:48,590
a number that we could

38
00:01:48,590 --> 00:01:51,720
identify as not the
correct number.

39
00:01:51,720 --> 00:01:54,065
I'm going to use a
number minus one,

40
00:01:54,065 --> 00:01:57,630
but as we find an entity,
let's say a force,

41
00:01:57,630 --> 00:01:59,540
that is at a
particular distance,

42
00:01:59,540 --> 00:02:02,290
that is smaller than
this very large number,

43
00:02:02,290 --> 00:02:04,465
then that's going to
become our closest object.

44
00:02:04,465 --> 00:02:09,210
If we keep repeating this
process over and over again,

45
00:02:09,210 --> 00:02:11,110
we will eventually be

46
00:02:11,110 --> 00:02:14,330
determining which is the force
that is the closest to us,

47
00:02:14,330 --> 00:02:16,810
and it's associated ID

48
00:02:16,810 --> 00:02:21,615
number so that we can actually
use it in the future.

49
00:02:21,615 --> 00:02:23,770
Out of that equation,
we're going to be

50
00:02:23,770 --> 00:02:25,390
creating a closest ID,

51
00:02:25,390 --> 00:02:27,370
which is going to be the ID of

52
00:02:27,370 --> 00:02:33,050
the force that will be
closest to the particle.

53
00:02:33,050 --> 00:02:35,200
This is something that we

54
00:02:35,200 --> 00:02:37,320
might need to look
further in the code.

55
00:02:37,320 --> 00:02:39,380
This is where we left off.

56
00:02:39,380 --> 00:02:41,100
Let's just do a quick recap.

57
00:02:41,100 --> 00:02:43,400
We have a particle systems with

58
00:02:43,400 --> 00:02:48,600
a singular force that we
display in the screen.

59
00:02:48,600 --> 00:02:50,550
The first thing we want to do in

60
00:02:50,550 --> 00:02:56,600
this tutorial is convert
our force to a collection.

61
00:02:56,600 --> 00:02:59,040
As we have all particles,

62
00:02:59,040 --> 00:03:03,250
I'm going to do all forces

63
00:03:03,380 --> 00:03:06,920
and it's also going
to be an empty list.

64
00:03:06,920 --> 00:03:14,010
Here, let's just do two forces.

65
00:03:16,310 --> 00:03:20,740
We're going to copy paste
this new force line,

66
00:03:21,460 --> 00:03:25,260
and it's going to be
our second force.

67
00:03:25,260 --> 00:03:28,425
We are going to give
it a position of maybe

68
00:03:28,425 --> 00:03:36,540
1,000 by 400, and
then we're going

69
00:03:36,540 --> 00:03:43,510
to work with a force
of 10 and -40.

70
00:03:45,830 --> 00:03:49,980
We also will just
for good measure,

71
00:03:49,980 --> 00:03:52,380
we're going to add
this new force here.

72
00:03:52,380 --> 00:03:54,160
But both of these forces,

73
00:03:54,160 --> 00:04:00,525
we're going to add them
to the all forces list.

74
00:04:00,525 --> 00:04:03,400
Remember, we append.

75
00:04:06,580 --> 00:04:10,800
The new force that we created
and also the second force

76
00:04:10,800 --> 00:04:15,245
, that is number 2.

77
00:04:15,245 --> 00:04:19,220
This time, instead of executing

78
00:04:19,220 --> 00:04:23,300
just the display function
of one of the forces,

79
00:04:23,300 --> 00:04:28,840
we can do a very similar
look at what we do for

80
00:04:28,840 --> 00:04:35,685
the particles for
f in all forces.

81
00:04:35,685 --> 00:04:43,840
For a force object within the
all forces list, f.display.

82
00:04:46,670 --> 00:04:48,870
At this point, let's see

83
00:04:48,870 --> 00:04:50,670
if we are running
into any errors.

84
00:04:50,670 --> 00:04:52,010
The only thing that
we're actually doing,

85
00:04:52,010 --> 00:04:53,730
and you could have
many more forces.

86
00:04:53,730 --> 00:04:56,530
The first thing we're doing
is trying to work with

87
00:04:56,530 --> 00:04:58,070
collections because
that gives us

88
00:04:58,070 --> 00:05:00,350
the flexibility of
having a singular item,

89
00:05:00,350 --> 00:05:03,670
maybe two, but maybe many more.

90
00:05:04,370 --> 00:05:08,570
That's all good. The second step

91
00:05:08,570 --> 00:05:11,230
is to pass the information.

92
00:05:11,230 --> 00:05:12,990
The particle currently
doesn't know that

93
00:05:12,990 --> 00:05:15,920
there is a collection
of forces out there,

94
00:05:15,920 --> 00:05:18,430
so in order for a particle

95
00:05:18,430 --> 00:05:21,090
to be able to understand
the world around it,

96
00:05:21,090 --> 00:05:23,330
and understand that there are,

97
00:05:23,330 --> 00:05:25,530
in fact, many forces,

98
00:05:25,530 --> 00:05:34,605
we are going to include
the collection here.

99
00:05:34,605 --> 00:05:40,360
We're going to pass the
collection force list.

100
00:05:47,080 --> 00:05:50,520
We're also going to say

101
00:05:52,120 --> 00:06:01,220
self.force_list = force_list.

102
00:06:01,220 --> 00:06:04,130
Once you do these changes
to the constructor,

103
00:06:04,130 --> 00:06:07,115
you're going to run into
an error unless you pass

104
00:06:07,115 --> 00:06:11,915
all forces to the
particle argument.

105
00:06:11,915 --> 00:06:13,610
When we construct a particle,

106
00:06:13,610 --> 00:06:17,750
we provide in the position,
all the particles.

107
00:06:17,750 --> 00:06:21,095
Let's just make sure that

108
00:06:21,095 --> 00:06:26,285
all forces list is done
here in the particles.

109
00:06:26,285 --> 00:06:27,500
The particles have already

110
00:06:27,500 --> 00:06:29,525
a reference to the
particle list,

111
00:06:29,525 --> 00:06:34,250
so we're going to do
that for the force list.

112
00:06:34,250 --> 00:06:37,310
We've done this already
for the particles,

113
00:06:37,310 --> 00:06:40,310
but we're going to make sure
that we're also doing it for

114
00:06:40,310 --> 00:06:42,060
the forces

115
00:06:47,650 --> 00:06:53,585
self.force_list = force_list.

116
00:06:53,585 --> 00:06:56,030
Let's make sure that we
didn't break anything

117
00:06:56,030 --> 00:06:58,850
here because we were
for some mistake.

118
00:06:58,850 --> 00:07:01,745
I could confuse. I actually

119
00:07:01,745 --> 00:07:03,380
was doing changes to the force.

120
00:07:03,380 --> 00:07:05,510
We don't want to do changes
to the force at this point.

121
00:07:05,510 --> 00:07:10,820
We're only changing the
constructor of the particle.

122
00:07:10,820 --> 00:07:12,860
And in the particle, when we

123
00:07:12,860 --> 00:07:14,855
actually construct it,
we give it the position,

124
00:07:14,855 --> 00:07:16,160
all the other particles, and

125
00:07:16,160 --> 00:07:20,195
all the forces. There we go.

126
00:07:20,195 --> 00:07:22,775
Now we are passing
the information

127
00:07:22,775 --> 00:07:27,960
of the forces to the
particles. That's great.

128
00:07:28,030 --> 00:07:30,350
Let's go into the particle,

129
00:07:30,350 --> 00:07:34,580
and let's create a function,

130
00:07:34,580 --> 00:07:37,980
maybe just after run here,

131
00:07:38,320 --> 00:07:44,390
and we're going to define
our closest force.

132
00:07:44,390 --> 00:07:46,460
Again, this is a function

133
00:07:46,460 --> 00:07:49,250
that whenever you feel like you

134
00:07:49,250 --> 00:07:51,860
need one single point to

135
00:07:51,860 --> 00:07:54,665
find the closest point
out of a collection,

136
00:07:54,665 --> 00:07:57,395
it's something
that you could do.

137
00:07:57,395 --> 00:07:59,420
Let's create a bit of space.

138
00:07:59,420 --> 00:08:02,695
We need two arbitrary variables.

139
00:08:02,695 --> 00:08:05,815
We're going to call
the closest distance.

140
00:08:05,815 --> 00:08:08,170
Again, the idea here
is that we start

141
00:08:08,170 --> 00:08:09,850
with something very large,

142
00:08:09,850 --> 00:08:13,310
larger than any distance that

143
00:08:13,310 --> 00:08:17,940
could be calculated between
our particles and a force,

144
00:08:17,980 --> 00:08:22,370
and the closest ID.

145
00:08:22,370 --> 00:08:25,640
It's important to
know that in Python,

146
00:08:25,640 --> 00:08:27,990
the ID minus 1,

147
00:08:27,990 --> 00:08:29,795
it's a valid ID.

148
00:08:29,795 --> 00:08:34,800
It's an ID that looks from
the backwards of the list.

149
00:08:35,560 --> 00:08:38,660
But still, it's an
arbitrary number that I

150
00:08:38,660 --> 00:08:41,195
know that I'm usually not
using negative numbers,

151
00:08:41,195 --> 00:08:43,910
so if I wanted to create
an exception to make

152
00:08:43,910 --> 00:08:45,095
sure let's say that

153
00:08:45,095 --> 00:08:46,805
this algorithm doesn't
find the number,

154
00:08:46,805 --> 00:08:49,745
we would end do that the
closest ID is minus one.

155
00:08:49,745 --> 00:08:52,655
We could check against
this default value.

156
00:08:52,655 --> 00:08:56,180
Again, you could use
a different value,

157
00:08:56,180 --> 00:08:59,690
but I'm going to use
a minus one for now.

158
00:08:59,690 --> 00:09:02,330
Let's do our loop. The
main important thing

159
00:09:02,330 --> 00:09:03,575
here is that we need to loop,

160
00:09:03,575 --> 00:09:06,980
so each particle will
loop through each force.

161
00:09:06,980 --> 00:09:11,520
So for in range.

162
00:09:12,880 --> 00:09:15,335
I'm going to use a range.

163
00:09:15,335 --> 00:09:19,280
I could look just directly
through the list of forces,

164
00:09:19,280 --> 00:09:23,360
but I would like to have the
iterator, the i variable.

165
00:09:23,360 --> 00:09:25,640
You could do this
in multiple ways.

166
00:09:25,640 --> 00:09:27,020
You can look through
the list and

167
00:09:27,020 --> 00:09:28,670
add an iterator variable,

168
00:09:28,670 --> 00:09:40,080
so len.self.force_list.

169
00:09:41,950 --> 00:09:46,235
We're looping through the list,

170
00:09:46,235 --> 00:09:48,860
or as long as that list is,

171
00:09:48,860 --> 00:09:52,470
we're creating a loop that
is as long as that list is.

172
00:09:52,540 --> 00:09:54,530
The first thing that we want to

173
00:09:54,530 --> 00:09:56,690
calculate is the distance.

174
00:09:56,690 --> 00:09:58,865
How we calculate the distance?

175
00:09:58,865 --> 00:10:01,625
Well, we can use the
subtraction vector

176
00:10:01,625 --> 00:10:05,825
between the particles position
and the force position,

177
00:10:05,825 --> 00:10:10,770
and that vector's magnitude
should be the distance.

178
00:10:11,290 --> 00:10:13,460
The subtraction is
something that we

179
00:10:13,460 --> 00:10:14,960
will call the difference vector,

180
00:10:14,960 --> 00:10:18,710
so I'm going to call
it dif for difference.

181
00:10:18,710 --> 00:10:23,280
The difference is between
the self.position,

182
00:10:23,280 --> 00:10:25,145
so the position of the particle.

183
00:10:25,145 --> 00:10:26,930
Let's make a copy of that
because we don't want

184
00:10:26,930 --> 00:10:29,390
to alter the position itself,

185
00:10:29,390 --> 00:10:31,130
we want to create

186
00:10:31,130 --> 00:10:33,740
a new vector that is a
copy of that vector.

187
00:10:33,740 --> 00:10:36,270
Then we subtract.

188
00:10:36,270 --> 00:10:38,440
This is where the
the vector operation

189
00:10:38,440 --> 00:10:40,960
start getting slightly longer.

190
00:10:40,960 --> 00:10:42,910
This is one vector.

191
00:10:42,910 --> 00:10:44,725
It's a copy of the position.

192
00:10:44,725 --> 00:10:48,505
We are subtracting the position

193
00:10:48,505 --> 00:10:50,760
of the force, which is self.

194
00:10:50,760 --> 00:10:58,775
and here we have to
access, force_list i.

195
00:10:58,775 --> 00:11:02,045
Because we're looping
through the force list,

196
00:11:02,045 --> 00:11:04,580
the force_list i it's

197
00:11:04,580 --> 00:11:08,600
the index that we're evaluating
currently,.position.

198
00:11:08,600 --> 00:11:11,790
This is the position
of the force.

199
00:11:13,090 --> 00:11:19,340
Then we can say distance
to force, just to give it.

200
00:11:19,340 --> 00:11:22,640
A bit more clarity is

201
00:11:22,640 --> 00:11:26,450
the the difference
vector diff.magnitude.

202
00:11:26,450 --> 00:11:30,455
The magnitude of that
difference vector.

203
00:11:30,455 --> 00:11:32,465
If you go back to vector math,

204
00:11:32,465 --> 00:11:34,460
you'll realize that substraction

205
00:11:34,460 --> 00:11:37,250
between two points will give us

206
00:11:37,250 --> 00:11:39,980
a vector that represents in

207
00:11:39,980 --> 00:11:44,000
its magnitude the distance
between those two points.

208
00:11:44,000 --> 00:11:47,225
Substraction is very linked to

209
00:11:47,225 --> 00:11:51,335
a distance calculation.
That's great.

210
00:11:51,335 --> 00:11:55,190
We are evaluating in
the loop the distance

211
00:11:55,190 --> 00:11:58,520
from one particle to the
force. What do we want to say?

212
00:11:58,520 --> 00:12:04,880
We want to say if the
distance to the force.

213
00:12:04,880 --> 00:12:08,285
Let's imagine that we
encounter a value of 100.

214
00:12:08,285 --> 00:12:10,250
Is the distance to the force

215
00:12:10,250 --> 00:12:14,915
smaller than this really big
number that we started with?

216
00:12:14,915 --> 00:12:18,605
The first iteration is
most likely to be yes.

217
00:12:18,605 --> 00:12:20,990
We want it to be a yes,

218
00:12:20,990 --> 00:12:24,035
a true condition
at the beginning.

219
00:12:24,035 --> 00:12:26,900
That's going to be true.
Then what happens?

220
00:12:26,900 --> 00:12:30,095
Well, the first
thing we say is then

221
00:12:30,095 --> 00:12:36,245
the closest distance is going
to become that distance.

222
00:12:36,245 --> 00:12:38,105
We are saying, let's update

223
00:12:38,105 --> 00:12:41,690
that the closest distance
is now that 100.

224
00:12:41,690 --> 00:12:45,665
But also, the closest ID,

225
00:12:45,665 --> 00:12:50,315
it's going to become that I,

226
00:12:50,315 --> 00:12:53,360
meaning that in this
iteration of the loop,

227
00:12:53,360 --> 00:12:55,790
this object that we're
evaluating this force is

228
00:12:55,790 --> 00:12:58,625
currently closer than
our closest force,

229
00:12:58,625 --> 00:13:02,000
and its associated ID is I.

230
00:13:02,000 --> 00:13:05,495
If we keep repeating
that, now we have 100.

231
00:13:05,495 --> 00:13:08,885
The next particle, let's
say it's 88. Is it closer?

232
00:13:08,885 --> 00:13:11,690
Yes, then the closest distance
is going to become 88,

233
00:13:11,690 --> 00:13:14,045
and the ID is associated ID.

234
00:13:14,045 --> 00:13:17,825
If we encounter a
force that is at 120,

235
00:13:17,825 --> 00:13:19,970
that is not going to be updated.

236
00:13:19,970 --> 00:13:23,465
As we look through all
the entities in the list,

237
00:13:23,465 --> 00:13:29,400
we would obtain the closest ID.

238
00:13:29,530 --> 00:13:33,870
Here it's important
that we exit the loop.

239
00:13:34,060 --> 00:13:38,540
We go back all the way
to the fore loop here.

240
00:13:38,540 --> 00:13:43,025
We could specify what
is the closest force.

241
00:13:43,025 --> 00:13:52,440
The closest force it's going
to be self.force list.

242
00:13:55,480 --> 00:13:57,770
From the list and

243
00:13:57,770 --> 00:14:00,830
the index is the index
that we obtained.

244
00:14:00,830 --> 00:14:04,250
What we're actually looking
is this item here is

245
00:14:04,250 --> 00:14:08,520
the index of the closest
force available.

246
00:14:10,630 --> 00:14:16,250
That's great. We
could at this point,

247
00:14:16,250 --> 00:14:25,055
just do a small stroke
visualization of this.

248
00:14:25,055 --> 00:14:33,120
Say let's do a line
from the position.

249
00:14:35,530 --> 00:14:39,900
We have self in the
position in x and y.

250
00:14:41,800 --> 00:14:44,600
Then we should have

251
00:14:44,600 --> 00:14:50,060
closes force.position because
force is a class that

252
00:14:50,060 --> 00:14:52,115
in turn has a position

253
00:14:52,115 --> 00:15:02,495
x and there we go.

254
00:15:02,495 --> 00:15:04,700
What we're doing here yet again

255
00:15:04,700 --> 00:15:07,595
is make sure we're seeing that.

256
00:15:07,595 --> 00:15:10,205
So we're drawing a red line.

257
00:15:10,205 --> 00:15:12,590
If you want it to be too thick,

258
00:15:12,590 --> 00:15:15,170
we can just add some
transparency between

259
00:15:15,170 --> 00:15:16,910
the position of the particle

260
00:15:16,910 --> 00:15:19,490
and the position of
this closest object.

261
00:15:19,490 --> 00:15:21,605
If we don't have any errors,

262
00:15:21,605 --> 00:15:27,690
which we might, let's
just calculate this.

263
00:15:27,760 --> 00:15:32,400
Let's just put it down here.

264
00:15:36,400 --> 00:15:39,860
Right now, we're not doing
anything with those objects.

265
00:15:39,860 --> 00:15:43,400
We're trying to find what
would be our closest force.

266
00:15:43,400 --> 00:15:46,350
But let's just see.

267
00:15:46,960 --> 00:15:52,200
Here we go. We actually
end up with a white line.

268
00:15:52,420 --> 00:15:55,160
But you see that half
of the particles draw

269
00:15:55,160 --> 00:15:58,085
the line to the left force,

270
00:15:58,085 --> 00:16:01,520
and I'm going to just reduce

271
00:16:01,520 --> 00:16:03,260
a little bit of the
visibility of that line.

272
00:16:03,260 --> 00:16:07,535
It's getting in the way of
the rest of the drawing.

273
00:16:07,535 --> 00:16:10,280
We still want something that is,

274
00:16:10,280 --> 00:16:12,170
so you can see here maybe it's

275
00:16:12,170 --> 00:16:14,450
a little bit too transparent.

276
00:16:14,450 --> 00:16:15,770
But as you can see,

277
00:16:15,770 --> 00:16:17,165
the particles are telling us,

278
00:16:17,165 --> 00:16:21,200
Oh, this would be the
closest force to me,

279
00:16:21,200 --> 00:16:24,275
and we're going to do an
exercise when we apply

280
00:16:24,275 --> 00:16:28,595
forces of a singular
force around us,

281
00:16:28,595 --> 00:16:34,985
and that force will be the
closest force around us.

282
00:16:34,985 --> 00:16:39,300
Each particle would be influenced
by this closest force.

283
00:16:40,000 --> 00:16:42,095
That's it for this one.

284
00:16:42,095 --> 00:16:45,605
It's an algorithm that
initially might sound

285
00:16:45,605 --> 00:16:48,245
a little bit complicated

286
00:16:48,245 --> 00:16:50,540
but as you start
really using it,

287
00:16:50,540 --> 00:16:53,150
you realize that it's an
incredibly useful algorithm

288
00:16:53,150 --> 00:16:55,340
that you could use in
many different occasions.

289
00:16:55,340 --> 00:16:57,840
I'll see you in the next video.