# Atan2 function

**URL:** <https://mworks.discourse.group/t/atan2-function/173>\
**Category:** Support\
**Created:** [July 28, 2020, 2:45pm UTC](https://mworks.discourse.group/t/atan2-function/173 "2020-07-28T14:45:28Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [July 28, 2020, 2:45pm UTC](https://mworks.discourse.group/t/atan2-function/173/1 "2020-07-28T14:45:28Z")

</div>

I am trying to calculate the angle of the mouse pointer with respect to the center of the screen and I am having hard time figuring out how to do it.

I have seen that recently atan has been introduced and that is great, but it is still very painful (at least to me) to calculate the angle from the mouse x an y positions.

I have a triangle moving around the screen together with the mouse and would like to have the triangle rotating according to the angle given by momentary x and y of the mouse cursor. The triangle would always point outward from the center of the screen.

This could be achieved either by adding atan2 to the basic expressions, or equipping a field “angle” to the mouse plugin. In this latter case, it might be useful to also have a field to specify the 0 point from which the angle is calculated.

just a suggestion  
thanks  
ant

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [July 29, 2020, 8:35pm UTC](https://mworks.discourse.group/t/atan2-function/173/2 "2020-07-29T20:35:47Z")

</div>

Hi Ant,

I can add atan2 to MWorks’ expression parser. In the meantime, you can use the following [MWEL expression macro](https://mworks.github.io/documentation/latest/mwel/index.html#expression) to emulate it:

```
%define atan2(y, x) atan(y / x) + pi() * (x < 0) * ((y >= 0) - (y < 0))

```

(I’m pretty sure I got that right, but you should double check my math.)

Cheers,  
Chris

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [July 30, 2020, 6:51am UTC](https://mworks.discourse.group/t/atan2-function/173/3 "2020-07-30T06:51:48Z")

</div>

Thanks!

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [July 30, 2020, 11:54am UTC](https://mworks.discourse.group/t/atan2-function/173/4 "2020-07-30T11:54:18Z")

</div>

This is my solution based on your macro:  
I added the conversion to go from radians to degrees and removed the logical checks, which I include later in the code:

```auto
%define atan2(y, x) ((atan(y / x) / (pi() / 180))) 

```

inside the protocol I then call the macro (y is flipped to make the unit circle rotating clockwise, according my my convention).

```auto
IO_mouse_theta = atan2(-IO_cursor_y, IO_cursor_x)
if (IO_cursor_x < 0) {
    IO_mouse_theta = IO_mouse_theta + 180 
}
if ((IO_cursor_x >= 0) #AND (IO_cursor_y < 0)) {
IO_mouse_theta = IO_mouse_theta + 360 
}
IO_mouse_theta = (round(IO_mouse_theta) + 90)%360

```

90, 180, or 360 is added according to x and y signs to have 0 in the upper position in the unit circle and to have a 360 mapping of the circle as opposed to a -/+180.

And it seems to work properly.

I have an additional question related to mwel macros: how would I write the if conditions I have in the code directly in the macro? I am confused a bit given that the macros do not behave exactly like a standard function (as far as I understand), so I do not really understand how to return values from the macro.

best  
ant

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [July 30, 2020, 8:54pm UTC](https://mworks.discourse.group/t/atan2-function/173/5 "2020-07-30T20:54:52Z")

</div>

Hi Ant,

> I have an additional question related to mwel macros: how would I write the if conditions I have in the code directly in the macro? I am confused a bit given that the macros do not behave exactly like a standard function (as far as I understand), so I do not really understand how to return values from the macro.

If you compute `IO_mouse_theta` in multiple spots in your protocol, then you can turn the computation in to a [statement macro](https://mworks.github.io/documentation/latest/mwel/index.html#statement). However, you’re correct that statement macros aren’t functions, and you can’t return values from them.

Expression macros aren’t functions, either, but they do act a bit more like them, in that they produce a value that can be used in other expressions. However, it’s awkward to implement conditional logic, as you need to do things like multiplying by `(x < 0) * ((y >= 0) - (y < 0))` in my definition of atan2. That said, I think the following encapsulates your computation as an expression macro:

```
%define mouse_theta(cursor_x, cursor_y) fmod(atan(-cursor_y / cursor_x) / (pi() / 180) + 180 * (cursor_x < 0) + 360 * (cursor_x >= 0 && cursor_y < 0) + 90, 360)

```

I definitely recommend testing that before using it in your experiment!

Cheers,  
Chris

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [August 3, 2020, 2:03pm UTC](https://mworks.discourse.group/t/atan2-function/173/6 "2020-08-03T14:03:27Z")

</div>

Hi Ant,

The [atan2 function](https://mworks.github.io/documentation/latest/expressions/index.html#mathematical) is now in the MWorks [nightly build](https://mworks.github.io/downloads/).

Cheers,  
Chris

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [August 3, 2020, 4:35pm UTC](https://mworks.discourse.group/t/atan2-function/173/7 "2020-08-03T16:35:30Z")

</div>

sounds great, thanks!

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [July 19, 2022, 8:27pm UTC](https://mworks.discourse.group/t/atan2-function/173/8 "2022-07-19T20:27:53Z")

</div>


