11

I want to move my image on a Bézier curve path from top to bottom but I can't get how can I calculate x/y points and slope from this path. The path looks like the following image:

A line that curves slightly to the right as it goes down the page.

I have start points, end points and two control points.

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); 
BSMP
  • 4,596
  • 8
  • 33
  • 44
Sunny
  • 14,522
  • 15
  • 84
  • 129

6 Answers6

18

Android gives you an API to accomplish what you want. Use the class called android.graphics.PathMeasure. There are two methods you will find useful: getLength(), to retrieve the total length in pixels of the path, and getPosTan(), to retrieve the X,Y position of a point on the curve at a specified distance (as well as the tangent at this location.)

For instance, if getLength() returns 200 and you want to know the X,Y position of the point in the middle of the curve, call getPosTan() with distance=100.

More info: http://developer.android.com/reference/android/graphics/PathMeasure.html

Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • http://stackoverflow.com/questions/18651025/how-to-move-image-on-curve-on-touch-event-in-android please help me on this question – BhavikKama Sep 06 '13 at 06:36
13

This is a cubic Bézier curve for which the formula is simply [x,y]=(1–t)^3*P0+3(1–t)^2*t*P1+3(1–t)t^2*P2+t^3*P3. With this you can solve for each point by evaluating the equation. In Java this you could do it like this:

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

So if you wanted to move a sprite along the path, then you would simply set the t value from a value of 0 - 1 depending on how far down the path you want to be. Example:

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
   }
}
Stas Jaro
  • 4,747
  • 5
  • 31
  • 53
  • hello... i want to move the image on path manually. I mean I want to move image on touch event.. how can i modify your code for that?? – SweetWisher ツ Sep 04 '13 at 06:11
  • My code is as manual as you could possibly get unless you want to write rasterizing routines for that image... – Stas Jaro Dec 14 '13 at 20:36
8

To find a point on a Bezier curve, you can use the De Casteljau algorithm.

See for example http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html or use Google to find some implementations.

Jan
  • 633
  • 11
  • 22
4

If you only have 2 control points, a bezier curve is a linear line.

If you have 3, you have a quadratic curve. 4 control points define a cubic curve.

Bezier curves are functions which depend on "time". It goes from 0.0 - 1.0. If you enter 0 into the equation, you get the value at the beginning of the curve. If you enter 1.0, the value at the end.

Bezier curves interpolate the first and last control points, so those would be your starting and ending points. Look carefully at what package or library you are using to generate the curve.

To orient your image with the tangent vector of the curve, you have to differentiate the curve equation (you can look up the cubic bezier curve equation on wiki). That will give you the tangent vector to orient your image.

PixelPerfect3
  • 110
  • 1
  • 1
  • 6
  • can you give me some hint on how to find the quadratic equation of a bezier curve with 2 and 3 control points. – Sunny Feb 29 '12 at 06:35
  • Look at: http://en.wikipedia.org/wiki/B%C3%A9zier_curve It shows equations for linear, quadratic and cubic – PixelPerfect3 Feb 29 '12 at 16:34
  • also note that in your example you have 4 control-points. the start- and end-point are also considered to be controlpoints. To evaluate the curve just use the last formula in the 'Cubic Bézier curves' section of the wiki. e.g. P0 = s, P1=cp1, P2=cp2, P3=e B(0) = s and B(1) = e in your example. – D-rk Mar 02 '12 at 09:50
3

Note that changing the parameter in the parametric form of a cubic bezier does not produce linear results. In other words, setting t=0.5 does not give you a point that is halfway along the curve. Depending on the curvature (which is defined by control points) there will be non-linearities along the path.

Vinnie Falco
  • 5,173
  • 28
  • 43
0

For anyone who needs to calculate static value points of Bezier curve Bezier curve calculator is a good source. Especially if you use the fourth quadrant (i.e. between X line and -Y line). Then you can completely map it to the Android coordinate system doing mod on negative value.

Rick
  • 1,177
  • 1
  • 19
  • 27