我正在尝试为分配实施Bezier曲线。我试图通过给我的函数一个关键帧数组来移动一个球(使用贝塞尔曲线)。该函数应该给我关键帧之间的所有帧...或控制点...但是虽然我使用wikipedia上找到的公式...它不是真的有效: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);
}
另外我注意到frames []数组应该大得多,但我找不到任何其他程序友好的文本
提前致谢。
答案 0 :(得分:1)
有很多事情在这里看起来不太正确。
这样做,插值将完全通过第一个和最后一个控制点,但不会通过其他控制点。这就是你想要的吗?
如果您有许多关键帧,则使用非常高次多项式进行插值。高度多项式是众所周知的糟糕行为,你可能会让你的位置在关键帧位置之间疯狂地摆动。 (这就是为什么问题1的答案应该是否定的一个原因。)
假设为了论证你真的做想要这样做,你的t
的值应该从开头的0到结尾的1。你恰巧有1001个关键帧吗?如果没有,你就会做错事。
通过大量调用fact
和pow
来评估这些多项式可能效率很低,尤其是n
很大时。
我不愿意详细了解你应该做什么而不了解更多关于你的任务范围的事情 - Stack Overflow为你做完作业没有任何好处您!你有什么关于贝齐尔曲线的消息?你的作业究竟要求你做什么?
编辑添加:
使用贝塞尔曲线进行插值的最简单方法可能就是这样。在每对关键点之间有一条(立方)贝塞尔曲线。每个贝塞尔曲线的端点(第一个和最后一个控制点)是那些关键点。你还需要两个控制点。为了在移动给定关键点时运动平滑,您需要(关键点减去前一个控制点)=(下一个控制点减去关键点)。因此,您在每个关键点选择一个向量,这将确定前一个和后一个控制点的位置。当您在每个关键点移动时,您将朝向该向量的方向移动,向量越长,您移动的速度就越快。 (如果向量为零,那么你的三次贝塞尔变换成一条简单的直线路径。)
选择那个向量以使一切看起来都很好是非常重要的,但在这个阶段你可能并没有被要求这么做。所以非常简单的东西可能就足够了。例如,您可以将矢量与(下一个关键点减去前一个关键点)成比例。如果你这样做,你需要在路径的开头和结尾做一些不同的事情。
答案 1 :(得分:0)
终于得到了我需要的东西!这是我做的:
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)];
}