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.
[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 :
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
Any reference link also appreciated in answer of this question.
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,