Section 4.14 Case Study: Point Rotation
Subsection 4.14.1 The problem
When drawing graphics, computers generally work with polygons defined by points. To draw an object as if it is far away, or rotated, the computer can transform the points before drawing the shape. We want to do a simple version of transforming a point. Given the point A at (2, 4), we would like to write a program that says where that point ends up if it is rotated by a certain number of degrees (\(ΞΈ\) - pronounced βthetaβ) around the origin (0, 0).
The figure below illustrates what we are trying to do. Use the slider to change \(ΞΈ\text{,}\) and it will show you the new location of A as Aβ.
Subsection 4.14.2 Making a Plan
Let us start with the same questions as last time:
- βWhat data you will start with?β
- a number of degrees
- βWhat values you want to calculate?β
- x and y position after (2, 4) is rotated
- βHow will you calculate those values?β
- Some searching revealed these formulas:\begin{gather*} x' = x * cos(ΞΈ) - y * sin(ΞΈ)\\ y' = x * sin(ΞΈ) + y * cos(ΞΈ) \end{gather*}
Before we start writing code, we should test these formulas. We can do that by hand. If we rotate the point (2, 4) by 90 degrees, I get (-4, 2). If we rotate it by 45 degrees, we should get (-1.41, 4.24). Those values seem to match what the animation shows. This confirms that we know how to do the math and will allow us to check the results of our code.
Subsection 4.14.3 Checking Our Tools
If we havenβt used a function like
sin
before, it makes sense to test it out and ensure that we know that it works correctly. So I am going to start with that. I will not worry about reading input yet, I will just hard code in a test value. Here is my first attempt:
Although 45 could be stored into an int, there is no reason
theta
needs to be a whole number. So it makes sense to use a double as its type. And I canβt use the symbol, so I have spelled out its name.
When I run this program, I get
sinValue: 0.850904
. That does not look right. I expected to get approximately 0.707.
The
sin
function in C++ expects the angle to be in radians, not degrees. So I need to convert the degrees to radians before I can use the sin
function. I can do that by multiplying the degrees by \(Ο/180\text{.}\) Here is my next attempt:
Note that since Ο should never change, I have made it a
const double
. And, as is convention for constants, I have named it using all uppercase. I have also renamed what used to be theta
to thetaDegrees
to clearly indicate what it stores and differentiate it from thetaRadians
.
This version seems to work better. Now I feel confident about trying to solve the actual problem.
Subsection 4.14.4 Calculating x2
Now letβs try to calculate the new location of x. In the formula, it is written as \(x'\) (pronounced βx primeβ) but we canβt use that symbol in a variable name, so we will call it
x2
. I also need to set some values for the original x and y.
This seems to work, or at least the answer matches what I calculated by hand.
Subsection 4.14.5 Calculating y2
Now letβs add code to calculate y2. Add the following two lines to the program above (right after the lines that calculate
x2
) and then run it.
double y2 = x * sinValue + y * cosValue;
cout << "y2: " << y2 << endl;
Checkpoint 4.14.2.
Subsection 4.14.6 Wrapping up
Now that we have the code working, we can add code to read in the value of theta from the user. Here is the final version of the program:
We might also choose to condense the code a bit. We could avoid storing the variables
sinValue
and cosValue
by calculating sin and cos of theta where they are needed like this:
...
double thetaRadians = thetaDegrees * numbers::pi / 180;
double x = 2;
double y = 4;
double x2 = x * cos(thetaRadians) - y * sin(thetaRadians);
cout << "x2: " << x2 << endl;
double y2 = x * sin(thetaRadians) + y * cos(thetaRadians);
cout << "y2: " << y2 << endl;
However, I am choosing to leave them in place. Using the variables makes it easier to go back and check the values of those calculations if I realize there is a bug. It also avoids redoing the work of calculating sin and cos of theta.
Note 4.14.1.
Again, we have worked on this program one piece at a time. This is the most effective way to write code. Write a bit, test what you have, and do not continue building on that until you are sure it is working.
Checkpoint 4.14.3.
You have attempted of activities on this page.