1
00:00:06,728 --> 00:00:08,702
Hi, welcome to this new lesson.

2
00:00:08,702 --> 00:00:14,598
We are going to continue talking about
behaviors that operate between classes.

3
00:00:14,598 --> 00:00:16,638
How do classes interact with one another?

4
00:00:16,638 --> 00:00:19,222
Especially what happens when
we have large populations.

5
00:00:19,222 --> 00:00:22,872
At some point, we will start having
challenges that have to do with

6
00:00:22,872 --> 00:00:25,662
the computational
complexity of the problem.

7
00:00:25,662 --> 00:00:30,687
How many calculations can we really
perform, especially if we are looking into

8
00:00:30,687 --> 00:00:35,862
real time computations, if we are actually
not so interested in how long a certain

9
00:00:35,862 --> 00:00:41,082
computation will take, maybe that's
something that we can avoid as a problem.

10
00:00:41,082 --> 00:00:46,046
But often it's important that we are aware
of how much computational complexity

11
00:00:46,046 --> 00:00:47,954
is involved in a problem.

12
00:00:47,954 --> 00:00:50,696
So with that, let's jump into the code and

13
00:00:50,696 --> 00:00:53,904
start understanding what I mean by this,
right?

14
00:00:55,244 --> 00:00:57,124
So, here we are.

15
00:00:57,124 --> 00:01:02,296
If you remember where we left off,
we have this gradient rectangle class,

16
00:01:02,296 --> 00:01:04,828
which is basically a bouncing box.

17
00:01:04,828 --> 00:01:08,084
Let's just kind of bring down
some of these variables.

18
00:01:08,084 --> 00:01:10,584
Maybe we wanted to have 20 of these.

19
00:01:12,484 --> 00:01:17,506
And we will actually turn
on the background for

20
00:01:17,506 --> 00:01:24,088
every frame so that we can
actually see them better, right?

21
00:01:24,088 --> 00:01:25,203
There we go.

22
00:01:25,203 --> 00:01:27,350
We also would like to.

23
00:01:27,350 --> 00:01:30,709
Let's just remove out
of this in our class.

24
00:01:30,709 --> 00:01:35,137
We have a run function that
operates as a dashboard, in a way,

25
00:01:35,137 --> 00:01:37,326
to control everything else.

26
00:01:37,326 --> 00:01:40,842
So let's just turn off the bounce_color so

27
00:01:40,842 --> 00:01:45,694
that we can actually see them
more clearly as a single color.

28
00:01:45,694 --> 00:01:53,874
And we could even start with
a color such as maybe white.

29
00:01:55,854 --> 00:01:59,634
Our beginning first color will be white.

30
00:02:01,174 --> 00:02:05,094
And you can leave on
bounce_with_each_other.

31
00:02:05,094 --> 00:02:07,310
That's a function that we just covered.

32
00:02:07,310 --> 00:02:12,916
But actually,
we will leave a bit of room here to

33
00:02:12,916 --> 00:02:19,328
actually write a function for
line in range, right?

34
00:02:19,328 --> 00:02:21,597
So this is going to be
a form of display function.

35
00:02:25,534 --> 00:02:30,496
Let me just make sure that we are kind
of doing well with the white rectangles.

36
00:02:30,496 --> 00:02:35,184
Let's turn off for
a moment the bounce with color.

37
00:02:35,184 --> 00:02:36,880
We can bring it back in a minute.

38
00:02:36,880 --> 00:02:41,636
But this function is new, and
it's going to make it more clear if we're

39
00:02:41,636 --> 00:02:46,310
actually not necessarily seeing
the bouncing with each other, but

40
00:02:46,310 --> 00:02:51,512
just isolating with the bouncing
behavior of these rectangles, right?

41
00:02:51,512 --> 00:02:54,800
So let's define this line within range,
right?

42
00:02:54,800 --> 00:02:59,367
So, line to others, and

43
00:02:59,367 --> 00:03:07,204
let's just call it line to others for now.

44
00:03:08,424 --> 00:03:14,884
And there we go.

45
00:03:16,704 --> 00:03:19,264
So let's think about this problem, right?

46
00:03:19,264 --> 00:03:24,664
How could we, based on what we've learned
on this other calculation, right?

47
00:03:24,664 --> 00:03:29,107
We could even do something very
similar to what we've done

48
00:03:29,107 --> 00:03:32,924
before here to find our adjacent unit up,
right?

49
00:03:34,044 --> 00:03:39,355
Saying if our index is bigger than zero,
the other entity

50
00:03:39,355 --> 00:03:44,790
up would be this one, right,
the index above me, right?

51
00:03:44,790 --> 00:03:49,205
We could at this point draw a line, right?

52
00:03:49,205 --> 00:03:57,227
Let's just do a line that goes
from self.vec_position.x,

53
00:04:03,532 --> 00:04:12,668
To, self position.y, right?

54
00:04:12,668 --> 00:04:15,136
Those are the first two coordinates.

55
00:04:15,136 --> 00:04:18,584
And in the other case,
we could use the other, right?

56
00:04:18,584 --> 00:04:25,711
So, Let's do that, right?

57
00:04:25,711 --> 00:04:29,353
So this is a line, and
let's just give it a color as well.

58
00:04:29,353 --> 00:04:36,427
So stroke(255), and
then fill or strokeWeight.

59
00:04:43,404 --> 00:04:48,116
StrokeWeight, strokeWeight gives
us the thickness of the line.

60
00:04:48,116 --> 00:04:51,942
So let's just start with
something rather thick, and

61
00:04:51,942 --> 00:04:58,304
then we can calibrate it to something
that it's more graphically pleasing.

62
00:04:58,304 --> 00:05:01,432
So let's understand what
this line of code is saying.

63
00:05:01,432 --> 00:05:05,543
It's saying let's find our neighbor
above us, which is the same thing that

64
00:05:05,543 --> 00:05:09,216
we did before, and let's draw
a line between us and that entity.

65
00:05:09,216 --> 00:05:14,129
And only do this if you are the second
entity in the list or beyond, right,

66
00:05:14,129 --> 00:05:15,484
until the last one.

67
00:05:18,234 --> 00:05:23,035
If you're wondering how come we're
actually drawing all these lines without

68
00:05:23,035 --> 00:05:27,946
a loop at all is that you have to remember
that we are within the class, right?

69
00:05:27,946 --> 00:05:32,473
We are writing behaviors from
within the class and the class,

70
00:05:32,473 --> 00:05:37,602
each one of these instances of
the class is being executed in a loop.

71
00:05:37,602 --> 00:05:40,420
So when we're writing these functions,

72
00:05:40,420 --> 00:05:45,732
we have to be considering that we're not
trying to draw lines to all entities,

73
00:05:45,732 --> 00:05:49,642
but only entities with
a particular relationship to us.

74
00:05:49,642 --> 00:05:52,242
In this case,
being above us in the list, right?

75
00:05:52,242 --> 00:05:57,646
So let's just see if this line_to_others

76
00:05:57,646 --> 00:06:02,912
function is working as expected, right?

77
00:06:02,912 --> 00:06:04,536
Let's start.

78
00:06:04,536 --> 00:06:05,873
Let's just add the self.

79
00:06:11,399 --> 00:06:13,314
So here we go.

80
00:06:13,314 --> 00:06:14,570
We have these lines.

81
00:06:14,570 --> 00:06:20,785
If you see these lines, it's not
a very pretty drawing, perhaps, but

82
00:06:20,785 --> 00:06:27,978
it does kind of explain the relationship
that these units have with one another.

83
00:06:27,978 --> 00:06:33,321
This is very close to the way in which
you could actually draw polylines,

84
00:06:33,321 --> 00:06:37,562
vertices, points, and
then lines that connect them.

85
00:06:37,562 --> 00:06:42,428
We're getting a little bit into ideas of
how data structures could be connected to

86
00:06:42,428 --> 00:06:46,668
geometry, but this is not exactly
where I would like to go with this.

87
00:06:46,668 --> 00:06:51,540
This is kind of a very simple computation
where we know our next neighbor is above

88
00:06:51,540 --> 00:06:52,436
us, right?

89
00:06:52,436 --> 00:06:57,845
But what if the situation changes and
we want to be able to make lines

90
00:06:57,845 --> 00:07:03,996
to any neighbors around me that
are perhaps within a certain range, then.

91
00:07:03,996 --> 00:07:09,433
Well, what we need to do is calculate our
distance to each one of the entities and

92
00:07:09,433 --> 00:07:13,714
determine, are there within
specific boundary condition?

93
00:07:13,714 --> 00:07:17,767
And this computation will start getting
more expensive because every entity will

94
00:07:17,767 --> 00:07:20,378
have to loop through every other entity,
right?

95
00:07:20,378 --> 00:07:25,434
So let's write it down and evaluate.

96
00:07:25,434 --> 00:07:30,802
Why is it more complex
than what we've done here.

97
00:07:30,802 --> 00:07:34,498
So I'm going to actually copy paste this
function because this function might be

98
00:07:34,498 --> 00:07:35,284
useful for you.

99
00:07:37,920 --> 00:07:43,399
You might want to leave it, For

100
00:07:43,399 --> 00:07:48,594
your own kind of research and
your own kind of study of these functions.

101
00:07:48,594 --> 00:07:53,174
So we can change the name of this second
function line to others in range.

102
00:07:56,754 --> 00:08:00,386
And it's going to use
the same principle of this.

103
00:08:00,386 --> 00:08:03,360
>> Previous function, but let's change it.

104
00:08:03,360 --> 00:08:09,976
So I'm going to comment out the previous
function and call this function, right?

105
00:08:09,976 --> 00:08:12,208
So this function is going to be executed.

106
00:08:12,208 --> 00:08:15,724
The other one we're commenting
out because that was kind of

107
00:08:15,724 --> 00:08:18,040
a small demonstration, right?

108
00:08:18,040 --> 00:08:23,363
Hopefully at this point, you are familiar
with the idea of how certain functions or

109
00:08:23,363 --> 00:08:28,250
methods, we call methods the functions
that are within a class, right?

110
00:08:28,250 --> 00:08:30,778
How these methods could be left behind.

111
00:08:30,778 --> 00:08:35,339
If we don't ever call them within
the class, they become archived in a way.

112
00:08:35,339 --> 00:08:36,730
They're basically not executed.

113
00:08:36,730 --> 00:08:41,780
But it's good sometimes to just
keep methods that are useful or

114
00:08:41,780 --> 00:08:46,610
might kind of bring ideas for
future behaviors, right?

115
00:08:46,610 --> 00:08:50,010
So what would make
the range calculation work?

116
00:08:50,010 --> 00:08:54,766
Well, first of all,
we need to do a loop, right?

117
00:08:54,766 --> 00:08:59,605
So we could say here for other in

118
00:08:59,605 --> 00:09:04,455
self., let's use the list.

119
00:09:08,886 --> 00:09:11,302
In the others list, right?

120
00:09:11,302 --> 00:09:12,926
So that's the loop, right?

121
00:09:12,926 --> 00:09:15,139
What are we looking for in the loop?

122
00:09:15,139 --> 00:09:23,722
If, other is not self, right?

123
00:09:23,722 --> 00:09:27,993
This is important because
we do not want to calculate

124
00:09:27,993 --> 00:09:30,874
a distance to ourselves, right?

125
00:09:30,874 --> 00:09:33,317
And we can actually get
rid of this statement now.

126
00:09:37,702 --> 00:09:39,340
Let's calculate the distance.

127
00:09:41,490 --> 00:09:45,694
The difference will be

128
00:09:45,694 --> 00:09:51,942
represented by the p vector sub.

129
00:09:51,942 --> 00:09:55,575
So we're going to do a subtraction
between the vector of position,

130
00:09:55,575 --> 00:09:56,970
our vector of position.

131
00:09:58,790 --> 00:10:03,129
When I say our, I'm kind of speaking
from within the class, right?

132
00:10:03,129 --> 00:10:06,670
I'm speaking as if I'm kind of
when I'm writing within a class,

133
00:10:06,670 --> 00:10:09,534
I start thinking of I'm this rectangle,
right?

134
00:10:09,534 --> 00:10:12,049
How do I kind of relate
to another rectangle and

135
00:10:12,049 --> 00:10:15,030
how do I draw aligned to
that other rectangle, right?

136
00:10:16,130 --> 00:10:21,147
So I'm going to do a subtraction
between my position,

137
00:10:21,147 --> 00:10:26,401
that is, a self, right,
.position, to an, oops.

138
00:10:29,879 --> 00:10:35,480
Let me just correct that,
self.position to the other,

139
00:10:37,955 --> 00:10:42,043
.position, right?

140
00:10:42,043 --> 00:10:46,133
So we're calculating d,
if you remember the vector and

141
00:10:46,133 --> 00:10:51,206
the subtraction between two vectors
is the distance between them.

142
00:10:51,206 --> 00:10:56,672
It's very useful to understand the vector.

143
00:10:56,672 --> 00:11:01,073
Basically, if we calculate the magnitude
of this subtraction vector,

144
00:11:01,073 --> 00:11:04,638
we will actually get distance
between these two points.

145
00:11:04,638 --> 00:11:10,780
So the distance is
the difference magnitude,

146
00:11:10,780 --> 00:11:15,660
and this is the way we actually ask for

147
00:11:15,660 --> 00:11:21,850
the magnitude of that vector, right.

148
00:11:21,850 --> 00:11:24,519
So with this distance value,

149
00:11:24,519 --> 00:11:30,754
we actually should have a way of
evaluating if we want to draw a line.

150
00:11:30,754 --> 00:11:32,322
And we will be able to draw this line.

151
00:11:32,322 --> 00:11:37,067
Notice that this line actually right
now is not just a line as we were

152
00:11:37,067 --> 00:11:39,712
doing before to our one neighbor up.

153
00:11:39,712 --> 00:11:42,870
But it's a line to, potentially,

154
00:11:42,870 --> 00:11:48,178
if we actually correct,
this line is actually incorrect.

155
00:11:48,178 --> 00:11:53,249
But let's just, We're going to

156
00:11:53,249 --> 00:12:00,018
do a line to each entity that is within
a particular range, a distance, right?

157
00:12:00,018 --> 00:12:06,152
So if the distance is smaller than,
let's say something like 50,

158
00:12:06,152 --> 00:12:11,227
let's just start with a value,
like a hard coded value,

159
00:12:11,227 --> 00:12:14,430
we will actually execute the line.

160
00:12:15,890 --> 00:12:17,590
So let's do this.

161
00:12:22,110 --> 00:12:27,534
So in this time,
let's just do a slightly thinner line.

162
00:12:27,534 --> 00:12:30,486
And who is this line in between?

163
00:12:30,486 --> 00:12:35,174
This line is between self,
so x, y, and other.

164
00:12:35,174 --> 00:12:39,838
But in this case, the other, we named
the other based on the loop, right?

165
00:12:39,838 --> 00:12:41,574
So for other, the entity.

166
00:12:41,574 --> 00:12:45,094
Other is each entity as we're
going through the list.

167
00:12:45,094 --> 00:12:50,090
So it's not the other_up
that we had used before, but

168
00:12:50,090 --> 00:12:53,356
it's this entity within the loop.

169
00:12:55,112 --> 00:12:57,033
And that should be it.

170
00:12:57,033 --> 00:13:02,629
What we're trying to do here is any
entity within 50 units of radius,

171
00:13:02,629 --> 00:13:05,440
we will draw a line to them, right?

172
00:13:06,820 --> 00:13:11,877
And this is one of the very traditional
examples that is used in creative

173
00:13:11,877 --> 00:13:17,082
coding to understand how entities
calculate proximity to one another.

174
00:13:17,082 --> 00:13:21,270
But because we have this for
loop, and this is a class,

175
00:13:21,270 --> 00:13:25,226
we are actually doing a loop
within a loop, right?

176
00:13:25,226 --> 00:13:29,490
It means that every class
is being run as a loop.

177
00:13:29,490 --> 00:13:31,682
So we run through all the classes and

178
00:13:31,682 --> 00:13:35,650
each one of those classes will
loop through every other class.

179
00:13:35,650 --> 00:13:39,092
So we're actually increasing,
quite importantly,

180
00:13:39,092 --> 00:13:44,460
the amount of computational complexity of
this problem, of this system, in a way.

181
00:13:44,460 --> 00:13:48,419
And if you start seeing your computer
lag and starting to run slower,

182
00:13:48,419 --> 00:13:52,387
it's because we are indeed kind of
doing quite a bit of computation.

183
00:13:52,387 --> 00:13:57,668
Or a lot more than what we used
to do in this previous example,

184
00:13:57,668 --> 00:14:01,404
where we were just finding our neighbor.

185
00:14:01,404 --> 00:14:05,374
And that was basically we knew that
our neighbor was the adjacent entity

186
00:14:05,374 --> 00:14:06,164
in the list.

187
00:14:06,164 --> 00:14:10,326
In this case, we're actually searching for
them in a list.

188
00:14:10,326 --> 00:14:12,010
So let's see how this looks.

189
00:14:13,910 --> 00:14:17,690
So we are running into
some indentation issues.

190
00:14:22,310 --> 00:14:25,350
Think that's what?

191
00:14:25,350 --> 00:14:32,133
So we have the for loop,
the if statement, and only if.

192
00:14:32,133 --> 00:14:33,147
Let's see.

193
00:14:35,690 --> 00:14:41,670
So we can see some lines.

194
00:14:43,210 --> 00:14:46,705
If you pay attention,
you can probably see them, but

195
00:14:46,705 --> 00:14:50,506
there are not too many of them,
and they're very small.

196
00:14:50,506 --> 00:14:52,430
Let's just increase that value, right?

197
00:14:53,610 --> 00:14:59,230
Let's say that we want to do it over 200,
right?

198
00:15:00,750 --> 00:15:07,114
So you can see now these lines appear and
disappear,

199
00:15:07,114 --> 00:15:13,050
depending if an entity
is within 200 pixels.

200
00:15:16,390 --> 00:15:19,334
So, yeah, this is great.

201
00:15:19,334 --> 00:15:20,798
This is actually working.

202
00:15:20,798 --> 00:15:24,304
This is kind of a system
that is kind of quite used,

203
00:15:24,304 --> 00:15:29,636
kind of a graphic representation of
lines between objects in proximity.

204
00:15:29,636 --> 00:15:34,509
A few things that you can do if
you want to do the system slightly

205
00:15:34,509 --> 00:15:37,240
different you might also want to.

206
00:15:39,340 --> 00:15:41,988
Instead of doing the lines right,

207
00:15:41,988 --> 00:15:47,009
which I find sometimes the most
obvious way of visualizing this,

208
00:15:47,009 --> 00:15:52,137
you might consider that you want
to do something like, no, fill.

209
00:16:01,696 --> 00:16:04,595
Let's change to ellipseMode(CENTER),

210
00:16:04,595 --> 00:16:08,836
meaning that we could actually
draw an ellipse with its center.

211
00:16:12,674 --> 00:16:17,321
And the ellipse that we want to draw here.

212
00:16:17,321 --> 00:16:21,744
Let's just copy the information that
we've done for the rectangle, right?

213
00:16:27,384 --> 00:16:32,024
So this is the coordinate
of the rectangle.

214
00:16:32,024 --> 00:16:33,928
We could actually say,
hey, I want to do that.

215
00:16:33,928 --> 00:16:36,672
The size times 2.

216
00:16:36,672 --> 00:16:39,964
So whatever your size is
supposed to be times two.

217
00:16:41,984 --> 00:16:46,779
And then for good measure,

218
00:16:46,779 --> 00:16:51,992
go back to no stroke, because

219
00:16:51,992 --> 00:16:58,848
we are starting with the stroke here.

220
00:16:58,848 --> 00:17:01,756
So what this would actually create, and

221
00:17:01,756 --> 00:17:05,443
if we actually create a few
more of these entities.

222
00:17:05,443 --> 00:17:08,287
Let's go up to 50.

223
00:17:08,287 --> 00:17:14,597
We could actually see, and
you'll see that this starts to lag,

224
00:17:19,630 --> 00:17:23,404
Due to the nested loops, right?

225
00:17:23,404 --> 00:17:27,956
Depending on the system that you're
running, depending on your computer,

226
00:17:27,956 --> 00:17:31,107
we are actually running
processing through Python,

227
00:17:31,107 --> 00:17:35,764
which is perhaps the most optimized
version for real time graphics.

228
00:17:35,764 --> 00:17:40,517
You can actually have very performative
real time graphics in other systems

229
00:17:40,517 --> 00:17:41,260
as well.

230
00:17:41,260 --> 00:17:45,436
But we certainly wanted to operate
within the ecology of code of Python.

231
00:17:45,436 --> 00:17:47,834
Therefore, we've been running it here.

232
00:17:49,574 --> 00:17:52,334
We actually lost the lines, right?

233
00:17:52,334 --> 00:17:55,354
That maybe made this whole thing
a little bit more visible.

234
00:17:59,454 --> 00:18:01,114
What else can we do here?

235
00:18:02,334 --> 00:18:06,431
I feel like the ellipse center,

236
00:18:06,431 --> 00:18:12,349
it's not really giving
us the result we want,

237
00:18:12,349 --> 00:18:16,614
if you wanted this ellipse to be.

238
00:18:20,474 --> 00:18:22,490
Yeah, it's kind of working.

239
00:18:22,490 --> 00:18:28,029
We can actually, As you can see here,

240
00:18:31,060 --> 00:18:36,017
Turn off the draw for
those rectangles, right?

241
00:18:36,017 --> 00:18:42,911
And then rely almost exclusively
on this ellipse information.

242
00:18:42,911 --> 00:18:49,247
And again,
playing with the line thickness,

243
00:18:49,247 --> 00:18:56,078
0.5, you can actually
go below the one pixel.

244
00:18:56,078 --> 00:18:59,814
So you could actually start getting this
kind of thinner line representation.

245
00:18:59,814 --> 00:19:01,714
You've probably seen these
kind of drawings before.

246
00:19:02,954 --> 00:19:07,467
It's something that is quite
used within code structures,

247
00:19:07,467 --> 00:19:12,682
especially when you're learning
how to do distance calculations.

248
00:19:12,682 --> 00:19:17,267
But just to wrap it up, this function,
again, a lot of flexibility,

249
00:19:17,267 --> 00:19:20,194
but it comes at a computational cost.

250
00:19:20,194 --> 00:19:23,258
It comes at the computational cost
of having a loop within a loop.

251
00:19:23,258 --> 00:19:27,992
And the bigger the number of entities
that you might want to include here,

252
00:19:27,992 --> 00:19:32,424
you would see your performance
running slower and slower, right?

253
00:19:34,444 --> 00:19:37,857
And there are ways of kind of
optimizing these systems for

254
00:19:37,857 --> 00:19:39,500
them to run a lot smoother.

255
00:19:39,500 --> 00:19:45,417
We will potentially getting those
into the next specialization.

256
00:19:45,417 --> 00:19:49,766
They have to do with kind of not really
looping through all entities, but

257
00:19:49,766 --> 00:19:52,978
looping through entities
that you might already know

258
00:19:52,978 --> 00:19:55,901
that are closer to you
based on space partition,

259
00:19:55,901 --> 00:20:00,750
a way in which we could actually subdivide
the space in a grid and already know that

260
00:20:00,750 --> 00:20:04,866
some entities are dynamically
changing between sectors in a way.

261
00:20:04,866 --> 00:20:09,739
So there are clever ways in which we could
actually make the computational complexity

262
00:20:09,739 --> 00:20:14,354
of a problem be resolved and
still maintain good performance, right?

263
00:20:14,354 --> 00:20:18,120
But as we're learning, we are actually
reaching the point where, for

264
00:20:18,120 --> 00:20:22,390
the first time, we're actually doing
a loop that searches through all entities

265
00:20:22,390 --> 00:20:24,362
from within an entity like class.

266
00:20:24,362 --> 00:20:29,145
Therefore, the computational complexity
is starting to be visible, right?

267
00:20:29,145 --> 00:20:32,788
So I'm going to leave this session here,
and I'll see you in the next one,

268
00:20:32,788 --> 00:20:36,401
where we're going to start really
kind of converting some of our old code.

269
00:20:36,401 --> 00:20:38,910
Especially our kind of ants and

270
00:20:38,910 --> 00:20:43,964
kind of grid systems into
object-oriented interactions.

271
00:20:43,964 --> 00:20:47,084
So we're going to be wrapping it up here,
and I'll see you in the next video.