简体   繁体   English

为什么在给定线性三次贝塞尔曲线时 p5.js bezierPoint() function 返回非线性值?

[英]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.好的,所以我一直在创建一个 UI 框架,并在其中添加了动画。 I wanted to allow users to control the timing functions of their animations using cubicBeziers, so I decided to use p5.js' bezierPoint() function.我想让用户使用cubicBeziers来控制动画的计时功能,所以我决定使用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.当我传入一个开始/结束点在0,11,0并且控制点在0.5,0.50.5,0.5的三次贝塞尔曲线(这是一个线性三次贝塞尔曲线)时,我会无缘无故地得到一个缓和的 animation 。 . 这应该产生一个线性 animation (可以在这里演示),但不知何故它不是。

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)您可以非常清楚地看到,与线性点(右侧的点)相比, bezierPoint()后面的点(左侧的点)以非线性速度移动

Why is this happening?为什么会这样?


Just thought I'd include this here for convenience.只是想为了方便起见,我会把它包括在这里。 This is p5.js' bezierPoint() function:这是 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我发现了这个问题: Custom animation usingcubic 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."其中指出“我在一个问题上看到 [that] 回答者建议简单地消除 x 并将 function 定义为 y 对 t。但是,这将给出非常不准确的结果,因为从 0.0 到 1.0 的线性贝塞尔曲线不会线性动画。”

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.采用线性曲线和动画值t如何线性地给出非线性结果?,我的代码中没有任何非线性的东西。 yet somehow I'm getting a non-linear animation, That really doesn't make sense to me at all.但不知何故,我得到了一个非线性 animation,这对我来说真的没有意义。 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".当三次贝塞尔曲线的 4 个控制极点共线时,贝塞尔曲线确实看起来“线性”。 But it does not mean this Bezier curve is exactly the same as a line that goes from P0 to P3.但这并不意味着这条贝塞尔曲线与从 P0 到 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 和 P2 放置在

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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