Calculate the new control points for cubic Bezier curve in Android Canvas

246 Views Asked by At

In the application I am developing currently, I am having a challenge drawing a bezire curve between start and end points to join 2 lines as shown in the image below. red curve is the bezire curve I need to achieve

The distance between the lines are 10dp as marked in the image. I needed a solid method to achive the curves as shown in the imaage attached with the following inputs - start coordinates, end coordinates, distance of the curve, gap between 2 lines [ 10dp - as shown in picture]. Can any one suggest a solid method to achieve my desired results?

I tried using path.cubicto() function with start coordinates(X1,Y1) and with trail and error method, I identified some range of constants values(which varies with the curve length) when added/Substracted with original start and end points(X1 + Xoffset,Y1 - Yoffset) to obtain 1st control point, and similarly (X3 - Xoffset, Y3+ Yoffset) to obtain the second control point. By having the start [ X1,Y1] and end [X3,Y3] coordinates for any line as constants already, I could always get the distance of the curve by substracting the Ystart from Yend. I tried linearly interpolating the distance values to the range of Offset constants but the curve starts losing its shape where I was expecting it to be in proper shape.

1

There are 1 best solutions below

0
Mike 'Pomax' Kamermans On

The problem here is that there is no such thing as a "straight line" on a cubic curve, so you need two: one for the upper bend, and one for the lower bend, with a straight line connecting them if they're bridging more than one step.

Getting the coordinates for given your picture, with terminal x positions t1 and t2, on row r1, r2, r..., and vertical spacing 10px, these curves are trivial:

enter image description here

(where cx is (t1 + t2) / 2 and cy is (r1+r2) / 2)

You simply make every connection "two curves and a straight line if necessary": each cubic (and they need to be cubic if you want them to look straight enough at both the horizontal and vertical connection) has a start coordinate at the terminal, a first control point at the horizontal midway point between two terminals, a second control point at exactly the same point, and then an end coordinate at that same x coordinate, but half the distance between rows down.

The first curve is:

S = (t1, r1)
c1 = (cx, r1)
c2 = (cx, r1)
E = (cx, cy)

And the second curve is:

S = (cx, cy)
c1 = (cx, r2)
c2 = (cx, r2)
E = (t2, r2)

And then we simply add a straight line running from r1 + 5px to r... - 5px if the vertical distance is more than one row.

And if you want a slightly weaker radius, you move all those control points closer to their respective on-curve points (so the first control point towards the start, the second control points towards the end).