Theo Walton - 1 year ago 56
C Question

# I can't tell if this rotation function is working as expected

So I derived a rotation function like this:

• I want to rotate (a, b, c) around the x axis

• the value of
`a`
will not change

• this is equivalent to rotating (b, c) around the origin in a 2d map

• for a 2d map in polar coordinates, rotating
`d`
degrees is as simple as:
`θ = θ + d`

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

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

since R2 = x2 + y2 and θ = arctan(y/x):

Q = (sqrt(x2 + y2) * cos(arctan(y/x) + d, sqrt(x2 + y2) * sin(arctan(y/x) + d)

I then made a C function that given a coordinate:
`a`
and
`rot_amount`
(usually 1) it would rotate my coordinate for me.

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

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

`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