Theo Walton Theo Walton - 9 months ago 32
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...

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