Draw a line from point to circle circumference, but pointing at the center

circles

I have an app, where I draw a graph. From each circle in this graph there are some lines to other circles. To not mess up my drawing, I tend to draw the line up from the circle, then horizontally in direction of the other circle. Then I stop some pixels before the other circle center and I draw the line from there to the other circles center. Now I wanted to clear the drawing, cuz when there are many lines going to the same circle, it's hard to see if the line ends with an arrow.

So I thought the lines would go into circles center direction, but they would stop at the circumference. Here's how it looks like:

enter image description here

As you can see, the lines which come from the left side to the right side (f.e from q1 to q2) are really fine, definitely pointing at the center, but not going inside.

But what about the lines coming from the right to the left (f.e from q4 to q1 or q3 to q1). You can clearly see, that they stop at the circumference, but they definitely do not point at the center, which is really not aesthetic.

This is the algorithm I came up with:

1.  I have X and Y of the point from I will be drawing the line (the final line, cuz every
    line consists of 3 lines -> the one which goes up or down, the one which goes
    horizontally and the last one, which connects the end of the 2nd line with circle center)
2.  Then I take the X and Y of the circle to which I would be drawing a line
3.  a = circleCenter.X - lineEnd.X
    b = circleCenter.Y - lineEnd.Y
    c = sqrt(a^2 + b^2)
4.  sin(alfa) = b/c
5.  alfa = asin(sin(alfa)) - PI
6.  Now I want to get the point on the circle:
    newPoint.X = R * cos(alfa)
    newPoint.Y = R * sin(alfa)
7.  newPoint has X and Y like the circle would be in 0, 0, so I need to do:
    newPoint.X = circleCenter.X + newPoint.X
    newPoint.Y = circleCenter.Y + newPoint.Y
8. And then I draw to this point

And as you can see, it works perfectly for those coming from the left, but not so well for those coming from the right

Best Answer

The asin function requires you to do various tricks to deal with lines that can come from any direction (upper right, upper left, lower right, lower left) because it only gives you half a circle's worth of angles, $-\frac\pi2$ to $\frac\pi2,$ whereas you need angles all around the circle.

The atan2 function, if your software library has it, is usually much better for applications like this. You call it like this:

    atan2(b, a)

and it gives you a full range of angles from $-\pi$ to $\pi,$ which will be sufficient for lines coming from any direction. Moreover, you don't even need to compute $c.$

Related Question