Public Group

Rotating point around point in 2D

This topic is 1522 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello.

Its simple as it sounds, rotating a point around point to simulate clock.

But i got: the point that is supposed to rotate goes away from the point that it is supposed to rotate around and i don't know where i made the mistake.

sf::Vector2f is just a vector of two points, x and y.

Also main for sfml 2.0 for example.

void Rotate(sf::Vector2f & p, double angle, sf::Vector2f r)
{
double pi = 3.14159;
float s = sin(angle);
float c = cos(angle);

r.x -= p.x;
r.y -= p.y;

p.x += r.x * c - r.y * s;
p.y += r.x * s + r.y * c;
}

int main()
{
sf::RenderWindow win;
sf::VideoMode vidMod(800, 600, 32);
win.create(vidMod, "hello", sf::Style::Default);
win.setFramerateLimit(60);

sf::VertexArray vaL;
vaL.setPrimitiveType(sf::Lines);
vaL.append(sf::Vertex(sf::Vector2f(400, 300)));
vaL.append(sf::Vertex(sf::Vector2f(600, 300)));
double angle = 90;
bool done = false;
while (done == false)
{
win.clear();

sf::Event event;
while (win.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
done = true;
break;
default:
break;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::R))
Rotate(vaL[1].position, angle, vaL[0].position);

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{//Reset data to old
vaL[0] = (sf::Vertex(sf::Vector2f(400, 300)));
vaL[1] = (sf::Vertex(sf::Vector2f(600, 300)));
}

win.draw(vaL);

win.display();
}

return 0;
};

Edited by BaneTrapper

Share on other sites

What Álvaro said.

You need to convert to radians.

You also need to translate to the origin, rotate and then translate back.

Here is your rotate method, this should probably work:

void Rotate(sf::Vector2f & p, double angle, sf::Vector2f r)
{
double pi = 3.14159;
float rx = r.x;
float ry = r.y;

r.x -= p.x;
r.y -= p.y;

p.x = rx + r.x * c - r.y * s;
p.y = ry + r.x * s + r.y * c;
}


Share on other sites

As an aside, if you want to rotate multiple points by the same angle around the same center, you can re-use your sin() and cos() values. For example, rotating the four pointers of a rectangle around its center. Not sure how costly those functions are, so probably a moot point - just thought I'd mention it since I was needing to rotate the corners of a rectangle a few weeks back.

Edited by Servant of the Lord

Share on other sites
I take this opportunity to plug complex numbers (as I have done in numerous other occasions):

#include <iostream>
#include <complex>

typedef std::complex<double> Point, Vector, Rotation;

Rotation rotation_from_angle(double angle) {
return Rotation(std::cos(angle), std::sin(angle));

// Or the alternative:
//   return std::polar(1.0, angle);
}

Point rotate_around_center(Point point, Rotation rotation, Point center) {
return center + rotation * (point - center);
}

double const pi = std::atan(1.0) * 4.0;
double const degrees = pi / 180.0;

int main() {
Rotation quarter_turn_clockwise = rotation_from_angle(-90.0 * degrees);
Point point(3,5);
Point center(2,2);
Point rotated = rotate_around_center(point, quarter_turn_clockwise, center);
std::cout << rotated << '\n';
}


Share on other sites

You posted entirely too much code. You should be able to make a simple test call to your Rotate function and tell us what you expected to get and what you got instead. But by then you can probably inspect every operation by hand and figure out what the problem is.

I'll tell you that your `angle' is in degrees and you never convert it to radians before sending it through sin() and cos(). Friends don't let friends use degrees. You can use degrees to get an angle from the user, to show it to the user or to set the value of a constant, but then you immediately convert it to radians and do everything internally as radians.

Ooh, i did not know that. Thank you!

What Álvaro said.

You need to convert to radians.

You also need to translate to the origin, rotate and then translate back.

Here is your rotate method, this should probably work:

void Rotate(sf::Vector2f & p, double angle, sf::Vector2f r)
{
double pi = 3.14159;
float rx = r.x;
float ry = r.y;

r.x -= p.x;
r.y -= p.y;

p.x = rx + r.x * c - r.y * s;
p.y = ry + r.x * s + r.y * c;
}

The example code, thank you kind sir!

Share on other sites

I take this opportunity to plug complex numbers

Are you using complex numbers because they happen to be a pair of floats/doubles, or is there something about complex numbers that make them well-suited to this use? I'm rather ignorant of math. How is typedef'ing a std::complex better than typedef'ing some other kind of two-float class?

Share on other sites

I take this opportunity to plug complex numbers

Are you using complex numbers because they happen to be a pair of floats/doubles, or is there something about complex numbers that make them well-suited to this use? I'm rather ignorant of math. How is typedef'ing a std::complex better than typedef'ing some other kind of two-float class?

If you look at rotate_around_center Alvaro utlized the properties of complex numbers to achieve the rotation. The only use of trig was in capturing the initial angle of rotation as a complex number. You may be interested the article A Visual, Intuitive Guide to Imaginary Numbers.

1. 1
2. 2
3. 3
Rutin
12
4. 4
5. 5

• 26
• 10
• 9
• 9
• 11
• Forum Statistics

• Total Topics
633694
• Total Posts
3013378
×