1. ## Calculating "o'clock" position

Hi all,

My maths is very rusty, so apologies for any bad terminology.

I'm working on some programming which involves describing places on a roughly circular map (if you're interested...) relative to the centre of it. I would like this description to read along the lines of "3 o'clock, 34% from centre" - this is to complement a function to search the map, and show the results in a way which can be understood by people with vision difficulties.

The map is an image file, and hence has co-ordinates starting from 0,0 in the top left. I've stored some meta data of the map which I feel will be useful - the co-ordinates of the middle of the circle, and the radius of it (large enough to encapsulate the whole map).

By subtracting the co-ordinates of a search result from the co-ordinates of the middle of the circle, I'm left with a set of co-ordinates relative to the middle of the circle - as if the circle was at 0,0 of a 2 axis graph which extends into the positive and negative.

This is where I'm stumped. I need to figure out what clock position (e.g. "3 o'clock") the search result is at, and how far from the centre it is - both of these will no doubt require the radius.

Any ideas or formulas to share?

Many thanks

For the sake of testing, here are the numbers:
Midpoint of map: 650, 635

Sample search result: 116, 824 (raw image co-ordinates) or -534, 189 (relative to midpoint of map)

2. Originally Posted by Kefka
Hi all,

My maths is very rusty, so apologies for any bad terminology.

I'm working on some programming which involves describing places on a roughly circular map (if you're interested...) relative to the centre of it. I would like this description to read along the lines of "3 o'clock, 34% from centre" - this is to complement a function to search the map, and show the results in a way which can be understood by people with vision difficulties.

The map is an image file, and hence has co-ordinates starting from 0,0 in the top left. I've stored some meta data of the map which I feel will be useful - the co-ordinates of the middle of the circle, and the radius of it (large enough to encapsulate the whole map).

By subtracting the co-ordinates of a search result from the co-ordinates of the middle of the circle, I'm left with a set of co-ordinates relative to the middle of the circle - as if the circle was at 0,0 of a 2 axis graph which extends into the positive and negative.

This is where I'm stumped. I need to figure out what clock position (e.g. "3 o'clock") the search result is at, and how far from the centre it is - both of these will no doubt require the radius.

Any ideas or formulas to share?

Many thanks

For the sake of testing, here are the numbers:
Midpoint of map: 650, 635

Sample search result: 116, 824 (raw image co-ordinates) or -534, 189 (relative to midpoint of map)
That's really a nice map!

1. If the search result has the coordinates $R(x_R\ ,\ y_R)$ then the distance to the midpoint is calculated by:

$d=\sqrt{(x_R - 650)^2+(y_R - 635)^2}$

Since you only can use integer numbers the value of d must be truncated. (Depending on the programming language you use the command should be something like trunc(d) or floor(d) or ...)

2. With the coordinates of R you can calulate the angle between the positive x-axis starting at the midpoint:

$\tan(\alpha)=\dfrac{y_r-635}{x_R-650}$

With this value you can determine the value of $\alpha$.

You have to consider 2 cases:

1. $y_R < 635 ~\implies~ 0^\circ \leq \alpha < 180^\circ$

2. $y_R \geq 635 ~\implies~ 180^\circ \leq \alpha < 360^\circ$

The 3'o clock position must be located in the sector of $75^\circ \leq \alpha < 105^\circ$

3. Hello, Kefka!

I hope I understood the problem . . .
Code:
                |
* * *
*     |     *  P
*      Q+ - - - o (x,y)
*        |     *  *
|   * r
*         |θ*       *
- - * - - - - o - - - - * - -
*      (xc,yc)      *
O
*        |        *
*       |       *
*     |     *
* * *
|

The center of the circle is $O(x_c,y_c)$
A given point is $P(x,y)$

The radius is: . $r \:=\:\sqrt{(x-x_c)^2 + (y-y_c)^2}$

If $R$ is the fixed radius of the base circle,
. . . the "percentage from the center" is: . $\frac{r}{R} \times 100$ percent.

Let $\theta$ be the clockwise angle between the y-axis and $OP$.

We see that: . $\begin{array}{ccc} PQ &=&r\sin\theta \\ OQ &=& r\cos\theta \end{array}\quad\Rightarrow\quad \begin{array}{cccc} x &=& x_c + r\sin\theta &{\color{blue}[1]}\\ y &=& y_c + r\cos\theta & {\color{blue}[2]}\end{array}$

. . $\begin{array}{ccccc}{\color{blue}[1]}\text{ becomes:}& r\sin\theta &=&x-x_c & {\color{blue}[3]}\end{array}$
. . $\begin{array}{ccccc}{\color{blue}[2]}\text{ becomes:} & r\cos\theta &=& y-y_c & {\color{blue}[4]}\end{array}$

Divide [3] by [4]: . $\frac{r\sin\theta}{r\cos\theta} \:=\:\frac{x_c+r\sin\theta}{y_c+r\cos\theta}$

. . Hence: . $\tan\theta \:=\:\frac{x_c+r\sin\theta}{y_c+r\cos\theta}\quad\ Rightarrow\quad \theta \;=\;\tan^{-1}\left(\frac{x_c+r\sin\theta}{y_c+r\cos\theta}\ri ght)$

Then the clock-reading is: . $\frac{\theta}{2\pi}\times 12 \:=\:\frac{6\theta}{\pi}$ o'clock.

4. Thanks for the help

Have got the distance from centre working with the following code - since (Xc, Yc) is always (0, 0) - the middle of the circle - the formula for that was very simple.... Here it is in code:

[PHP]sqrt( pow( $relx, 2 ) + pow($rely, 2 ) ); //calculates distance in pixels.[/PHP]

It was then a simple matter of turning it into a % using the radius of the city circle. It's a little bit off since the city isn't a perfect circle, but I'm sure it's close enough.

Now to try figure out the o'clock bits... I've always been much better at reading code than formulae... :P

UPDATE: After some prodding and fiddling and a more code-oriented discussion found at distance and angle between 2 xy coordinates [Archive] - WebDeveloper.com I've got the angle working... It seems to work! I think always having a (0, 0) point simplifies things a lot. Here's the code to get the angle...

[PHP]$angle = acos( -$rely / $dist ) / (M_PI * 2) * 360; //Calculate angle$angle = $rely < 0 ? (180-$angle) + 180 : $angle; //Correct for negative quadrants[/PHP] The second line is an if statement (in shorthand) saying "if the Y co-ordinate of the result is negative, then correct by doing (180-$angle) + 180, otherwise, leave it as is."

Now I'm just trying to figure out the converting to o'clock part... Soroban's formula doesn't seem to work...

e.g. using an angle of 90 (3 o'clock), we have (6 * 90) / Pi... which gives us 172 o'clock.

UPDATE 2: Oops, just figured out I can just divide the angle by 30, with rounding, and it's fine!

Oops, there's some kind of error still lurking... Hmm.

5. ## Solved at last!

Ok, the error which was lurking turned out to be me calculating the relative Y co-ordinate wrong - it was the inverse of what it should be... so, here's the code in full...

[PHP]$relx =$resultx - $middlex; //Calculate X of result relative to middle of map$rely = $middley -$resulty; //Calculate Y of result relative to middle of map

$dist = round( sqrt( pow($relx, 2 ) + pow( $rely, 2 ))); //Calculate distance$dist2 = $dist >$city_radius ? 100 : round(($dist /$meta[$name[0]]['r']) * 100); //Convert distance to %, correcting if over 100$angle = acos( $rely /$dist ) / ( M_PI * 2 ) * 360; //Calculate angle
$angle =$relx < 0 ? (180 - $angle) + 180 :$angle; //Correct for negative quadrants
$clock = round($angle / 30); //Convert to o'clock
$clock =$clock == 0 ? 12 : $clock; //Correct if rounded to 0 o'clock echo "Match found at ".$clock." o'clock, ".\$dist2."% out from middle.";[/PHP]

Huzzah! Thanks muchly for the help