在Bézier曲线路径上移动对象

Sun*_*nny 10 graphics android bezier surfaceview android-animation

我想在Bézier曲线路径上从上到下移动我的图像,但我无法得到如何从这条路径计算x/y点和斜率.该路径如下图所示:

沿着页面向下轻微向右弯曲的线条.

我有起点,终点和两个控制点.

Path path = new Path(); 
Point s = new Point(150, 5); 
Point cp1 = new Point(140, 125); 
Point cp2 = new Point(145, 150); 
Point e = new Point(200, 250); 
path.moveTo(s.x, s.y); 
path.cubicTo(cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y); 
Run Code Online (Sandbox Code Playgroud)

Rom*_*Guy 17

Android为您提供了一个API来完成您想要的任务.使用名为android.graphics.PathMeasure的类.您会发现有两种方法有用:getLength(),用于检索路径的总长度(以像素为单位)和getPosTan(),用于检索曲线上指定距离处的点的X,Y位置(以及这个位置的切线.)

例如,如果getLength()返回200并且您想知道曲线中间点的X,Y位置,则调用距离= 100的getPosTan().

更多信息:http://developer.android.com/reference/android/graphics/PathMeasure.html


Sta*_*aro 11

这是一个立方贝塞尔曲线,公式简单[x,y]=(1–t)^3*P0+3(1–t)^2*t*P1+3(1–t)t^2*P2+t^3*P3.有了这个,您可以通过评估等式来解决每个点.在Java中你可以这样做:

/* t is time(value of 0.0f-1.0f; 0 is the start 1 is the end) */
Point CalculateBezierPoint(float t, Point s, Point c1, Point c2, Point e)
{
  float u = 1 – t;
  float tt = t*t;
  float uu = u*u;
  float uuu = uu * u;
  float ttt = tt * t;

  Point p = new Point(s.x * uuu, s.y * uuu);
  p.x += 3 * uu * t * c1.x;
  p.y += 3 * uu * t * c1.y;
  p.x += 3 * u * tt * c2.x;
  p.y += 3 * u * tt * c2.y;
  p.x += ttt * e.x;
  p.y += ttt * e.y;

  return p;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您想沿着路径移动精灵,那么您只需将值设置为0 - 1,具体取决于您想要的路径下降距离.例:

int percentMovedPerFrame = 1;// Will complete path in 100 frames
int currentPercent = 0;
update() {
   if (currentPercent < 100) {
      this.pos = CalculateBezierPoint(currentPercent / 100.0f, this.path.s, this.path.c1, this.path.c2, this.path.e);
      currentPercent += percentMovedPerFrame
   }
}
Run Code Online (Sandbox Code Playgroud)


Jan*_*Jan 7

要在Bezier曲线上找到一个点,可以使用De Casteljau算法.

请参阅http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html或使用Google查找某些实现.