Drawing curve with 3 points, or help with quadratic calculations


#1

Hello,

I’m trying to draw a curved line between 2 objects in a way that if I move the objects around the curve remains the same. I’m having difficulties with the quadratic method and calculating the control point. Any help with this or ideas for another approach will be welcome.

What I want to get:

What I have so far:

linePath.clear();
linePath.startNewSubPath (x1, y1);

float amplitude = 100;    
float a = atan2f(-(y2-y1), x2-x1) + float_Pi/2.0;
float midx = (x2-x1)/2 + x1 + cos(a)*amplitude;
float midy = (y2-y1)/2 + y1 + sin(a)*amplitude;

linePath.quadraticTo(midx, midy, x2, y2);

Ideally I’d like to have an arrow that the user can edit. The typical connector line where you add points and then curve it yourself. But that’s for version 2.0 :wink:

Thx,
Ana


#2

I am not sure, if that’s what you are up to, but I used Path::cubicTo():

linePath.startNewSubPath (x1, y1);
linePath.cubicTo (x1 + x1_tangent, y1 + y1_tangent, x2 - x2_tangent, y2 - y2_tangent, x2, y2);

Looks like this:


#3

Hi Daniel, how do you calculate x1_tangent and the other tangents? I’m a bit confused, you need an angle for that, don’t you?

I want to create something similar to the picture I posted (doesn’t need to be exactly the same). Just an arc or a curve of some form so when I move the listener around the talker the curve moves with it.

Thx again,
Ana


#4

How silly of me!! I didn’t realise the juce coordinates are like upside down. So the y=0 is on the top and y=50 is on the bottom.
And I was doing my calculations using the normal cartesian y+ on top and y- on the bottom.

So I’ve just changed
float midy = (y2-y1)/2 + y1 - sin(a)*amplitude;

:nerd::woman:


#5

That was the thing I didn’t completely understand in your OP, I thought your idea “to have an arrow that the user can edit” would be the same, as I did.

Usually you specify the control vertices in the function quadraticTo / cubicTo. If you start with an angle I would compute that using Point::getPointOnCircumference (float radius, float angle) const

Obviously there are a lot of curves that match your criteria, so you have to define, how “round” you want your curve…

Point<float> p1 (x1, y1);
Point<float> p2 (x2, y2);
linePath.cubicTo (p1.getPointOnCircumference (radius, angle), p2.getPointOnCircumference (radius2, angle2), p2);

I don’t know if that helps…


#6

oh nice one, I didn’t realised about that getPointOnCircumference method. It would have save me some time re-studying my high school maths! :blush:


#7

You might also find some other methods in the Line class handy for this sort of thing.


#8

Ahhhhh thx! I’ve just saw this: Line::getAngle()

Thx,
Ana