atan2

acalapai's Avatar

acalapai

28 Jul, 2020 02:45 PM

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

  1. Support Staff 1 Posted by Christopher Sta... on 29 Jul, 2020 08:35 PM

    Christopher Stawarz's Avatar

    Hi Ant,

    I can add atan2 to MWorks' expression parser. In the meantime, you can use the following MWEL expression macro 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

  2. 2 Posted by acalapai on 30 Jul, 2020 06:51 AM

    acalapai's Avatar

    Thanks!

  3. 3 Posted by acalapai on 30 Jul, 2020 11:54 AM

    acalapai's Avatar

    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:

    %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).

    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

  4. Support Staff 4 Posted by Christopher Sta... on 30 Jul, 2020 08:54 PM

    Christopher Stawarz's Avatar

    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. 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

  5. Support Staff 5 Posted by Christopher Sta... on 03 Aug, 2020 02:03 PM

    Christopher Stawarz's Avatar

    Hi Ant,

    The atan2 function is now in the MWorks nightly build.

    Cheers,
    Chris

  6. 6 Posted by acalapai on 03 Aug, 2020 04:35 PM

    acalapai's Avatar

    sounds great, thanks!

  7. Christopher Stawarz closed this discussion on 10 Aug, 2020 12:15 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac