关于Bezier匀速问题

直接使用BezierBy,BezierTo,运动不是匀速的,经过各种搜索之后

在cocos2d\cocos\2d下添加BezeLength.h 和BezeLength.CPP

代码如下

BezeLength.h

double beze_length(double t, float xa, float xb, float xc, float xd, float ya, float yb, float yc, float yd);
double beze_even(double t, double total_length, float xa, float xb, float xc, float xd, float ya, float yb, float yc, float yd);

```





BezeLength.CPP
#include 
#include "BezeLength.h"


//x坐标速度方程-------------------------------------------------------------------------------------
double beze_speed_x(double t, float xa, float xb, float xc, float xd) 
{ 
 double it = 1-t;
 return -3*xa*it*it + 3*xb*it*it - 6*xb*it*t + 6*xc*it*t - 3*xc*t*t + 3*xd*t*t;
}
//y坐标速度方程-------------------------------------------------------------------------------------
double beze_speed_y(double t, float ya, float yb, float yc, float yd)
{ 
 double it = 1-t;
 return -3*ya*it*it + 3*yb*it*it - 6*yb*it*t + 6*yc*it*t - 3*yc*t*t + 3*yd*t*t;
}
//速度方程-------------------------------------------------------------------------------------
double beze_speed(double t, float xa, float xb, float xc, float xd, float ya, float yb, float yc, float yd)
{
 double sx = beze_speed_x(t, xa, xb, xc, xd);
 double sy = beze_speed_y(t, ya, yb, yc, yd);
 return sqrt(sx*sx+sy*sy);
}
//长度方程,使用Simpson积分算法-------------------------------------------------------------------------------------
double beze_length(double t, float xa, float xb, float xc, float xd, float ya, float yb, float yc, float yd)
{
 //在总长度范围内,使用simpson算法的分割数
 #define TOTAL_SIMPSON_STEP (10000) 


 //分割份数
 int stepCounts = (int)(TOTAL_SIMPSON_STEP*t);


 if(stepCounts & 1) stepCounts++; //偶数


 if(stepCounts==0) return 0.0;


 int halfCounts = stepCounts/2;


 double sum1=0.0, sum2=0.0;


 double dStep = t/stepCounts;


 for(int i=0; i<halfCounts; i++)
 {
 sum1 += beze_speed((2*i+1)*dStep, xa, xb, xc, xd, ya, yb, yc, yd);
 }


 for(int i=1; i<halfCounts; i++)
 {
 sum2 += beze_speed((2*i)*dStep, xa, xb, xc, xd, ya, yb, yc, yd);
 }


 return (beze_speed(0.0, xa, xb, xc, xd, ya, yb, yc, yd)+beze_speed(1.0, xa, xb, xc, xd, ya, yb, yc, yd)+2*sum2+4*sum1)*dStep/3.0;
}


//根据t推导出匀速运动自变量t'的方程(使用牛顿切线法)-------------------------------------------------------------------------------------
double beze_even(double t, double total_length, float xa, float xb, float xc, float xd, float ya, float yb, float yc, float yd)
{
 double len = t*total_length; //如果按照匀速增长,此时对应的曲线长度
 double t1=t, t2;
 do
 {
 t2 = t1 - (beze_length(t1, xa, xb, xc, xd, ya, yb, yc, yd)-len)/beze_speed(t1, xa, xb, xc, xd, ya, yb, yc, yd);
 if(fabs(t1-t2)<0.0000001) break; 
 t1=t2;
 }while(true);
 return t2;
}

```
3赞

原来是分割数太多了!安卓上跑才20帧

//在总长度范围内,使用simpson算法的分割数
#define TOTAL_SIMPSON_STEP (10000)

改小一点就可以了,但精确度就相应减少了,自己衡量了。

这个怎么用?

感谢分享,这个动作多了的话计算量确实有点大。

存起来备用:14:

mark on :2:

为何在电脑看到是匀速的,在安卓手机上在最高点总是慢一些