Sign in to follow this  
homi576

C++ Rotating 2D shape in list

Recommended Posts

Hay everyone
 
  This is going to be a really basic concept but I am struggling with this immensely and am finding my self getting more and more confused as time goes on so any help with this would be a god send. 
 
   Basically I have a list which takes vertices for a shape, print out shape to the screen, such as a triangle and am trying to then implement a function which will rotate the triangle by a give input e.g 20 degrees. I have look over formulas and translating to the origin, perform the rotation and then move back to the centeroid but I an struggling to implement all this, I struggling to to see what the code is doing. Any help would be great thanks.

 

I have attached some .cpp and header files to the post for anyone to review, thanks. I have renamed the extensions as .txt to allow me to attach them.

Share this post


Link to post
Share on other sites
Fragment from shape.cpp:
    // rotates the vertices of a shape by a specified angle in degrees
    //
    // a simple method for rotating a point around 0,0 is
    // x = x * cos(degrees in radians) - y * sin(degrees in radians)
    // y = y * cos(degrees in radians) + x * sin(degrees in radians)
    // first translate the object to the origin of the graph (0,0)
    // then apply the rotation formula to each vertex of the shape
    // finally, translate the object back to its original centroid
    // remember that 0,0 is at the top left, not the bottom left, corner of the console
    // this means that your shapes may appear upside down
Is this home work?

The three steps are literally listed above.

Do you know how to translate? I'd suggest to start with implementing a translation on a vertex, and then on the shape.

Share this post


Link to post
Share on other sites

Fragment from shape.cpp:

    // rotates the vertices of a shape by a specified angle in degrees
    //
    // a simple method for rotating a point around 0,0 is
    // x = x * cos(degrees in radians) - y * sin(degrees in radians)
    // y = y * cos(degrees in radians) + x * sin(degrees in radians)
    // first translate the object to the origin of the graph (0,0)
    // then apply the rotation formula to each vertex of the shape
    // finally, translate the object back to its original centroid
    // remember that 0,0 is at the top left, not the bottom left, corner of the console
    // this means that your shapes may appear upside down
Is this home work?

The three steps are literally listed above.

Do you know how to translate? I'd suggest to start with implementing a translation on a vertex, and then on the shape.

 

Would I use a matrix to translate to point of origin?

Share this post


Link to post
Share on other sites

 

    // x = x * cos(degrees in radians) - y * sin(degrees in radians)
    // y = y * cos(degrees in radians) + x * sin(degrees in radians)

 

Instead, I would do this like so:

 

 

    // x2 = x * cos(degrees in radians) - y * sin(degrees in radians)
    // y = y * cos(degrees in radians) + x * sin(degrees in radians)

 

.. So x won't change in the first line, since it's used in the second one too (you're going to need the original x, not the rotated one for y rotation) :)

Share this post


Link to post
Share on other sites

// x = x * cos(degrees in radians) - y * sin(degrees in radians)
    // y = y * cos(degrees in radians) + x * sin(degrees in radians)

 
Instead, I would do this like so:
 

// x2 = x * cos(degrees in radians) - y * sin(degrees in radians)
    // y = y * cos(degrees in radians) + x * sin(degrees in radians)

 
.. So x won't change in the first line, since it's used in the second one too (you're going to need the original x, not the rotated one for y rotation) :)

 
There's a good habit I follow which is not to reuse variables. If the coordinates of the unrotated point are x and y, the coordinates of the rotated point should be something else, like x_rotated, y_rotated. Edited by Álvaro

Share this post


Link to post
Share on other sites

You posted the steps yourself. You don't need another tutorial, you already have the steps documented in your files as a tutorial.  If you want you can put the search terms in your favorite search engine and find more, but you don't need them.

 

Your teacher has spoon-fed you exactly the information you need, right there in those files you posted.  

 

If you need more help with it, contact your teacher.  It is their job to help you here, and if you don't talk to your teacher they won't know where you are struggling and where you need more instruction.  The teacher will assume you understand the material and move on to more complex material.

Edited by frob

Share this post


Link to post
Share on other sites

You posted the steps yourself. You don't need another tutorial, you already have the steps documented in your files as a tutorial.  If you want you can put the search terms in your favorite search engine and find more, but you don't need them.

 

Your teacher has spoon-fed you exactly the information you need, right there in those files you posted.  

 

If you need more help with it, contact your teacher.  It is their job to help you here, and if you don't talk to your teacher they won't know where you are struggling and where you need more instruction.  The teacher will assume you understand the material and move on to more complex material.

Its not the math part that is the issue its applying it to each vertices

Share this post


Link to post
Share on other sites

Thanks to all the members for there advice. Its a shame the moderators a so pretentious and self righteous. Not a pleasant experience on this site, does not live up to its reputation.

Share this post


Link to post
Share on other sites

We have a strict rule of not doing people's homework on the site.  

 

We will gladly help with a specific error or a specific problem you are having on homework when someone is clearly working on it and stumbling over something small like a syntax error, but anything more is directed back to your teacher. 

 

This pattern is common to nearly all programming forums and discussion boards. 

 

You are not asking about that type of problem, something where there is a subtle error in your code.  You have given us what appear to be the contents of your assignment and asked questions about topics your teacher should have covered.

Share this post


Link to post
Share on other sites

All I'm asking is how to apply rotation to a vertices, whats the point in knowledge when you don't share it? I'm not asking you to do an assignment Im basically asking to be pointed in the direction of an explanation of the logic, the files provided were just to show what the aim was.

 

Asking you guys to do the assignment would not benefit me in the slightest, I don't know whether you have miss interpreted my intentions with this thread but I want to learn how to do this, I am not a programming wiz kid or pick up a computer and automatically find myself in the matrix but I am committed to learning programming,

 

Sorry but it makes me angry that your implying I am here to get someone to do an assignment for me just to get a grade.

 

I'm not a little kid fresh in school, I'm 25 studying a degree and just need a helping hand which is difficult to get when 500 other people are trying to get that as well.

Share this post


Link to post
Share on other sites

So how far did you get with my suggestion to start with a translation of a single vertex?

 

We don't mind helping you, but "explaining the logic" is either the sentences you already have as comment in your assignment, or the actual code. To me, there is nothing in between, and the latter is exactly the solution you don't even want.

 

As such, I have no idea whatsoever what you don't understand, or where you are stuck. You haven't shown anything either, so I have nothing to point out where you make the wrong turn.

 

No doubt it's a simple communication problem, but that happens when you discuss something with a bunch of strangers across a text-only medium. A face-to-face discussion with someone like your teacher, is really a lot better in these cases.

Share this post


Link to post
Share on other sites

So how far did you get with my suggestion to start with a translation of a single vertex?

 

We don't mind helping you, but "explaining the logic" is either the sentences you already have as comment in your assignment, or the actual code. To me, there is nothing in between, and the latter is exactly the solution you don't even want.

 

As such, I have no idea whatsoever what you don't understand, or where you are stuck. You haven't shown anything either, so I have nothing to point out where you make the wrong turn.

 

No doubt it's a simple communication problem, but that happens when you discuss something with a bunch of strangers across a text-only medium. A face-to-face discussion with someone like your teacher, is really a lot better in these cases.

 

When you put it like that I see your position. I have gone away and had a look at working on applying the function to one vertices as such here is what I have so far, unfortunately it does not rotate the shape but moves it to the right instead.

 

Could you give a nod if I'm heading in the right direction or way off.

void Shape::rotate(double degrees)
{
	int x, y, xx, yy;
	double radians;

	x = vertices.back().getX() - centroid.getX();
	y = vertices.back().getY() - centroid.getY();

	int testX;
	int testY;

	list<Vertex>::iterator current = vertices.begin();

	while (current != vertices.end())
	{
		testX = (*current).getX();
		testY = (*current).getY();

		radians = degrees * PI / 180;
		xx = round(x * cos(radians) - y * sin(radians));
		yy = round(y * cos(radians) + x * sin(radians));
		
		testX = testX + xx +x;
		testY = testY + yy +y;

		(*current).setX(testX);
		(*current).setY(testY);
	
		current++;
	}
}

The function is them called like so

list<Shape*>::iterator itr = shapes.begin();
	while(itr!=shapes.end())
	{
		(*itr)->drawShape();
		(*itr)->rotate(20);
                Console::clear();
		(*itr)->drawShape();
		itr++;
	}

Share this post


Link to post
Share on other sites

I have revised the code again and can easily manipulate one of the vertices, the issue is when I iterate through the list it does do the other vertices

 

This allow to manipulate one of the vertices

int x, y, xx, yy;
	double radians;

	
		x = centroid.getX();
		y = centroid.getY();


		x = vertices.back().getX() - centroid.getX();
		y = vertices.back().getY() - centroid.getY();

		radians = degrees * PI / 180;
		xx = round(x * cos(radians) - y * sin(radians));
		yy = round(y * cos(radians) + x * sin(radians));
		xx = xx + centroid.getX();
		yy = yy + centroid.getY();
		vertices.push_back(Vertex(xx, yy));

once I add the iteration

	int x, y, xx, yy;
	double radians;
	list<Vertex>::iterator itr = vertices.begin();
	while (itr != vertices.end())
	{
		x = centroid.getX();
		y = centroid.getY();


		x = vertices.back().getX() - centroid.getX();
		y = vertices.back().getY() - centroid.getY();

		radians = degrees * PI / 180;
		xx = round(x * cos(radians) - y * sin(radians));
		yy = round(y * cos(radians) + x * sin(radians));
		xx = xx + centroid.getX();
		yy = yy + centroid.getY();
		vertices.push_back(Vertex(xx, yy));

		itr++;
	}

}

I now get no output to the console?

Share this post


Link to post
Share on other sites
It still has problems. I don't think I should provide any more hints - you should be able to solve this, but the code you're writing indicates that you don't understand some pretty fundamental things about the programming and debugging process.

Read the code that you have written, line by line, think about what it does. Think about what is going into each variable, and how it's being used. ESPECIALLY consider how each line of code will affect the OTHER lines of code that are going to execute later.

Compare this with what you think it should be doing. If you don't know what it should be doing, that's what you need to figure out first. Just copy/pasting code in different arrangements and saying it doesn't work is not how programming works.

You should step through it line-by-line in a debugger, watch what it's doing, and see where it isn't doing what you expect it to do. Edited by Nypyren

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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';
}

Share this post


Link to post
Share on other sites

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. Edited by Nypyren

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this