Bézier curves (Coding Challenge 163)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to a very special coding challenge video this video is part of support p5 2020 i know it's 2021 but part of the campaign to raise money for the processing foundation in 2020 one of the rewards for making a donation was request a topic for a coding trade video and i'm here finally in the summer of 2021 to fulfill these requests this video was is thanks to the generous donation from jason oswald chair of computer science at germantown academy if you're not familiar with the processing foundation it is the organization that maintains p5.js processing you can learn all about the processing foundation at the processing foundation website and that's where you too can also make a donation so much of what i do on the coding terrain actually basically all of what i do on the coding trade would not be possible without the processing foundation's uh support and community and that's the anything that i could do to give back i am thrilled to be able to do so what function did jason request that i explore in this particular video it is ta-da the bezier function the bezier function draws a bezier curve named for the french engineer pial bezier who was working on i think modeling renault cars in the 1960s and developed this curve so in this video i both want to demonstrate the bezier function itself as it exists in p5.js as well as the math behind it what if you didn't have that function could you get that curve on the screen just through your own calculations in learning about the bezier curve your first stop should really be roone madsen's programming design systems book in the shapes chapter in the custom shapes section he has a wonderful explanation of what a bezier curve is how it works and what kinds of designs and shapes you can create in p5.js really everything that i want to cover in this video is very well explained there you might also want to wonder your way over to the wikipedia page for the psja curve there you can find all the math behind how the curve is calculated now what is most commonly referred to as a bezier curve is actually known as a cubic bezier curve there's such thing as a linear bezier curve which is really just a line a quadratic bezier curve and a cubic bezier curve the bezier function in p5 itself is the cubic bezier curve and that's what you usually find in things like adobe illustrator as well a bezier curve always has two anchor points a linear bezier curve is just a line between those two points what's special about bezier curves what makes them curvy is the fact that in addition to the anchor point there are also control points a quadratic bezier curve involves just one control point so i'm going to re-number these points now the middle point is the control point and it's like a gravitational pull if i were to pull this point down the curve would also be pulled down and if you're thinking what i'm thinking a cubic bezier curve has two control points four points in total both of them controlling the shape of the curve additionally a single bezier curve which has these four points can be extended to what's known as a bezier spline by adding more control points along a sequence we can create continuous geometry that bends according to a sequence of bezier vertices but i'm getting ahead of myself let's start by exploring the bezier function in p5 before i write the bezier function i just want to lay out where i imagine the anchor points and control points to be so i'm going to draw four points anchor point control point control point anchor point the bezier function itself takes eight arguments four pairs of x y points anchor control control anchor interestingly the bezier function natively tries to create an enclosed shape with a fill is this what you expected i always expect the curve itself to end up much closer to the control point but we'll see in a moment when i start to look at the math why it's not coming all the way up to that control point so we can see a little better let me move one with the mouse now as i move this control point around we can see how the bezier curve itself responds let me add a couple more lines one thing you might notice now is that these lines are tangent to the curve that's an important mathematical principle here in the bezier curve as an exercise i might suggest can you make your own bezier curve tool but you can move all the points around individually now before i move on to the math behind the bezier curve i think it's worth exploring what the bezier vertex function does in p5.js as well here we can see with begin shape and end shape we can set single vertices so if there are only two vertices then i have a line that connects those two vertices a bezier vertex and it's giving me an error because i haven't finished here not only sets the next point that you're defining along the way of a shape but two control points along the way that determine how you curve between this first vertex which has to be specified with the plane vertex function and the next vertex which is the last two arguments of the bezier vertex function now you see i have precisely the same curve that i had before but instead of the full bezier function i set the first anchor point with vertex and then the next two control points and the next anchor point with bezier vertex what does this allow me to do it allows me to continue this is how i can start to create more elaborate shapes like the one that you're seeing here by stringing together multiple bezier vertices and you can actually go quite far with this there's also a quadratic vertex which just involves a single control point you can have regular vertices and bezier vertices and quadratic vertices to create all sorts of possibilities and remember with a custom shape like this you can also include a fill this alone should give you plenty to explore just having the bezier function of the bezier vertex function right there in p5 opens up so many visual possibilities i recently did a coding challenge about a self-avoiding walk which connects a whole set of points with line segments and just adding the variation of connecting all these points with bezier vertices creates a very different visual quality to the output so maybe just trying to sketch where you put a lot of lines and vertices in and try using bezier curves instead but we are limited here because we're using the bezier function in p5 directly we don't have access to all the points along the way on the wikipedia page you might have noticed a diagram of the quadratic bezier curve visualized with string art we can do this with something really special another function a bonus that you're getting in this video for free the lerp function now how in the world is the bezier function related to the alert function let's go back to a simple linear bezier curve or just a line between two points i'm going to call this x0 and this one x1 the lerp function takes two values and returns back to you a value in between those two values some percentage along the way between 0 and 100 in this case 0.5 would give me the value 50 of the way there this value is often represented with the letter t i think of it as like the amount of time to get from this point all the way to this point the math for doing this is quite simple and intuitive let's imagine t is equal to 0.2 well we want to start at this point and then we want to go about 20 of the way of the distance between x0 and x1 so start at x0 and add 20 of the distance which is x1 minus x0 times 0.2 linear interpolation coming back to the wikipedia page you'll notice something interesting look at that formula right there under linear bezier curve exactly this formula let's implement this in a code example so here we have our straight line i'm using the create vector function to pair an x and y value in a single variable now there's a lot more to vectors than that but for our purposes here i just don't want to have a lot of separate x y variables so i've got p zero dot x dot p0.y p1.x and p1.y and of course i'm just using the line function to draw that line but what if instead of using line i wanted to draw the line myself as many different points along the way between those two anchor points i'll start with a for loop i'm choosing to loop t starting at zero all the way up to one hundred percent or one then let me just apply this formula and look at that there's that beautiful formula that i'm getting all of the points each an additional 10 along the way to the end adding begin shape and end shape and changing it to vertex i have my line again now while i've put in here the raw math for linear interpolation p5 has the lerp function so i believe i could get my code to be easier to read without the raw math there with just the lerp function itself and there we go now i have that line drawn with the lerp function because i'm using p5 vector i could actually use the p5 vector lerp function which will allow me to sort of consolidate the xy together but just to make everything really clear and for me be able to follow it i'm going to keep it as separate x y's for right now but i'm making a bezier curve this is just a line lerp works for linear interpolation lines how do i make a quadratic bezier from three points and lerp remember a quadratic bezier has two anchor points and one control point probably ends up something like this well what if i wanted to do linear interpolation between x0 and x1 it would look like this what if i wanted to do linear interpolation between x1 and x2 it would look like this this is the linear interpolation between these two points this is the linear interpolation between these two points what if i took and this is going to blow your mind it's like ler perception i can't say that lerpception [Music] what if i lurked this point and this point by t as well so i would be taking the if this whole thing were a and this whole thing were b i would say a plus b minus a times t so plug this whole thing into here and then plug this into here and listen to here and oh let's go back and look at the wikipedia page that's exactly what's happening there and it's working all its way out and you can see eventually we end up with this particular formula there i could go through and derive all of the math and then write it all out in my p5 code itself but i've got the lerp function there remember this is just this lerp function this one is just this lerp function and this is going to look really crazy but i can just put the lerps inside the lerp lerp the result of the first lerp with the result of the second lerp according to t this is the quadratic bezier and if your mind's going where mine's going right now just wait till we get to the cubic one let's put this into the code and see what we get so the vertex now with the math that i had before is just drawing the line between p0 and p1 let's call that x1 and y1 x2 and y2 is the lerp between p1 and p2 and then x is the lerp between x1 and x2 and look there's our quadratic bezier all with lerp i can't believe that worked i love it so much let's have p1 be controlled by the mouse well what's going on here oh no no p1 i really did something crazy there the other thing that's super interesting here is this value 0.1 that's the amount of space in between every point along the way that we're calculating i could call that the delta maybe if delta or 0.5 you can see i'm just basically getting one point in between a very small delta would be calculating lots of little points in a way i want to go back to drawing those points and incidentally what happens then if i connect x1 and y1 with x2 and y2 with a line oh look at that remember the string art on the wikipedia page that's what i've got right now i don't even need to draw these points or the bezier curve itself the bezier curve happens just by the sort of layering of all these lines and because they're all separate lines i could make the rainbow colored so for whatever reason i'm not i'm getting the first line because i'm starting at t equals zero but i'm not getting the what i expect to see as completely closing off um at t is equal to one this is because of one of those pesky little javascript things where there's like a rounding error and i'm not actually getting all the way up to t equals one oh there we go so that's a little bit of a hack solution there but i'm just gonna leave it and now i've closed off this shape oh i love it so much we're not done yet though i have got to do cubic oh boy how am i gonna do cubic well i need another point so p2 will be something like 400 comma zero i'm just gonna make something simple right now and p3 is then the last point and i'm going to write a function that's called quadratic and quadratic is going to receive three points and it's going to do exactly this and return that result as a vector i'm going to say v for vertex is the result of quadratic oh and it needs a t obviously okay great so i forgot like i can put in p3 here and we can see this is what i had before all right but i have it all in a function that's doing the quadratic bezier math always learned now what if i were to say v1 is the quadratic from p0 to p1 to p2 and v2 is the quadratic from p1 p2 to p3 then i could just say that x is lerp v1 right i need to lerp both quadratics are you with me if quadratic is lurping two lerps then cubic is lurping two quadratics find the quadratic bezier between these three points find the quadratic bezier between these three points i totally numbered them wrong x1 x2 x3 and then lurk those two curves together i've messed something up here what did i mess up oh oh oh my goodness what am i doing there we go sorry for that so this is correct in the sense that i've taken two quadratic curves and lurped between them i think it would be advisable for me to put all of this into a function called cubic which takes all the points then does the quadratic between the first three and the second three calculates the x y and returns that as a vector so quadratic is lurping two line segments p0 p1 p1 p2 cubic is lurping two quadratics now i can just say let v is cubic p0 p1 p2 p3 comma t vertex v dot x v dot y there we go so this works i've got the bezier curve drawn as a sequence of vertices but i lost the beautiful string art and the rainbow colors so let's see if i can get that back i'm going to add that stroke in there get rid of begin shape and end shape and the vertices and now let's just draw lines connecting various points so what if here in cubic i connect v1 to v2 look at that and i can see the bezier curve there as the sort of tangents of all of these lines mixed together but i could make this really crazy and i could also draw all those quadratic connections whoa i did something wrong here x1 y1 x2 y2 i got a little overly excited there there we go look at this this is two quadratic curves meeting in the middle to draw the bezier i could add a little bit of alpha here just so it's you get some blending i could go on forever here but what if i instead of just moving one point around with the mouse let me move all the points around according to just some random bouncing ball logic so very quickly i just made a class called particle that both has an x y as well as a d x and d y are x speed and y speed i could have called them the x y's move around and if it hits the edges the direction is reversed so all of these are particles now adding particle.js to index.html and i've got the exact same sketch the difference is now that these are all particle objects instead of setting one to the mouse location i can call their update function which causes it to bounce around i really don't know what i've made here but it's kind of cool let me try commenting out moving the anchor points of this bezier curve so i have some semblance of control here so now just the control points are moving i don't know what i've made here but hopefully i've opened up a door to a lot of creative possibilities that you could explore from this code i should say that i'm not so convinced that this implementation of the bezier curve as this kind of nested calls to the lerp function is particularly efficient but it does uh provide all of the data involved in the creation of the curve so that you can draw all sorts of visualizations of all of the properties but ultimately i could have just written a single function that uses this exact formula which is the result of playing out all of these nested linear interpolations so i'll include as an extra example a version of this with just that formula in it well i think that's everything you could possibly want to know about the bezier function the bezier vertex quadratic vertex how to do all this stuff without those functions play with this make your own variation of it share it with me at thecodingtrain.com there's instructions there for how to do so i will take a look at some and feature them in a future live stream really though what i should be doing next right i got some spare i got like three more hours is try it one more level in right what if instead of four points i now had five i think that would be a quartic bezier lerp the cubics which lerp the quadratics i'll leave that to you please do that let me know how it goes in the comments can't wait to see goodbye see you in the next coding challenge [Music] you
Info
Channel: The Coding Train
Views: 94,562
Rating: 4.958549 out of 5
Keywords:
Id: enNfb6p3j_g
Channel Id: undefined
Length: 22min 58sec (1378 seconds)
Published: Sun Aug 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.