C++ Rotating 2D shape in list

Started by
39 comments, last by homi576 8 years ago
Here, free code commentary. Don't get used to it, though; Nypyren is absolutely right that you should learn to go through the code yourself, either executing the code by hand or with the help of a debugger.

	int x, y, xx, yy; // Why are these variables here? I don't know what they mean. They should be declared where you use them, not here.
	double radians; // Same thing. At least this one has a better name. Although it's only the units...
	list<Vertex>::iterator itr = vertices.begin(); // One would normally put this line and the two marked with (*) in a single for loop.
	while (itr != vertices.end()) // (*)
	{
		x = centroid.getX(); // This would be a good place to declare the type of x. But the value you are assigning never gets used.
		y = centroid.getY();


		x = vertices.back().getX() - centroid.getX(); // Oh, so this is what you wanted x to be.
		y = vertices.back().getY() - centroid.getY();

		radians = degrees * PI / 180; // If degrees doesn't change inside the loop, why is this computation inside the loop?
		xx = round(x * cos(radians) - y * sin(radians)); // And why are you using integer coordinates? Rotation wonn't work too well..
		yy = round(y * cos(radians) + x * sin(radians));
		xx = xx + centroid.getX(); // Here you are modifying xx, which means the variable meant something up to this point, and something different from now on.
		yy = yy + centroid.getY();
		vertices.push_back(Vertex(xx, yy));

		itr++; // (*) It's probably better to use ++itr, but you are not ready to understand why, so don't worry about it too much for now.
	}

}

I now get no output to the console?


What output did you expect? I didn't see any line of code in what you posted that printed anything.
Advertisement
Just for fun, here's how I would probably implement something like that:

#include <iostream>
#include <vector>
#include <complex>

typedef std::complex<float> C;

std::vector<C> rotate_points(std::vector<C> const &points, float angle, C center_of_rotation) {
  std::vector<C> result;
  C rotation = std::polar(1.0f, angle);
  for (auto point : points)
    result.emplace_back(center_of_rotation + (point - center_of_rotation) * rotation);
  return result;
}

const float TAU = std::atan(1.0f) * 8.0f;

int main() {
  std::vector<C> points = {C(1.0f, 1.0f), C(-2.0f, -1.0f)};
  float angle = TAU * 0.25f; // A quarter of a turn, a.k.a. 90 degrees
  std::vector<C> rotated_points = rotate_points(points, angle, C(1.0f, 1.0f));
  for (auto point : rotated_points)
    std::cout << point << '\n';
}

Just for fun...


Dammit, why did I never learn cool properties of complex numbers when I was in school?!

I feel like there's all this awesome math I could be using, but the courses I took never introduced any of this.

Dammit, why did I never learn cool properties of complex numbers when I was in school?!


Yeah dude. Complex numbers, bro: http://acko.net/blog/how-to-fold-a-julia-fractal/
That was something I asked my math teacher way back then when discovering the notation for complex numbers and graphing were the same, and conversions between polar coordinates and Cartesian coordinates gave the same results as converting complex numbers in the calculator. The teacher just said "Huh, I didn't realize that". It was the first time I had that type of mind-blowing experience with math. Various things clicked in my brain, these are all the same thing just applied in different types of math.

Then when I was introduced to quaternions in my programming book (still in high school before the Interwebz were a thing, the book was published in the 1970s) I saw the math and realized they were doing exactly the same thing when converting between Euclidean coordinates and quaternion coordinates.

Math is stupid, until you figure out what it means or where it helps you. Then math is amazing.

Here, free code commentary. Don't get used to it, though; Nypyren is absolutely right that you should learn to go through the code yourself, either executing the code by hand or with the help of a debugger.


	int x, y, xx, yy; // Why are these variables here? I don't know what they mean. They should be declared where you use them, not here.
	double radians; // Same thing. At least this one has a better name. Although it's only the units...
	list<Vertex>::iterator itr = vertices.begin(); // One would normally put this line and the two marked with (*) in a single for loop.
	while (itr != vertices.end()) // (*)
	{
		x = centroid.getX(); // This would be a good place to declare the type of x. But the value you are assigning never gets used.
		y = centroid.getY();


		x = vertices.back().getX() - centroid.getX(); // Oh, so this is what you wanted x to be.
		y = vertices.back().getY() - centroid.getY();

		radians = degrees * PI / 180; // If degrees doesn't change inside the loop, why is this computation inside the loop?
		xx = round(x * cos(radians) - y * sin(radians)); // And why are you using integer coordinates? Rotation wonn't work too well..
		yy = round(y * cos(radians) + x * sin(radians));
		xx = xx + centroid.getX(); // Here you are modifying xx, which means the variable meant something up to this point, and something different from now on.
		yy = yy + centroid.getY();
		vertices.push_back(Vertex(xx, yy));

		itr++; // (*) It's probably better to use ++itr, but you are not ready to understand why, so don't worry about it too much for now.
	}

}

I now get no output to the console?


What output did you expect? I didn't see any line of code in what you posted that printed anything.

Great advice thank you very much, what you commented on really made sense.To output I call a drawshape function which plots the vertices from the vertex list.

As you can see from the code above I use push back to add the rotated vertices to the list and then re draw the shape with the draw shape function with the newly defined vertices, what I mean by no output is I draw the shape, which display the shape, rotate the vertices using the rotate function, clear the console to re draw but when I re draw nothing appears like it cant find the newly defined vertices.

As you can see from the code above I use push back to add the rotated vertices to the list and then re draw the shape with the draw shape function with the newly defined vertices, what I mean by no output is I draw the shape, which display the shape, rotate the vertices using the rotate function, clear the console to re draw but when I re draw nothing appears like it cant find the newly defined vertices.


From a symptom like "nothing appears" you can't know if the problem is in the piece of code you posted or somewhere else. Use the debugger to step into the function and see what it does. You can also add a couple of lines of code to print some debugging output, for instance with the list of vertices just before returning from the function.

I have narrowed it down to being an issue with the push back in the rotate function.

I have created a function to output the vertices before the rotate function and everything is as expected.

Once I introduce rotation, with the push back on the vertex list, the program hangs like its stuck in the while loop (now a for loop).

Should I be creating a separate list to hold the newly rotated x and y?

I have narrowed it down to being an issue with the push back in the rotate function.

I have created a function to output the vertices before the rotate function and everything is as expected.

Once I introduce rotation, with the push back on the vertex list, the program hangs like its stuck in the while loop (now a for loop).

Should I be creating a separate list to hold the newly rotated x and y?

Scratch that, I was getting caught in an infinite look because I was starting at the begin() of list instead off end(), so I would increment forward and then push back thus getting stuck if I'm correct. Now i start at the end() and -- and get my output of added x and y to my list.

Wait, I didn't realize you are pushing new elements into the same list you are iterating through. How is that ever going to end? You keep adding more work for yourself...

This topic is closed to new replies.

Advertisement