Search code examples
mathrotationatan2

How to change the "0°" position of a Knob in Snap.svg Library


I created a Knob (basically a circle) using the Snap.svg library which I rotate using Snap's transform function and rotate parameter.

I use two Snap built in functions, Snap.deg() and Snap.angle() to rotate the knob to a certain position (so that the "hand" faces the cursor or a touch point). My understanding is that Snap.angle works very similarly to the atan2 function, while Snap.deg converts a radian value to degrees

The issue I am having is that by default, the 0 / 360° position is when the hand of the knob (like the hour hand) is facing 3:00 and (the degrees go up when you move the knob clockwise) I want the 0 / 360° position to be when the hour hand is at 6:00 (with the degrees still going up for clockwise rotation).

I tried to just add subtract 90° but that just makes the value inaccurate because from 3:00 and 6:00 the angle calculated is between 0 and -90.

These values are important not because of how the physical knob looks (the current calculations work for that) but because I am using the calculated values elsewhere in the code and want a value of 0 for due south, 90 for due west, 180 for due north etc.

The reference for Snap.deg is: http://snapsvg.io/docs/#Snap.angle


Solution

  • The "normal" cartesian coordinates and trig operations use:

    x = cos(theta)
    y = sin(theta)
    

    and make zero degrees go along the positive X axis, and points sweep anticlockwise as theta increases.

    To start at the "6 o'clock" position and rotate clockwise instead, you need:

    x = -sin(theta)
    y = -cos(theta)
    

    i.e. x and y swapped, and negated.

    Hence, to get theta from x and y, use:

    theta = atan2(-x, -y);    // usually y, x