首页 > 解决方案 > 为什么在给定线性三次贝塞尔曲线时 p5.js bezierPoint() 函数会返回非线性值?

问题描述

好的,所以我一直在创建一个 UI 框架,并在其中添加了动画。我想让用户使用cubicBeziers来控制他们动画的计时功能,所以我决定使用p5.js的bezierPoint()功能。我花了几个小时让它工作,最后让它以我认为完美的方式工作......直到现在我发现它(不知何故)没有按预期工作。

当我传入一个开始/结束点在0,1and1,0和控制点在0.5,0.5and的三次贝塞尔曲线时0.5,0.5(这是一个线性三次贝塞尔曲线),我无缘无故地得到一个缓和的动画......这应该产生一个线性动画(可以是在这里演示)但不知何故不是。

所以我进一步研究它只是为了证明我不只是看到事物,果然,它实际上给出了非线性数字。我写了这个小代码片段:

<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>

您可以非常清楚地看到,bezierPoint()与线性点(右侧的点)相比,跟随的点(左侧的点)以非线性速度移动

为什么会这样?


只是想为了方便起见,我会把它包括在这里。这是 p5.js 的bezierPoint()功能:

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);
}

标签: javascriptp5.jsbezier

解决方案


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.


推荐阅读