简体   繁体   中英

Why is the p5.js bezierPoint() function returning non-linear values when given a linear cubic bezier?

Okay, so I've been creating a UI framework and I added animations to it. I wanted to allow users to control the timing functions of their animations using cubicBeziers, so I decided to use p5.js' bezierPoint() function. I spent hours making it work, and finally got it working in a way that I thought was perfect..... Until now I find out that it's (somehow) not working as expected.

When I pass in a cubic bezier with start/end points at 0,1 and 1,0 and control points at 0.5,0.5 and 0.5,0.5 (this is a linear cubic bezier), I get an eased animation for no reason... This should be yielding a linear animation (which can be demonstrated here ) but somehow it's not.

So I looked into it further just to prove that I wasn't just seeing things, and sure enough, it is in fact giving non-linear numbers. I wrote this tiny code snippet:

 <script src = "https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.min.js"></script> <script> function setup(){ createCanvas(100,100); } function draw(){ background(255,255,0); noFill(); stroke(0,0,0); strokeWeight(3); bezier(0,100,50,50,50,50,100,0); ellipse(bezierPoint(0,50,50,100,frameCount / 100),bezierPoint(100,50,50,0,frameCount / 100),5,5); ellipse(50,bezierPoint(100,50,50,0,frameCount / 100),5,5); ellipse(60,100 - frameCount,5,5); } </script>

And you can see very clearly that the dot following bezierPoint() (the one on the left) is moving at a non-linear speed when compared to the linear one (the one on the right)

Why is this happening?


Just thought I'd include this here for convenience. This is p5.js' bezierPoint() function:

function bezierPoint(e,t,r,i,n){
    var a = 1 - n;
    return(Math.pow(a,3) * e + 3 * Math.pow(a,2) * n * t + 3 * a * Math.pow(n,2) * r + Math.pow(n,3) * i);
}

Okay, so after continued research, it appears as though this is expected behavior somehow.

I found this question: Custom animation using cubic Bezier function

Which states "I saw on a question [that] the answerer recommended simply eliminating x and define the function as y against t. However, this will give pretty inaccurate results, as a linear Bezier curve from 0.0 to 1.0 will not animate linearly."

Which clues me into the fact that what I'm seeing here is somehow expected behavior... I just can't wrap my brain around it.

How does taking a linear curve and animating value t linearly give non-linear results?, There's nothing in my code which is non-linear. yet somehow I'm getting a non-linear animation, That really doesn't make sense to me at all. but now that I know that it's expected behavior I guess I can expect to not receive the answer that I'm looking for.

When the 4 control poles of a cubic Bezier curve are collinear, the Bezier curve indeed will look "linear". But it does not mean this Bezier curve is exactly the same as a line that goes from P0 to P3. The first derivative for a line is a constant but the first derivative for a linear Bezier curve is not a constant (in general).

To obtain a "true" linear cubic Bezier curve, you need to place the two middle control points P1 and P2 at

P1 = P0 + (P3-P0)/3
P2 = P0 + 2*(P3-P0)/3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM