Theo Walton - 1 year ago 45

C Question

So I derived a rotation function like this:

- I want to rotate (a, b, c) around the x axis
- the value of will not change
`a`

- this is equivalent to rotating (b, c) around the origin in a 2d map
- for a 2d map in polar coordinates, rotating degrees is as simple as:
`d`

`θ = θ + d`

- for a point P(x, y), and
`x = Rcos(θ)`

`y = Rsin(θ)`

- so let Q be the point after rotation, then
`Q = (Rcos(θ + d), Rsin(θ + d))`

since R

Q = (sqrt(x

I then made a C function that given a coordinate:

`a`

`rot_amount`

`static void xrotate_coor(t_coor *a, int rot_amount)`

{

double d;

double e;

d = a->y;

e = a->z;

if (e == 0 && d == 0)

return ;

if (d == 0)

{

a->y = sqrt(d * d + e * e) * cos(atan(INFIN) + rot_amount * M_PI / 50);

a->z = sqrt(d * d + e * e) * sin(atan(INFIN) + rot_amount * M_PI / 50);

return ;

}

a->y = sqrt(d * d + e * e) * cos(atan(e / d) + rot_amount * M_PI / 50);

a->z = sqrt(d * d + e * e) * sin(atan(e / d) + rot_amount * M_PI / 50);

}

INFIN is a macro I set to 999999.

I am not sure if it is correct though since using this formula the shape I am rotating is getting deformed so I feel like there is a flaw in my logic somewhere...

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

... the shape I am rotating is getting deformed ...

`atan(e / d)`

loses the 4 quadrant nature of `a->y, a->z;`

. Consider that with OP's code, if the `y,z`

are negated, the same result ensues. @Nominal Animal

```
d = -(a->y);
e = -(a->z);
...
atan(e / d)
```

Instead use a 4 quadrant arctangent.

`double atan2(double y, double x);`

The`atan2`

functions compute the value of the arc tangent of`y`

/`x`

, using the signs of both arguments to determine the quadrant of the return value. A domain error may occur if both arguments are zero.

Other suggested improvements below too.

```
#include <math.h>
static void xrotate_coor(t_coor *a, int rot_amount) {
double d = a->y;
double e = a->z;
double r = hypot(d, e); // vs. sqrt(d * d + e * e)
if (r) {
double angle = atan2(e, d);
angle += rot_amount * (M_PI / 50);
a->y = r * cos(angle);
a->z = r * sin(angle);
}
}
```

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**