We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Animations from first principles

00:00

Formal Metadata

Title
Animations from first principles
Title of Series
Number of Parts
131
Author
Contributors
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
How do you create an animation? What if you want to morph a circle into a figure eight? As it turns out, all you need is two or three functions and a loop! In this live-coded talk, we'll go over the basic concepts and code needed to create an animation _from first principles_. Because the talk presents the ideas and the code from first principles, you will be able to take the key concepts and build your own animations after! We'll start simple and build from there: - How can you draw a circle if all you can do is colour single pixels? - How can you animate the process of drawing a circle? - How can you animate the process of drawing something other than a circle? - How can you animate the process of morphing two figures? - How do you add colour to your animations? This visually appealing talk will show you all of the code without skipping a single line and by the time we're done you'll be jumping in your seat to create your own animations!
System on a chipOrdinary differential equationAnalog-to-digital converterCodeMultiplication signIntegrated development environmentCodeDampingRight angleDifferent (Kate Ryan album)Row (database)WordVirtual realityScaling (geometry)Set (mathematics)Game theoryRootComputer animationLecture/Conference
Web pageMachine codeWindowView (database)Addressing modeLetterpress printingWoven fabricComa BerenicesComputer fileTouchscreenRouter (computing)outputElectronic visual displayCodeScripting languageDifferential (mechanical device)Computer fontDesign of experimentsPseudodifferentialoperatorVideoconferencingValue-added networkComputer iconProduct (business)Computer fileSet (mathematics)RectangleEllipseDisk read-and-write headSingle-precision floating-point formatCircleFigurate numberFunctional (mathematics)CodeTouchscreenPixelMultiplication signWordRow (database)MereologySquare numberLine (geometry)Cheat <Computerspiel>Point (geometry)Primitive (album)Module (mathematics)BitGame theorySoftware bugDirac delta functionPosition operatorSource codeComputer animation
Web browserCollaborationismOpen setOnline helpSign (mathematics)WindowBookmark (World Wide Web)View (database)Electronic visual displayProduct (business)TouchscreenoutputHand fanMachine codeRange (statistics)UsabilityLoginDisintegrationGastropod shellError correction modelMaximum likelihoodComputer configurationPressureValue-added networkTrigonometric functionsScripting languageTerm (mathematics)PixelTrigonometric functionsFunctional (mathematics)Sampling (statistics)Well-formed formulaPoint (geometry)PixelMultiplication signPosition operatorVideo gameRotationTerm (mathematics)CircleMathematicsTouchscreenNumbering schemeArithmetic progressionNeuroinformatikoutputReal numberWindowIntegerGame theoryLatent heatLoop (music)Disk read-and-write headAnalytic continuationTotal S.A.Programmer (hardware)CodeElectronic visual displayRadiusWeb pageLie groupRight angleCommunications protocolComputer programmingComputer animation
Range (statistics)TouchscreenWindowView (database)Machine codeSpiraloutputScripting languageTerm (mathematics)Electronic visual displayRootRouter (computing)Beer steinGame theoryPortable communications deviceMultimediaLibrary (computing)Surjective functionFormal languageComputer programCircle2 (number)Receiver operating characteristicComputer iconComputer multitaskingHand fanMaximum likelihoodComputer engineeringClefBookmark (World Wide Web)TouchscreenDemo (music)CircleBit rateMultiplication signPixelFigurate numberNeuroinformatikPoint (geometry)Numbering schemePosition operatorSpiralFunctional (mathematics)Video gameAxiom of choiceWeb pageMedical imagingMathematicsWell-formed formulaGreatest elementWhiteboardShape (magazine)String (computer science)Fluid staticsGoodness of fitSign (mathematics)RadiusType theoryArithmetic progressionSet (mathematics)Disk read-and-write headParametrische Erregung8 (number)Computer animation
View (database)Online helpMachine codeWindowTouchscreenRange (statistics)outputSpiralElectronic visual displayScripting languageState of matterAlpha (investment)Dynamic random-access memoryMorphingSystem of linear equationsCodeFunctional (mathematics)Position operatorArithmetic progressionTouchscreenLoop (music)Right angleAverageMultiplication signDivisorMedical imagingAlpha (investment)Level (video gaming)Frame problemMorphingCircleArrow of timeTotal S.A.Point (geometry)Figurate numberWell-formed formulaInterpolationVideoconferencingNumbering schemeEstimationType theoryRow (database)MathematicsSpiralParameter (computer programming)ImplementationInterior (topology)Building8 (number)Greatest elementComputer animation
TouchscreenWindowView (database)Range (statistics)outputRootElectronic visual displayAlpha (investment)MorphingMachine codeComputer fileCodeGame theoryNetwork switching subsystemScripting languageTerm (mathematics)Dot productMetreSpiralComa BerenicesRouter (computing)ClefPixelCountingLogic gateInterrupt <Informatik>Keyboard shortcutCodeMultiplication signProcess (computing)SpiralGoodness of fitFunctional (mathematics)Arithmetic progressionDesign by contractMathematicsPerfect groupMedical imagingPixelVolumenvisualisierungLoop (music)Well-formed formulaDemo (music)TouchscreenMeasurementFeedbackProgrammschleifeForm (programming)CircleMultiplication tableExpandierender GraphSeries (mathematics)Frame problemRow (database)MereologyDegree (graph theory)Transformation (genetics)Video gameNeuroinformatikChronometryRight angleNumbering schemeComputer animationSource code
Roundness (object)Control flowLevel (video gaming)Right angleLecture/ConferenceComputer animation
Transcript: English(auto-generated)
Hi everyone. It's a pleasure to be here. I'm very excited. But I'm also very nervous because it's the first time my wife is watching live. So if this goes wrong, it will be the end of a short but happy marriage. So please root for me.
As was said, I'll be showing you how to create some simple 2D animations from first principles. I talked to a couple of people before today and I realized that maybe I fooled you, not on purpose, maybe on purpose. But the talk is marked as advanced. It's not because we're going to be seeing lots of very advanced animations. I'm not going to render a Pixar movie right now.
I'm going to be showing you actually quite quote unquote simple concepts. It's just that when I write the code for those concepts, I don't want to have to worry to explain the code. So that's why I marked it as advanced, as in if you feel comfortable with Python, then that should be enough. You don't have to be a pro.
So that's an important disclaimer. Now, I also have a couple of other disclaimers and questions to ask you. But the main thing is that I want to show you that there's no tricks up my sleeves. I'm wearing a short-sleeved shirt and I'm going to be doing everything from scratch in front of you. I'll just be setting up a virtual environment and installing some things while I ask you a couple of questions if that's okay.
So I'll start with the environments. Now, I wanted to know, on a scale from 1 to 10, how goofy slash playful are you guys feeling today? This is actually an honest question. Do we have people feeling playful here or are you in a more, you know, serious kind of vibe?
This is very, very serious. We have to, we can't smile. Yeah, playful, okay. Because I've noticed I have an issue. And that is, well, I have plenty of issues as my wife could tell you. But I have one important one for today which is when I'm presenting, I tend to start lots of sentences with so, and it becomes annoying and repetitive.
And I found out, well, yeah, I found out about this game that they played in a different PyCon conference at Lightning Talks. There was this forbidden word. And when the speaker said it, the audience was supposed to quack. And I found it funny. And I think that might help me get through the issue
of starting all my sentences with so. So, if you're feeling up for it, we could play. When you get tired of it, it's fine. It's gonna die out, it's fine. But just bear with me because it's really annoying. I'm watching my own recordings and I keep hearing myself saying so, so, so, so it's so annoying, very, very annoying.
All right, so, right. I'm very close to being set up. I just need to install PyGame which thankfully is cached. And I also need to copy a couple of IDE settings so that the font size is big enough. Otherwise, people are going to complain because they always do. So, I just need to copy the settings here.
Thank you. And we should be good to go up to creating a new file, saving it as talk.py because that's the best name ever. Now, I've been told that a dark font, sorry, a dark theme might not be great at these kinds of settings. So, people at the back, do you prefer this?
Please don't hate me, or this? What's best? Is this more readable? All right, so, I'll put my own well-being aside for you guys. We'll go, because I think we all know this joke but lights attracts bugs, right?
So, that's gonna be the excuse for, thank you. Thank you, I appreciate it. Lots of effort went into making this talk. I'm gonna start from first principles and really it's not that, I have to start somewhere, right? And I'm going to start with pygame. Not necessarily because pygame is the best tool to create animations.
It's just because it's something I know that can put pixels on the screen. And that's our starting point. Let's assume we can color pixels on the screen. All right, and we're going to build from that. To get a screen, I just need to initialize pygame. It's not the most interesting thing ever. Let's define a constant because why wouldn't you?
Let's make it 600 by 600. Hopefully, it's going to be big enough. So, that's my screen. Now, I always have an issue which is, I don't know which is white and which is black, but I think it's this one. We'll figure it out very soon. And what I'll do now is I'll fill my screen with a single color if I'm gonna,
what did I do? Oh, okay. I was playing it back in my head. Apologies for that. And now, I'll do the following. I'll move this on the side because we don't really care about that. It's gonna take a second
because it's the first time pygame is running and we should see a white screen, hopefully. Okay, so did I really get them wrong? Apparently, yes. I was pretty sure. Ah, okay, yes, I'm fine. I forgot to do something. I always forget to do this at some point or another.
I was about to say so. When you draw something on the screen, you then need to tell pygame, hey, please update what the user is seeing. So that's what this line does. That's why the screen was black. All right, so I managed to get the colors correct. Could I get an applause, please? This is the hardest part. Thank you.
That's genuinely the part where I failed the most, but then I had forgotten to update the screen. Very nice. Now, I said we could draw pixels on the screen, so maybe I could show you how to do that. And pygame does provide a function or rather a method to do that, but I just want to hide that behind this function
because it's going to be clearer in the code when you see draw pixel. It's going to be better. So we'll say that this takes a screen, some positions, and a color, and we just defer to the method that pygame gives us, which is set x. This is all we're going to do. And if we have a screen that's filled with whites, I can use my function draw pixel on my screen,
and I'll paint a black pixel smack dead in the middle. Now, there's going to be an issue with that. Can you see the pixel? Really? Are you lying? Well, it's there. It's tiny. So what I'll do is I'll cheat a little bit
because why wouldn't I? It's my talk. I do what I want. And from ITER tools, I'm just going to, in my function draw pixel, instead of only drawing a pixel, I just draw a small region around it to make it larger for you. Are you fine with cheating like that?
Yes, it's permissible, I heard in the front row. It's a complicated word for someone who's typing and talking at the same time. And clearly I failed because I forgot to add my deltas. Fine. This was boring, but we need to start somewhere.
Let's start with drawing because if I want to animate something, maybe I should draw it first. Pygame and lots of other modules or packages that let you deal with graphics, they tend to have primitives that let you draw lines and circles and ellipses and rectangles. These are pretty common. But someone has to have implemented those.
And what I want to show you is how you can implement those because as soon as you know how to implement one, you can implement as many as you want and you can draw way more interesting things than just circles and ellipses and rectangles and squares and that's why we're starting from there. Now I forgot a very important part of my setup
which was to open a place where I could draw. Alrighty, so I'll do the following. I'll draw a circle right in front of you. It's not going to be perfect, but you'll have to excuse me. Also take note of where I'm starting. I'm more or less at the right of the page, yeah? You can all see that. I'm going to draw a circle, which is marvelous.
Almost. Almost. You all saw what I did, right? You saw me move the mouse. I'm going to be, I'll start talking about pens because it makes more sense in my head. So let's pretend I did that with a pen. Where, please answer my questions. Where did my pen start? In the screen, what was the position where it started?
On the right, yes. I'll mark the position. It was more or less around here, correct? This was the, the X marks the spot. Brilliant. So now let's play a game. It's admittedly a silly game, but let's play a game. Where was my pen when I was 25% done with my drawing?
At the top. You're very clever, thank you. When, I'm not joking. Some people take longer to realize what I'm asking. It's not that the question is difficult. It's just that sometimes my phrasing is terrible. So I was at the top. And when I was halfway done with the drawing, where was I? On the left side.
My left or your left? Yes. The answer is always yes. When someone asks A or B, the answer is yes. And where was I when I was 100% done with the drawing? Exactly, the same place. So this one. So this is both zero and 100%. Now I told you that this was going to be a game.
I also said it was not going to be very fun. I just give you a percentage and you return a position on the screen. That's what happens. Right? What I want to do now is, I'm a programmer, I try to. What I'll do is I'll write a Python function that accepts a percentage and plays the game for me. So it should return a position on the screen
that's going to match exactly where my pen was. Do you understand the statement? Excellent. So I will do that. If I, I was, so do you see, this is all of the windows I have opened and I was looking for my ID and I couldn't find it.
Because I'm just, I'm so used to having the black theme, I forgot, I forgot it was that thing. But it's here, it's here. This is no joke. I lost it for a second. I'm going to call this function circle and like I said, it takes a percentage and it's going to return a position on the screen. Something. So an X and a Y. Now what goes in here?
Apparently a formula. Yay! Who likes formulas? I know it's a bit early in the morning, but okay. No worries. I studied math so I kind of enjoy them sometimes. I will not go as far as explaining the actual mathematics
that goes into the exact formula. I'll just give a hand wavy explanation of some of the terms. I'm going to be using the cosine function which apparently is useful in real life. So that's good to know. And for Y, I'll be using the sine function, which is as useful as cosine.
These two terms are going to define more or less the rotation around the center of the circle. This is a very, I don't know if you know this, but cosine and sine will produce numbers between minus one and one. And my screen is 600 by 600. So that's going to be ridiculously small. So let's expand that.
I'm going to be multiplying by a bigger number which is going to act as the radius of my circle. So the radius, bless you. Oh, that was not someone sneezing, my bad. So this is the radius, which means that the circle is going to have a radius of a third of the screen. And I'll show it to you right now. Let's park this.
I have this function that plays our weird little game. Now I want to actually draw the circle. And how do I do that? Well, with code. Yes, sorry to break it to you. I can't say, I wish I could, but I can't say. So Python, not in, I'm not mad.
So Python draw circle and do something and use my circle function with Python draw. And it's going to take my function. It's going to do it automatically. I need to do something about it. And what I did with my hands, I just pressed the mouse and I did the circle motion. And then I released the mouse. That's a continuous thing. It's a continuous motion.
The Python doesn't, well, programming in general doesn't really handle continuous things. All I can do is loop over a specific number of steps. So what I'll do is I'll take my function circle and I'll take this idea of drawing from 0%. And this is the most important idea of the whole talk. It's that percentages start at zero and end at 100.
I'm going to go through that progress. And sorry, I'm going to stop along the way in a number of predefined places. And I'm going to look at the position of the pen for that percentage, as we did for the zero, the 25 and the 50. And I'm going to jot down those points.
And if I do that enough, it's going to look like a circle. It's not the circle. We know the truth, but it's going to look like a circle, which means this talk really is just about fooling you. You're sitting here out of your own volition. So if you're feeling betrayed,
I will be sad, but you're free to leave. I'm going to set the number of steps or the number of times I'm going to sample my percentage. And I'm going to iterate through it because that's the obvious way to do things in Python. Just write a loop. It's probably going to work. And I'll define the percentages as the ratio of the current step
over the total number of steps. And what will I do? I'll compute the position I met, sorry, not draw pixel. I'm going to use my function that does this computing. And then I draw the pixel, not on this fixed position, but on the one I just computed. When I'm done, I update the display,
and then I just wait for some input so that we have time to look at the circle. The problem is this doesn't work. This was expected. It's a simple fix. Pygame, when I'm drawing pixels, it's expecting X and Y to be integers, so let's just fix that. And this is the last time we need to change our function drawPixels. So this should be enough.
I can close that, and I can rerun the code, and we have some points. Can you see the points over there? Yeah. Can you tell me what's wrong? It's, yes, it's centered around the corner, or rather, it's not centered in the screen. One of the other important things about this talk,
so lots of things are going to be very important, because all I say is important. This was sarcasm. I'm going to show you that changing what happens in here changes the drawing itself. For example, if I add side over two over here, this will recenter the circle.
Not really a circle, but the 10 points we drew. And what I told you, which hopefully wasn't a lie, is that if I increase the number of steps, this is going to become closer and closer to an actual circle. Still not a circle, but it's getting there. And if I do 1,000 points, that's enough.
Now we have a circle. And I'm not sure if you've been paying attention, I'm just, I'm looking at the code, so I'm not looking at your faces enough, sorry. I'm not sure if you've been paying attention, but there's nothing special about the circle function. The only thing that's special is the protocol, quote unquote, or the way circle is supposed to work.
Remember, this function accepts a percentage and returns a position on the screen. It just happens to look like a circle. As long as I write a function that accepts a percentage and returns a position, I can draw whatever I want.
In mathematics, we call this a parametrization of the circle. The way I intuitively think of it is literally, I have the pen, the pen is moving, and as time goes by, I'm changing the position of the pen. It works for me. Let's try with a different function. I just said something, let's prove
that I'm not completely wrong. Let's write a parametrization of the figure eights. Everyone knows this formula by heart. If you don't, you should rethink your life choices. It's actually very simple. If you know the circle one, you'll know this one.
Now there's the time, this is where I type, and you just look at it, because I don't know what to say now, but I'm actually getting done. Notice it's actually very simple to the circle. It's the same functions, they're just swapped, and of course you put the four inside the sign because why wouldn't you?
And now what I do is I swap the circle for the figure eights, and hopefully it's gonna work. I'm always nervous before a live demo. What was special about this function? Nothing, it's a parametrization. It accepts a percentage, returns a position. You know this by heart. If you want to draw something, what do you need?
You need a parametrization, a function that accepts a percentage and returns a position. I'm really hammering this because it's going to be very important in not the next step, but the one after. To talk about animations, all we've seen is static images, boring. Let's animate this. What's an animation? Well, much like a drawing of what looks like
a continuous shape, it's just a bunch of points shown at the same time. An animation is a bunch of images that I show in quick succession. If the images are shown quickly enough, it's going to look like there's movement. That's the point. I'm pretty sure you all knew that. And still, I knew that and I was blown
when I got this to work. Well, what I'll do is instead of drawing the pixels a bunch of times and then updating the screen, I'll just update the screen more often. And believe it or not, that's enough to create an animation. Is there? Oh, interesting. Oh no, because did you notice that the bottom there was not filled,
but then somehow it was magically filled? I don't know what happens. Hopefully that doesn't happen again. This was enough, right? We just have an animation and it just, the only thing I needed to do was update the screen often enough. And that's really all there is to it. To just update the screen often enough.
Is there something special about figure eight? Well, clearly not. Clearly not. You can change this for any other parameterization and it's going to work the same. Again? What it's? Ah, okay. Because it's completed in my, let's run this again.
I'm not touching my, now if I touch my mouse, it feel, did you see that? I don't know, let's try again. Yes, okay, now if I, I see, okay. So when I run something, I need to keep moving my mouse, otherwise the image is not going to update. It's live debugging, folks.
And it went well, usually it goes wrong. What are we going to do next? Let's just draw one more figure because why wouldn't you? I have plenty of time to queue. Let's draw a spiral. And what's a spiral? It's really just a circle where the radius keeps changing. I'm so thankful that people just keep nodding. It's good, okay. I'm glad you're, I'm either saying easy things
or you're very clever or you're just trying to make me feel good. It's working, I appreciate it. Let me get rid of the docstring. The terrible thing about docstrings is that they easily get outdated, especially if you copy code around. I said that the radius needs to change and previously, 30 years ago, I told you
that this thing is the thing that's controlling the radius. I want it to change as time goes on or really as the pen moves, as the percentage or as the progress increases. And it turns out that multiplying something by a number does things. This was hopefully very clear. If I multiply by the percentage there,
what's going to happen is move my mouse. Did it also get janky there? Yes, so I can't move my mouse a lot. It's only when I'm done. So just keep learning. It didn't work because I forgot to update the spiral here. Oh, I'm sorry. I always forget something.
Thankfully, you're paying attention. So it's not very interesting, but it's a spiral. Let's make it do a couple more turns. The way you do this, remember, I said these one out of 10 very important things is the numbers here control what's shown. Do you see the two over here? This is controlling the number of turns. So if the two gives me one turn,
who can guess what number needs to go there so that I have two turns around the center? Four. Not 24, four. Excellent. Let's see if you learn this. So if four gives me two turns, what do I need for three turns?
Six. I love how you're very afraid. It's going to be okay, I promise. Six, and now if I want five turns, what do I need here? 10, excellent. Someone knows how to multiply by two, which is good. Now, it's no longer looking like a spiral.
What's the issue? The issue is that the spiral is too long for the number of sampling steps that I have. So we fix this, we just do more computations. You just do more work. It's always bigger is better, just more numbers. Yes, and it's filled again. Let's go with 3,000. If I make it bigger, then it's going to take a long time.
Are you guys keeping up so far? Brilliant. We've drawn, we've animated the drawings. Let's go to the next step. This is my favorite step. I was at home playing with this, and when I got it to work, I fell off my chair. Almost. I just felt like I should have fallen out of my chair. It was, it's not that it's technically super advanced,
it's just that it worked. I hope you feel the same way, otherwise it's going to be a very disappointing talk. Let's go to my drawing board. And let's do a drawing. Let me draw three pages. Now bear with me for a second as I draw a rectangle
and copy it over three times. Actually only just two, exactly. These, let's pretend that these are three pages, or the three, not the three. These are three images of the animation I want to create. And what I want to do live in front of you,
I've never practiced this, which is false, this is the first time I'm doing it, and you've been the best audience so far, I love it here in Prague. This is terrible, I can't live with myself. Yeah, this is not better. What I want to do is, please don't mock me,
I want to go from the circle to the figure eight. I want to animate this in some way that looks smooth, because I could just take the zero, sorry, the circle and replace it with the eights. It's animated, it's going to look terrible. So I want to do something in between the zero and the eights that looks cool and that hopefully gives me a ah
from the audience, that's what I'm going for. What do I do? Now for some reason, in my head, hopefully in yours as well, it makes sense to me to think of the animation again as this set of pictures that change with time. When I'm starting out, I have the circle,
and as time goes by, eventually I get to the eights. The question is, and it's the thing I've been talking around for ages, what goes in here? How do I feel these intermediate images? For example, what should I draw
when I'm 50% done with the animation? At the halfway mark, what does this look like? What goes in here? Is it a four? Thank you, because I did a dry run with someone
and they didn't laugh at this joke. I don't know what's wrong with them. I improvised some jokes, others I don't, and it really meant a lot, I appreciate it. So it's not a four. You left that hypothesis out of the stage. So what goes in there?
Now jokes aside, what did I say? Hopefully I hammered this in enough. What did I say? When you need to draw something, what do you need? A parameterization, exactly. A function that accepts a percentage and returns a position on the screen. Now this is where it gets mind blowing. It's that I have two notions of progress,
two notions of time. I have the notion of the time of the animation, which is the arrow at the bottom in red. Hopefully you can see it back there. And I have the notion of progress of the drawing itself because for each image I need to draw something. So at 50% of the time, sorry,
at the halfway mark of the video of my animation, I need to draw something and there's going to be progress there too because I need to make the drawing. Therefore I need the parameterization. The thing is I have two parameterizations already. I have a parameterization for the circle, let's call it P1 and I have a parameterization for the figure eight.
Let's call it P2. What do we usually do when you have two things and you need the one in the middle? You average, you divide, you add them and you divide them by two. So what I want, what I kind of want is to take the two parameters, let's not write them.
I want to take the two parameterizations and kind of average them out. Intuitively for me, if it doesn't make sense for you, it's your problem. But for me, it makes sense to think of it that way. I have two things and I'll average them out to figure out what's in the middle and that's kind of what we will be doing, what I will be doing.
I will write this function morph and can I please move this? Yes. And what the morph function is going to do is it's going to accept two parameterizations and it's going to accept a blending factor. I'll call it alpha because it looks appropriate. And my blending factor is going to represent
the progress of the animation. So it's going to vary from zero to 100%. On the left, when I'm with a circle, alpha will be zero. On the right, when I should be at the figure eight, alpha will be one. So alpha will change along the way. And the point is that morph will produce the parameterization I need for the given image.
That's the idea. Is the idea clear enough? If you have questions, you can shout them. I'll repeat them for the recording and we can try to handle them live. It's not going to go well, but I can try. Don't overestimate my abilities.
Let's do that. Let's implement morph and let's see how it works. Remember, I'm looking for the, ah, when it works. Only when it works. Let's write a function. It accepts two parameterizations and the blending factor. What does this function return?
No, not yet, close. Morph takes two parameterizations and kind of averages them out to build a new parameterization. So I'm building a new parameterization, which is a function that accepts a percentage, you know that by now, and returns a position. And if morph is building the function, might as well just return it, otherwise I wouldn't be able to use it.
What goes in here? What position exactly am I going for? There's a couple of ways to do this. A reasonable way is to compute both parameterizations at the same percentage of the drawing and now remember, inside this function, inside the parameterization called parameterization,
alpha is fixed. So I'm drawing a specific frame, a specific image of my animation. What's varying is the position of the pen to make the drawing. I'll compute both positions for both parameterizations and now I average these out because it's not very easy to average functions out directly,
but I'm very good at averaging numbers out. You just sum them and divide them, it's very easy. Now it's not really an average because alpha is not really always 50%, but I can do something called linear interpolation, which is just a fancy name for this very simple formula. If you don't believe it's simple,
just stare at it for long enough and it will become simple. Notice how, let's walk through it, bless you. If alpha is zero, which is when I'm at the beginning, I should get the circle, right? If alpha is zero, what do you get when you multiply zero by something?
Come on guys, you get zero. So this goes away and you get the original position. If alpha is one, what do you get when you multiply something by alpha? You get the something. So if alpha is one, this goes away, you get this and please bear with me, but the minus here cancels out the plus here
and we get the thing on the right. So it works for the ends, now we just hope that it works along the way. That's how I think about it. If it works on both ends, hopefully it's gonna work around the way, otherwise maths wouldn't be cool and we all know maths is cool, so it has to work. Brilliant. This is the drawing for a specific image.
Now we need a loop that emulates the progress of time or the progress of the animation. Let's do 100 blending steps because it's reasonable and let's iterate over those. I hope you all know when I'm saying
let's do 100 blending steps, I'm actually lying, it's clearly 101, but I just need things to work out correctly. Again, the ratio of the current step over the total. I need to compute my new parameterization, let's just call it P because it's a lot to type. Now we morph the two, let's start with the circle and the figure eight
at this given blending factor. And now that I have a parameterization, I want to draw it. How do I draw a parameterization? Oh wait, there's the code here. So let's indent that. And instead of using the spiral, we will use the parameterization we just built from morph. We're using that.
And we will update the screen after I'm done with this drawing. It's almost done. We're just missing one step, which I always forget what I remembered this time, which is to clean the screen between each figure. Please Rodrigo.
Alrighty. The outer loop controls the images, the inner loop draws each image, and when I'm done drawing, I update the screen. Now remember, I was looking for the, oh, when it works. Will it work? Oh man, okay. Okay, it works. I know, right?
This was scripted, but that's more or less how I felt. It's not the most elegant transformation, but it's working, which is what matters. Very nice. Now, you've heard me say this a thousand times already. There's nothing special about circle nor about eight.
Can you guys please pick one? Either the circle or the eight? Eight, let's replace the eight with a spiral. This should work as well because there's nothing special about, that was not scripted, kind of, right? So thank you. Again, it looks kind of janky, but it's clearly working, right?
It was a circle, now it's a spiral, so something we did is correct. So this is how you can morph two things. And again, it's about this notion of time, of thinking that there's this progression and you need to bake that into your code somehow. And this is groundbreaking news. I hope you're sitting for this. You don't have, when you're,
let's say that the drawing process is this rendering thing, you don't have to render things live. For my talk, it's kind of good, otherwise you'll have to sit for a long time. I'm guessing that animated movies, they don't render, they're not computing the images live, right? You can compute an image, you can save it for later,
you can compute the next image, you save it for later, you compute the next one, you save it for later, and when you're done, you put everything together. So if you're creating things that are more complex than a spiral with 3,000 steps, it's gonna take longer, but that's fine, you save the image and then you put everything together. I hope this is not very, it makes sense, right?
And somehow, I still trip over that, I don't need it to happen as we speak. Perfect. Now, I'm not sure if you read the abstract of the talk, I promised some color, so let's go there, otherwise you will be upset, as you rightfully should. And let's also do something else, which I find quite interesting, which is let's change the spiral.
This is getting boring, it's not you, it's me. Let's do a rotating spiral. Because so far, all of our animations have a well-defined beginning and a well-defined ending. And animations can also be loops, never-ending loops.
And when you do, sorry, not when you do, when you need a never-ending loop, what keyword do you use in Python? I'm sorry to break it to you guys. If you need infinite loops, you use a for loop. I don't know who taught you Python.
All right, so my outer loop now is going to tick time. It's going to be this measure of time, and I need to bake this change, because this is changing and now it's relevant. I need to bake this change into my rotating spiral. And again, I needed the master's degree for this. I hope, it's okay, guys,
you don't need to understand, I'm just adding something here. This was sarcasm. And I'm just captioning it because I did a talk where I used sarcasm as a key part of a very specific thing and I watched the recording and I didn't feel like the sarcasm came across. So it just looked like I was insulting the audience, which was terrible. So now I just caption it all the time.
All right, so tick is defined now. I don't need to compute the blending step. I'm not morphing any, actually, I'll save this for later because some of you might want the code. And if none do, I'll be very sad because I wasted 45 minutes of my life, plus the prep. Let's not go into detail on how much that was.
So I'm filling the screen, no so. I'm filling the screen with white. I'm drawing something which is going to be my rotating spiral. So instead of VP, I'm going to use the rotating spiral here. And now not only do I need the percentage, but also the tick so that I know in which frame I am. And I think the remainder should be the same,
unless I made a blender, which is also likely. Well, exactly. That's very fast. Let's slow it down. Can you please slow down? Also easy to fix. The actual speed is going to depend on your computer, right? But yeah, let's go with this for now. Now this is rotating. I'll do one other thing because I just find it fun.
Let's make it contract and expand. I'm just adding stuff in there to confuse you. Now to contract and expand, we can do, there were plenty of ways you could do this. I just found that this works for me. It's actually quite an interesting exercise to look at each of these terms and try to interpret it. We're going to do that. I think this is enough.
It's contracting and expanding. Brilliant. And now let's add color, which is what I said I would do 10 years ago. Because there's really no reason I need to use this constant white and this constant black here. I can do whatever I want. It could be other colors. It could be colors that change with time or with the progress of my drawing. Let's make them change with time because it's interesting.
I'll do a function for the, now I have to think for the backgrounds, which is going to depend on time or the tick or whatever. And it's going to return an RGB value. And again, we all know from primary school that there's this very good formula for good colors for demos about animations.
It's, we teach this in Portugal. I don't know how, I don't know if you do it in our country or not. We do this in Portugal. You get, there's the times table and then there's the BG and the FG functions. You have to memorize those. Now I need to think. Yes, of course. Come on, my teacher would be so.
So now you do, actually I don't remember. I think it's this. We'll see. If it works, it works. If it doesn't, these are not times. These are actually, I really forgot. Oh no. These go outside. Sorry about that. I panicked for a second. It's going to be fine, I promise.
And then I want this to be positive. Otherwise it might blow up elsewhere, somewhere, maybe here. This is a minus. I'm getting there, guys. Stay with me. And now we're going to multiply this with 0.5 because it would be boring to use the same number again. And this is, can I do it? Actually, I can't.
Can I? I clearly can't. And this is 85 plus. I'm sorry, I'm just, I'll not dictate it. It's a very short formula. And then what I'm looking for is for people to fall off the chairs because this is going to be so absolutely amazing that there's really no other reaction possible. It's really just the same animation with color
and the colors aren't that good because I know nothing of design, which maybe I should fix. And the background color goes here and you put in the tick. And the color, please let's not compute it every single time inside the loop. Let's compute it outside. The tick goes in here and we put the color there. And we run it, fingers crossed.
And it works, woo hoo. Yes. Wow, yes. All right. That's it, hopefully, thankfully for you guys. This is a very simple animation from first principles. Remember that we started with only being able to draw pixels. Now I'm almost able to hypnotize you.
If anyone asks, this was the best, look at there. This was the best talk you've ever attended. Thank you. I also scripted this one. I didn't say goodbye yet. I didn't say, so now you have to clap twice.
My name is Rodrigo. I don't remember what's in, oh, okay. So this is a feedback form. I have this tendency of making people suffer through my talks over and over again. And I try to make them worse each time. So if you fill in the feedback for me, and you tell me what was best, I can remove that from the talk.
And if you tell me what's wrong, I can add more of that. And there's also links to the code and written explanations if you want to try this later. Thank you. Thank you, Rodrigo, for a very interactive talk. It was almost like a small lesson in animation.
I loved it. So now we'll open the stage for questions. We have five minutes. So are there any questions? Okay, Rodrigo will be here. So if you have any questions, you can find him later in the conference and ask him questions personally. All right. Now we'll have a five-minute break before the next talk.
Another round of applause for Rodrigo, please.