Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find new control point when endpoint change in cubic bezier curve

I'm implementing cubic bezier curve logic in my one of Android Application.

I've implemented cubic bezier curve code on canvas in onDraw of custom view.

// Path to draw cubic bezier curve
Path cubePath = new Path();

// Move to startPoint(200,200) (P0)
cubePath.moveTo(200,200);

// Cubic to with ControlPoint1(200,100) (C1), ControlPoint2(300,100) (C2) , EndPoint(300,200) (P1)
cubePath.cubicTo(200,100,300,100,300,200);

// Draw on Canvas
canvas.drawPath(cubePath, paint);

I visualize above code in following image.

Output of above code

[Updated]

Logic for selecting first control points, I've taken ,
baseX = 200 , baseY = 200 and curve_size = X of Endpoint - X of Start Point

Start Point     : x = baseX and y = baseY
Control Point 1 : x = baseX and y =  baseY - curve_size
Control Point 2 : x = baseX + curve_size and y =  baseY - curve_size
End Point       : x = baseX + curve_size and y = baseY

I want to allow user to change EndPoint of above curve, and based on the new End points, I invalidate the canvas.

But problem is that, Curve maintain by two control points, which needs to be recalculate upon the change in EndPoint.

Like, I just want to find new Control Points when EndPoint change from (300,200) to (250,250)

Like in following image :

New Image

Please help me to calculate two new Control Points based on new End Point that curve shape will maintain same as previous end point.

I refer following reference links during searching:

http://pomax.github.io/bezierinfo/

http://jsfiddle.net/hitesh24by365/jHbVE/3/

http://en.wikipedia.org/wiki/B%C3%A9zier_curve

http://cubic-bezier.com/

Any reference link also appreciated in answer of this question.

like image 840
Hitesh Patel Avatar asked Apr 17 '13 07:04

Hitesh Patel


People also ask

How do you find the control point on a Bezier curve?

To find any point P along a line, use the formula: P = (1-t)P0 + (t)P1 , where t is the percentage along the line the point lies and P0 is the start point and P1 is the end point. Knowing this, we can now solve for the unknown control point.

What will happen if the position of a control point of an already drawn Bezier curve is changed?

Changing the position of a control point will change the shape of the defined Bézier curve.

How many control points does the Bezier curve has if the degree of the Bezier curve is n?

A quadratic Bezier curve is determined by three control points.

When the curve passes through the control points it is called as?

A bezier curve is defined by control points.


2 Answers

changing the endpoint means two things, a rotation along P1 and a scaling factor.

The scaling factor (lets call it s) is len(p1 - p0) / len(p2 - p0)

For the rotation factor (lets call it r) i defer you to Calculating the angle between three points in android , which also gives a platform specific implementation, but you can check correctness by scaling/rotationg p1 in relation to p0, and you should get p2 as a result.

next, apply scaling and rotation with respect to p0 to c1 and c2. for convenience i will call the new c1 'd1' and the new d2.

d1 = rot(c1 - p0, factor) * s + p0
d2 = rot(c2 - p0, factor) * s + p0

to define some pseudocode for rot() (rotation http://en.wikipedia.org/wiki/Rotation_%28mathematics%29)

rot(point p, double angle){
  point q;
  q.x = p.x * cos(angle) - p.y * sin(angle);
  q.y = p.x * sin(angle) + p.y * cos(angle);
}

Your bezier curve is now scaled and rotated in relation to p0, with p1 changed to p2,

like image 85
nido Avatar answered Sep 17 '22 12:09

nido


Firstly I would ask you to look into following articles :

  1. Bezier Curves
  2. Why B-Spline Curve
  3. B-Spline Curve Summary

What you are trying to implement is a piecewise composite Bézier curve. From the Summary page for n control points (include start/end) you get (n - 1)/3 piecewise Bézier curves.

The control points shape the curve literally. If you don't give proper control points with new point, you will not be able to create smoothly connected bezier curve. Generating them will not work, as it is too complex and there is no universally accepted way.

If you don't have/want to give extra control points, you should use Catmull-Rom spline, which passes through all control points and will be C1 continous (derivative is continuous at any point on curve).

Links for Catmull Rom Spline in java/android :

  • http://hawkesy.blogspot.in/2010/05/catmull-rom-spline-curve-implementation.html
  • https://github.com/Dongseob-Park/catmull-rom-spline-curve-android
  • catmull-rom splines for Android (similar to your question)

Bottom line is if you don't have the control points don't use cubic bezier curve. Generating them is a problem not the solution.

like image 36
user568109 Avatar answered Sep 19 '22 12:09

user568109