L'ultimo
L'ultimo

Reputation: 561

C: find the angle between two 3D-vectors

I wrote a code which should calculate the angle between two given 3D vectors following this formula:

$\theta = \cos^{-1} [\frac{v.v'}{|v||v'|}] = \cos^{-1} [\frac{aa' + bb'+cc'}{\sqrt{a^2 + b^2 + c^2} \sqrt{a'^2 + b'^2 + c'^2}}]$

This is the code:

#include <math.h>

float v1[3] = {0, 1, 2};
float v2[3] = {2, 2, 2};
float angle;

float dotProd(float *vec1, float *vec2) {
    return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
}

float norm(float *vec){
    float res;
    for (int i=0; i<3; i++)
        res += pow(vec[i], 2);
    return sqrt(res);
}

float angleBetween(float *vec1, float *vec2){
    return acosf(dotProd(vec1, vec2) / (norm(vec1) * norm(vec2)));
}

int main(){
    angle = angleBetween(v1, v2) * 180 / M_PI;
    printf("%f", angle);
}

The problem is that it returns a wrong angle. (I checked with geogebra and the right one with v1 = {0, 1, 2}, v2 = {2, 2, 2} is 39.2)

What am I doing wrong?

Upvotes: 1

Views: 1314

Answers (2)

Alex Reynolds
Alex Reynolds

Reputation: 96927

If you compile with -Wall, you'll get a hint:

$ gcc -Wall angle.c
angle.c:14:9: warning: variable 'res' is uninitialized when used here [-Wuninitialized]
        res += pow(vec[i], 2);
        ^~~
angle.c:12:14: note: initialize the variable 'res' to silence this warning
    float res;

You want to initialize res to zero, presumably.

There's another warning, but it is unrelated to this error. Still, you'll also want to #include the stdio.h header if you are using printf().

Get into the habit of compiling with warnings turned on. It can save you a lot of time with debugging.

Upvotes: 3

sigbjornlo
sigbjornlo

Reputation: 1043

You need to initialise your variables, or they will contain whatever value the memory that was allocated for them contains. In this case, changing the first line of float norm(float *vec) to float res = 0.0; will fix your code.

Upvotes: 2

Related Questions