Knowing when I need the obtuse angle from a circle

183 Views Asked by At

Essentially i'm building a city building game, and for the road tool, I create these cubic Bezier curves. The curves need to form the arcs of circles, meaning they are restricted to 90 degree angles for them to be accurate. This isn't relevant to the question but it gives some background information on what i'm trying to achieve. When the user drags to build the road, you have a start point, and an end point where the mouse currently is. The user also creates an exit angle from the start point, which I use to calculate a gradient (also the tangent gradient of the start point.) Using this information and some basic trig, I can find the centre of the circle. Problem is that I now need to know the angle between the start point and the end point, from the centre. I can use the cosine formula to get this angle, however it only works for acute triangles. If the user is dragging far enough around the circle, the road will be greater than 180 degrees and the angle from the start point to the end point will be obtuse. I've attached a paint diagram of what i'm trying to achieve, hopefully you understand what I'm after. :) diagram

1

There are 1 best solutions below

8
On BEST ANSWER

Suppose the start vector is $v = (x, y)$. Compute a new vector $w = (-y, x)$. This will be 90 degrees counterclockwise from $v$. (Pretty cool, eh?)

Now take the vector $u$ whose angle from $v$ you want to find (measure CCW, from 0). Compute $$ c = u \cdot v \\ s = u \cdot w, $$ where both of those denote the dot-product of vectors, and then set $$ \theta = atan2(s, c) $$ (with the small proviso that in your programming language, you may want to use atan2(c, s), because there's always someone willing to screw with a standard, even if it is a stupid standard.)

The result will be an angle between $-\pi$ and $\pi$ (in almost every language). If the vector $u$ happens to be the zero vector, you'll probably still get $\theta = 0$, which isn't what you want -- you want an error. So you should check that at least one of $c$ and $s$ is nonzero, and if both are zero, throw an exception or raise an error. (Listen to the guy with 50 years of experience here: you really DO want to do this.)