Chen Yu
Chen Yu

Reputation: 4077

how to calculate radian angle from start vector to end vector?

I want to the calculate radian anticlock wise angle (0-2*pi) from start vector to end vector. For example , start vector: {10,0}, end vector: {-10,-10}, want to get the angle {pi * 5/4}, but the result is {pi * 3/4}.

How to adjust to anticlose wise angle?

  def get_vector_angle({x, y}, {x1, y1}) do
    :math.acos(
      (x * x1 + y * y1) /
        (:math.sqrt(x * x + y * y) * :math.sqrt(x1 * x1 + y1 * y1))
    )
  end

The following is before code, it can work but too long and complex.(angle: by milli degree)

vector_angle({X_a,Y_a},{X_b,Y_b})->
    B =case {X_b,Y_b} of
           {0,0} ->
               0;
           _ ->
               get_x_direction(0,0,X_b,Y_b)
       end,
    C = case {X_a,Y_a} of
            {0,0} ->
                0;
            _ ->
                get_x_direction(0,0,X_a,Y_a)
        end,
    case (A = (B - C )/1000) > 360 of
        true ->
            A - 360;
        false ->
            case A < 0 of
                true ->
                    A + 360;
                false ->
                    A
            end
    end.

get_x_direction({0,0})->
    0;

get_x_direction({X_b,Y_b})->
    get_x_direction(0,0,X_b,Y_b).

get_x_direction({X,Y},{X_b,Y_b})->
    get_x_direction(X,Y,X_b,Y_b).

get_x_direction(A_x,Original_y,A_y,Target_y) when (A_x == A_y orelse A_y - A_x == 0.0) 
                                                  andalso Original_y > Target_y ->
    270000;

get_x_direction(A_x,Original_y,A_y ,Target_y) when (A_x == A_y orelse A_y - A_x == 0.0) 
                                                  andalso Original_y < Target_y ->
    90000;

get_x_direction(A,Original_y,A,Target_y) when Original_y == Target_y ->
    throw(?MSG_HANOCH_DIRECTION_DATA_ERROR);

get_x_direction(Original_x,Original_y,Target_x,Target_y) when Target_y == Original_y ->
    case Target_x > Original_x of
        true ->
            0;
        false ->
            180000
    end;


get_x_direction(Original_x,Original_y,Target_x,Target_y)->
    B = round(math:atan((Target_y - Original_y)/(Target_x - Original_x))
                    * ?PI_CONVERT_2),
    C = case (Target_x - Original_x) < 0  of
        true ->
            B + 180000;
        false ->
            B
    end,
    case C < 0 of
        true->
            C + 360000;
        false ->
            C
    end.

Upvotes: 0

Views: 238

Answers (3)

Rune Trold
Rune Trold

Reputation: 51

The formula you use calculate the smallest angle between the two vectors. Which will be between 0 and pi. So 3/4*pi is correct.

If you wanna get the "larger" angle, you can just subtract the found one from 2pi.

I'm not sure what you mean by differentiate between the start and end vector. Will the angle you want to find always be the "counterclockwise" one?


Alright :) To determine the angle you can use that the dot product relates to cos and the determinant relates to sine, of the angle between the vectors. Where:

dot({x,y}, {x1, y1}) = x * x1 + y * y1

det({x,y}, {x1, y1}) = x * y1 - x1 * y

Then you calculate the angle with artan2:

angle = atan2( dot(), det() )

If the angle is negative then add 2*pi and you'll find the counterclockwise one.

Just make sure that the first input vector in the determinant is your starting vector.

Upvotes: 1

creme332
creme332

Reputation: 1945

You can use the concept of argument from complex numbers. The argument of a complex number is the anticlockwise angle the complex number makes with the positive horizontal axis.

To calculate the argument of a vector :

  • If vector is in first quadrant (y>=0 && x>=0), arg(v) = arctan(y/x)
  • If vector is in second quadrant (y>=0 && x<=0), arg(v) = pi - arctan(|y/x|)
  • If vector is in third quadrant (y<=0 && x<=0), arg(v) = pi + arctan(|y/x|)
  • If vector is in fourth quadrant (y<=0 && x>=0), arg(v) = - arctan(|y/x|)

Now to find the anticlockwise angle between two vectors : |arg(v1) - arg(v2)|

Upvotes: 1

Matt
Matt

Reputation: 2802

Because cosine is a repeating function most implementations of arccosine return values between 0 and pi. Take the degrees of 170 and 190. They both produce a cosine of -.98481. You will need to determine which quadrant you're in to find the angle you're after. If you use sine along with cosine you can check the signs to figure out where you are. Taking that same example as before, the value of sine for 170 and 190 are .17453 and -.17453 respectively.

A simpler approach is to use atan2 which already takes into account quadrant. There are a few ways to do it with atan2 such as atan2(y1,x1) - atan2(y,x) or atan2(x*y1 - y*x1, x*x1 + y*y1), for your example both of these will return -2.35619 radians or -135 degrees. Since it's negative add 2 pi and you get 5/4 pi.

Upvotes: 1

Related Questions