C++: Rotating a Vector Around a Certain Point

C++: Rotating a vector around a certain point

The answer depends on your coordinate system.

Computer graphics coordinate system, with (0,0) at Top left

If you are using a computer graphics vector implementation where (0,0) is the top left corner and you are rotating around the point (dx, dy), then the rotation calculation, including the translation back into the original coordinate system, would be:

x_rotated =      ((x - dx) * cos(angle)) - ((dy - y) * sin(angle)) + dx
y_rotated = dy - ((dy - y) * cos(angle)) + ((x - dx) * sin(angle))

Physics/Maths coordinate system, with (0,0) at Bottom left

If you are using a more traditional real world coordinate system, where (0,0) is the bottom left corner, then the rotation calculation, around the point (dx, dy) including the translation back into the original coordinate system, would be:

x_rotated = ((x - dx) * cos(angle)) - ((y - dy) * sin(angle)) + dx
y_rotated = ((x - dx) * sin(angle)) + ((y - dy) * cos(angle)) + dy

Thanks to mmx for their comment on Pesto's post, and to SkeletorFromEterenia for highlighting an error in my implementation.

Rotating a point about another point (2D)

First subtract the pivot point (cx,cy), then rotate it (counter clock-wise), then add the point again.

Untested:

POINT rotate_point(float cx,float cy,float angle,POINT p)
{
float s = sin(angle);
float c = cos(angle);

// translate point back to origin:
p.x -= cx;
p.y -= cy;

// rotate point
float xnew = p.x * c - p.y * s;
float ynew = p.x * s + p.y * c;

// translate point back:
p.x = xnew + cx;
p.y = ynew + cy;
return p;
}

Rotate a point around another point

The problem is int center = radius which you are setting int radius = 576. This doesn't make sense as surely you are rotating about a point that should have an x and y location.

Given you are rotating around the origin the center x and y should both be 0 not 576.

So, given that, try this.

/// <summary>
/// Rotates one point around another
/// </summary>
/// <param name="pointToRotate">The point to rotate.</param>
/// <param name="centerPoint">The center point of rotation.</param>
/// <param name="angleInDegrees">The rotation angle in degrees.</param>
/// <returns>Rotated point</returns>
static Point RotatePoint(Point pointToRotate, Point centerPoint, double angleInDegrees)
{
double angleInRadians = angleInDegrees * (Math.PI / 180);
double cosTheta = Math.Cos(angleInRadians);
double sinTheta = Math.Sin(angleInRadians);
return new Point
{
X =
(int)
(cosTheta * (pointToRotate.X - centerPoint.X) -
sinTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.X),
Y =
(int)
(sinTheta * (pointToRotate.X - centerPoint.X) +
cosTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.Y)
};
}

Use like so.

Point center = new Point(0, 0); 
Point newPoint = RotatePoint(blueA, center, 45);

Obviously if the center point is always 0,0 then you can simplify the function accordingly, or else make the center point optional via a default parameter, or by overloading the method. You would also probably want to encapsulate some of the reusable math into other static methods too.

e.g.

/// <summary>
/// Converts an angle in decimal degress to radians.
/// </summary>
/// <param name="angleInDegrees">The angle in degrees to convert.</param>
/// <returns>Angle in radians</returns>
static double DegreesToRadians(double angleInDegrees)
{
return angleInDegrees * (Math.PI / 180);
}

/// <summary>
/// Rotates a point around the origin
/// </summary>
/// <param name="pointToRotate">The point to rotate.</param>
/// <param name="angleInDegrees">The rotation angle in degrees.</param>
/// <returns>Rotated point</returns>
static Point RotatePoint(Point pointToRotate, double angleInDegrees)
{
return RotatePoint(pointToRotate, new Point(0, 0), angleInDegrees);
}

Use like so.

Point newPoint = RotatePoint(blueA, 45);

Finally, if you are using the GDI you can also simply do a RotateTransform.
See: http://msdn.microsoft.com/en-us/library/a0z3f662.aspx

Graphics g = this.CreateGraphics();
g.TranslateTransform(blueA);
g.RotateTransform(45);

Algorithm for finding new points of rotating a vector

I think it would be best to use the following code.
I've made some minor modifications and supplements to your code.

The calculation part of 'theta' was slightly modified.
And, you can refer to the rotation algorithm from the following URL.

Rotation (mathematics)

struct Vector2D
{
public double x;
public double y;
public double theta;

public Vector2D(double x, double y)
{
(this.x, this.y) = (x, y);
theta = x != 0 ? Math.Atan(y / x) : Math.Sign(y) * Math.PI / 2.0;
}

public double Magnitude()
{
return Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
}

public (double x, double y) PointFromRotation(double angle)
{
double Sint = Math.Sin(angle);
double Cost = Math.Cos(angle);

double rX = x * Cost - y * Sint;
double rY = x * Sint + y * Cost;

return (rX, rY);
}
}


Related Topics



Leave a reply



Submit