Animation 实现Bezier曲线

Animation 实现Bezier曲线,animation,interpolation,bezier,Animation,Interpolation,Bezier,我正在尝试为赋值实现贝塞尔曲线。我试图通过给我的函数一系列关键帧来移动一个球(使用贝塞尔曲线)。函数应该给我关键帧之间的所有帧。。。或控制点。。。但是尽管我用的是在…上找到的公式。。。它没有真正起作用:s 她是我的密码: private void interpolate(){ float x,y,b, t = 0; frames = new Frame[keyFrames.length]; for(int i =0;i<keyFrames.lengt

我正在尝试为赋值实现贝塞尔曲线。我试图通过给我的函数一系列关键帧来移动一个球(使用贝塞尔曲线)。函数应该给我关键帧之间的所有帧。。。或控制点。。。但是尽管我用的是在…上找到的公式。。。它没有真正起作用:s

她是我的密码:

  private void interpolate(){
      float x,y,b, t = 0;
      frames = new Frame[keyFrames.length];
      for(int i =0;i<keyFrames.length;++i){   
         t+=0.001;
         b = Bint(i,keyFrames.length,t);   
         x = b*keyFrames[i].x;
         y = b*keyFrames[i].y;
         frames[i] = new Frame(x,y);     
      }
  }

private float Bint(int i, int n, float t){
  float Cni = fact(n)/(fact(i) * fact(n-i));
  return Cni * pow(1-t,n-i) * pow(t,i);
}
private void interpolate(){
浮点数x,y,b,t=0;
帧=新帧[关键帧.长度];

对于(inti=0;i,这里有很多东西看起来不太正确

  • 这样做,插值将完全通过第一个和最后一个控制点,但不会通过其他控制点。这就是您想要的吗

  • 如果你有很多关键帧,你正在使用一个非常高次的多项式进行插值。高次多项式的行为是出了名的糟糕,你可能会在关键帧位置之间剧烈振荡。(这就是问题1的答案可能是否定的原因之一。)

  • 为了论证起见,假设您确实想这样做,那么
    t
    的值应该从开始时的0变为结束时的1。您是否恰好有1001个关键帧?如果没有,您将做错误的事情

  • 通过大量调用
    fact
    pow
    来计算这些多项式可能效率低下,特别是当
    n
    很大时

  • 我不愿意在不了解作业范围的情况下详细说明您应该做什么——为您做作业对堆栈溢出没有任何好处!关于贝塞尔曲线,您已经被告知了什么?您的作业要求您做什么

    编辑以添加:

    使用贝塞尔曲线进行插值的最简单方法可能是这样。在每对关键点之间有一条(立方)贝塞尔曲线。每条贝塞尔曲线的端点(第一个和最后一个控制点)就是这些关键点。您还需要两个控制点。要使运动在通过给定关键点时平滑,您需要(关键点减去上一个控制点)=(下一个控制点减去关键点)。因此,在每个关键点上选择一个向量,它将确定上一个和后续控制点的位置。当您通过每个关键点时,您将沿着该向量的方向移动,向量越长,移动越快。(如果向量为零,则三次Bezier将退化为简单的直线路径。)


    选择那个向量使所有东西看起来都很好是非常重要的,但是在这个阶段你可能没有被要求这样做。所以一些非常简单的东西可能就足够了。你可以,例如,让向量与(下一个关键点减去上一个关键点)成比例。如果您这样做,您将需要在路径的起点和终点做一些不同的事情。

    最终得到了我需要的!以下是我所做的:

    private void interpolate() {    
      float t = 0;
      float x,y,b;
      for(int f =0;f<frames.length;f++) {      
        x=0;
        y=0;
        for(int i = 0; i<keyFrames.length; i++) {       
          b = Bint(i,keyFrames.length-1,map(t,0,time,0,1));   
          x += b*keyFrames[i].x;
          y += b*keyFrames[i].y;
        }    
      frames[f] = new Frame(x,y); 
      t+=partialTime;     
    }
    

    [处理]它是基于Java的,但是帧类和关键帧类都是我创建的。(它们其实什么都不是,只是一个x,y位置和一个时间域,我在这段代码中没有用到,我不想让你帮我做家庭作业。基本上我们有一个叫做动画的主题,我们在这里非常简要地介绍了线性插值,三次样条曲线,cutmul rom和bezier曲线,然后我们要求实现它们,呵呵,这就是全部内容但是我更倾向于编程,而不是数学,虽然维基百科上的公式很简单,但我没有完全明白什么是不准确的?甚至可能是一些程序员友好的教程或是我所要求的,我通常为我的程序感到骄傲,喜欢接受新的挑战,但我认为我击中了我的头或者别的什么。你可以把
    t
    看作是一个时间值,参数化曲线上的运动。在
    t=0
    处,你处于第一个控制点。在
    t=1
    处,你处于最后一个控制点。在这两者之间,你的移动方式受其他控制点的控制,但不一定(甚至通常)通过任意一条曲线。如果你有一个任意的位置序列,并且你想在它们之间做一些平滑的插值,那么你要看的是各种样条插值。你可以用贝塞尔曲线来做这件事,但是在选择控制点时需要做额外的(非平凡的)工作:它不仅仅是“实现贝塞尔曲线”。(在不确切知道您被告知要做什么的情况下,我不知道这是否表明这超出了您的讲师希望您做的!)使用各种技术(线性插值、Catmull Rom样条曲线和贝塞尔曲线)执行中间处理并评估结果。这是作业摘要中的一个问题(其他人则对实现和性能等进行了评论)。这与原始问题中的代码基本相同,除了#3(已修复)之外,还有我在回答中提到的所有缺陷.但如果它满足你的需要,那就足够了。
    private void createInterpolationData() {
         time = keyFrames[keyFrames.length-1].time -
         keyFrames[0].time;
         noOfFrames = 60*time;
         partialTime = time/noOfFrames;
         frames = new Frame[ceil(noOfFrames)];  
    }