实施贝塞尔曲线

发布于 2024-10-28 22:22:07 字数 756 浏览 1 评论 0原文

我正在尝试为作业实现贝塞尔曲线。我试图通过为我的函数提供一组关键帧来移动球(使用贝塞尔曲线)。该函数应该为我提供关键帧之间的所有帧...或控制点...但是尽管我使用 wikipedia...它并没有真正起作用:

她是我的代码:

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

我还注意到框架[]数组应该更大,但我不能找到任何其他对程序员更友好的文本

提前致谢。

I am trying to implement Bezier Curves for an assignment. I am trying to move a ball (using bezier curves) by giving my function an array of key frames. The function should give me all the frames in between the key frames ... or control points ... but although I'm using the formula found on wikipedia... it is not really working :s

her's my code:

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

Also I've noticed that the frames[] array should be much bigger but I can't find any other text which is more programmer friendly

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱情眠于流年 2024-11-04 22:22:08

这里有很多事情看起来不太对劲。

  1. 这样做,您的插值将精确地通过第一个和最后一个控制点,但不会通过其他控制点。这是您想要的吗?

  2. 如果您有很多关键帧,则可以使用非常高次的多项式进行插值。众所周知,高次多项式的行为很糟糕,您的位置可能会在关键帧位置之间剧烈振荡。 (这就是问题 1 的答案可能是否定的原因之一。)

  3. 为了论证,假设您确实确实想要这样做,您的 t< 值/code> 应该从开头的 0 到结尾的 1。您恰好有 1001 个这样的关键帧吗?如果不是,你就会做错事。

  4. 通过大量调用 factpow 来计算这些多项式可能效率低下,尤其是在 n 很大的情况下。

在不了解更多有关您的作业范围的情况下,我不愿意详细说明您应该做什么 - Stack Overflow 为您做作业对任何人都没有任何好处!关于贝塞尔曲线,您已经了解了什么?您的作业具体要求您做什么?

编辑添加:

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

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

There are lots of things that don't look quite right here.

  1. Doing it this way, your interpolation will pass exactly through the first and last control points, but not through the others. Is that what you want?

  2. If you have lots of key frames, you're using a very-high-degree polynomial for your interpolation. Polynomials of high degree are notoriously badly-behaved, you may get your position oscillating wildly in between the key frame positions. (This is one reason why the answer to question 1 should probably be no.)

  3. Assuming for the sake of argument that you really do want to do this, your value of t should go from 0 at the start to 1 at the end. Do you happen to have exactly 1001 of these key frames? If not, you'll be doing the wrong thing.

  4. Evaluating these polynomials with lots of calls to fact and pow is likely to be inefficient, especially if n is large.

I'm reluctant to go into much detail about what you should do without knowing more about the scope of your assignment -- it will do no one any good for Stack Overflow to do your homework for you! What have you already been told about Bezier curves? What exactly does your assignment ask you to do?

EDITED to add:

The simplest way to do interpolation using Bezier curves is probably this. Have one (cubic) Bezier curve between each pair of key-points. The endpoints (first and last control points) of each Bezier curve are those keypoints. You need two more control points. For motion to be smooth as you move through a given keypoint, you need (keypoint minus previous control point) = (next control point minus keypoint). So you're choosing a single vector at each keypoint, which will determine where the previous and subsequent control points go. As you move through each keypoint, you'll be moving in the direction of that vector, and the longer the vector is the faster you'll be moving. (If the vector is zero then your cubic Bezier degenerates into a simple straight-line path.)

Choosing that vector so that everything looks nice is highly nontrivial, but you probably aren't really being asked to do that at this stage. So something pretty simple will probably be good enough. You might, e.g., take the vector to be proportional to (next keypoint minus previous keypoint). You'll need to do something a bit different at the start and end of your path if you do that.

夜血缘 2024-11-04 22:22:08

终于得到了我需要的东西!这就是我所做的:

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

}

private void createInterpolationData() {
     time = keyFrames[keyFrames.length-1].time -
     keyFrames[0].time;
     noOfFrames = 60*time;
     partialTime = time/noOfFrames;
     frames = new Frame[ceil(noOfFrames)];  
}

Finally got What I needed! Here's what I did:

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

}

private void createInterpolationData() {
     time = keyFrames[keyFrames.length-1].time -
     keyFrames[0].time;
     noOfFrames = 60*time;
     partialTime = time/noOfFrames;
     frames = new Frame[ceil(noOfFrames)];  
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文