954,500 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

school's back, and so am i :D

Hey everyone, I'm back in C++ this semester; Last semester I went through Structured C++ (and passed with a 4.0; many thanks to all of you!) and this semester I'm in OOP.

I don't have sample code yet because I haven't started. But I was talking to a classmate, and one of our programming exercises wants us to write a function that will modify a point (i.e., (3, 2)) so that it will rotate it 90 degrees, clockwise. Is there an easier way to do this rather than 5 or 6 "If" statements?


Example scenario:

I input point x as 3 and point y as 2. I select the option to rotate the point by 90 degrees and should get x as 2 and y as -3.

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

How do you rotate a point? A point is a point, there's no kind of transformation you can do until you have more than one. :D

Hamrick
Posting Whiz
325 posts since Jun 2007
Reputation Points: 180
Solved Threads: 34
 

Don't they teach simple geometry in schools any more?
http://mathworld.wolfram.com/RotationMatrix.html

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 
How do you rotate a point? A point is a point, there's no kind of transformation you can do until you have more than one. :D

I haven't taken a math class in many, many years, but from what I can recall, you rotate a point by drawing a vector starting at the origin and passing through the point, and then rotate that vector 90 degrees, in this case.

cscgal
The Queen of DaniWeb
Administrator
19,422 posts since Feb 2002
Reputation Points: 1,474
Solved Threads: 230
 
I haven't taken a math class in many, many years, but from what I can recall, you rotate a point by drawing a vector starting at the origin and passing through the point, and then rotate that vector 90 degrees, in this case.


Yes that's right, but it assumes you're rotating about the origin :) Either way, the origin is a point, so, as hamrick said, you need two points in order to rotate something. :)

Bench
Posting Pro
577 posts since Feb 2006
Reputation Points: 307
Solved Threads: 63
 

I like to do problems that are new to me. I found a few lines of trigonometry did just dandy.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

Thanks Dave; any tips as to which ones? ;)

Hamrick: sorry I didn't clarify. There is an assumed point (i'm guessing) that is constant at (0,0).

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

x' = x * cosine(90) + y * sine(90)
y' = x * sine(90) - y * cosine(90)

that look right?

edit] i think these are the right ones:

rx = x * cos(90) + y * sin(90) ;
ry = y * cos(90) - x * sin(90) ;

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 
point(double x_ = 0, double y_ = 0)
   : x(x_), y(y_), 
   radius(std::sqrt(x * x + y * y)), 
   angle(std::atan(y / x))
   {
   }
   void rotate(double radians)
   {
      angle = std::fmod(angle + radians, 2 * pi);
      x = radius * cos(angle);
      y = radius * sin(angle);
   }
Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

Ok, here's how I am doing it; is this wrong?

<pre><code>#include &lt;cmath&gt;
#include &lt;iostream&gt;
using namespace std ;

int main () 
{
    int x ;
    int y ;
    double angle ;
    int rx ;
    int ry ;

    angle = 90 ;
    x = 3 ;
    y = 2 ;
    rx = x * cos(angle) + y * sin(angle) ;
    ry = y * cos(angle) - x * sin(angle) ;

    cout &lt;&lt; rx &lt;&lt; &quot; &quot; &lt;&lt; ry &lt;&lt; endl ;

    return 0 ;
}</code></pre>


something is wrong, because for x i get 0 output, but when i do it in my calculator i get the right answer (2) !

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

Ok i've tried my equation with multiple expamples and i think it works, but why am i getting the wrong output?

for output i get x = 0 y = -3; x should be 2, y is right.

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

I'm not seeing how this is a course in OOP.

cscgal
The Queen of DaniWeb
Administrator
19,422 posts since Feb 2002
Reputation Points: 1,474
Solved Threads: 230
 

ha! Isn't it horrible when you have to spend more time on the math fundimentals than on the programming?

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

I'm getting ready for bed, but if someone could give me a hand in the next couple minutes I would really appreciate it!!

Here's my current delima:

//header

<pre><code>#pragma once

#include &lt;cmath&gt;
#include &lt;iostream&gt;
using namespace std ;

class Point
{
public:
    void menu ( ) ;
    void set ( int , int ) ;
private:
    void movePoints ( int , int ) ;
    void rotate ( int , int ) ;
    void getX ( ) const ;
    void getY ( ) const ;
    
    int x ;
    int y ;
    int rx ;
    int ry ;

    double angle ;
};



//other relevant code
//header file
#include &quot;prob3.h&quot;

//driver function
int main () 
{
    Point PointOpp ;

    int xCoord ;
    int yCoord ;

    cout &lt;&lt; &quot;Please enter your 'x' coordinant:  &quot; &lt;&lt; flush ;
    cin &gt;&gt; xCoord ;
    cout &lt;&lt; &quot;Please enter your 'y' coordinant:  &quot; &lt;&lt; flush ;
    cin &gt;&gt; yCoord ;

    PointOpp.set ( xCoord , yCoord ) ;
    PointOpp.menu ( ) ;
    
    return 0 ;
}



//last of relevant code
void Point::menu ( ) 
{
    int a ;
    int opp ;
    int xAm ;
    int yAm ;

    do
    {
    cout &lt;&lt; &quot;1.  Move the point&quot; &lt;&lt; endl ;
    cout &lt;&lt; &quot;2.  Rotate the point by 90 degrees&quot; &lt;&lt; endl ;
    cout &lt;&lt; &quot;3.  Print 'x' value&quot; &lt;&lt; endl ;
    cout &lt;&lt; &quot;4.  Print 'y' value&quot; &lt;&lt; endl ;

    cout &lt;&lt; &quot;Please specify an opperation:  &quot; &lt;&lt; flush ;
    cin &gt;&gt; opp ;

    switch ( opp )
    {
    case 1:
        cout &lt;&lt; &quot;Specify the ammount in which to move the 'x' axis point:  &quot; &lt;&lt; flush ;
        cin &gt;&gt; xAm ;
        cout &lt;&lt; &quot;Specify the ammount in which to move the 'y' axis point:  &quot; &lt;&lt; flush ;
        cin &gt;&gt; yAm ;
        movePoints ( xAm , yAm ) ;
        break ;
    case 2:
        rotate( x , y ) ;
        break ;
    case 3:
        getX ( ) ;
        break ;
    case 4:
        getY ( ) ;
        break ;
    case 5:
        a = 5 ;
        break ;
    default:
        cout &lt;&lt; &quot;Invalid opption specified :: Limit input to '1', '2', '3', or '4'&quot; &lt;&lt; endl ;
        exit(1) ;
    }
} while ( a != 5 ) ;
}


//rotate function
void Point::rotate ( int rx , int ry )
{
    x = rx * cos(angle) + ry * sin(angle) ;
    y = ry * cos(angle) - rx * sin(angle) ;
    cout &lt;&lt; x &lt;&lt; &quot; &quot; &lt;&lt; y &lt;&lt; endl ;
}</code></pre>

All the other functions work, so I haven't posted them in here. My rotate function just outputs the orriginal x and y coordinates, with no changes.

I am almost positive the equation works, but you may want to double-check me. Maybe I'm using the cos/sin functions wrong? I'm not very familiar with cmath; only used it a couple times.

thanks for any help; i r really tired so i'll be getting in bed in a few and will finish up tomorrow morning if noone has posted in the next 10 minutes or so.

nite all

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

Just happened to think someone may want to put my code in their compiler; here's all of my code (see attached).

Attachments prob3.func_.cpp (1.36KB) prob3.h (0.33KB) prob3.main_.cpp (0.56KB)
Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

> something is wrong, because for x i get 0 output,
If you had bothered to read the manual, you would have discovered that the trig functions work in radians, not degrees.

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 

ah! son of a...

thanks!

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

Ok, now I'm getting output, but it's 1 off (for x). The y values are still right.

Here's my updated function:

<pre><code>void Point::rotate ( int rx , int ry )
{
    angle = 1.57079633 ;
    x = rx * cos(angle) + ry * sin(angle) ;
    y = ry * cos(angle) - rx * sin(angle) ;
    cout &lt;&lt; x &lt;&lt; &quot; &quot; &lt;&lt; y &lt;&lt; endl ;
}</code></pre>
Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

If you're rotating 270 degrees (or any multiple of 2pi/4 radians), there's no reason to be using trig functions. Just replace (x,y) -> (y,-x). That's what your code simplifies to, once you replace cos(angle) with 0 and sin(angle) with 1. You don't really need to know trig for this, just congruent triangles :-)

Also, make a habit of thinking in radians (which is just a way of describing angles as a fraction of a full circle). It's useful. Always look upon degrees as inferior, except when navigating. It helps if you remember that 2pi is a fundamental constant, while pi is merely 2pi/2, and a quarter circle is 2pi/4, etc. The people who decided that 3.141... was worthy of a name while 6.283... was not were noobs.

Also, in your implementation above, you really shouldn't hard-code the constant 2pi/4. Write it as SOME_NAME_FOR_PI/2. The only reason for this is that your constant doesn't have all the digits you need -- and you don't want to go around copying some random mathematical constants all over the place, to 16 decimal places or whatever is needed to completely fill the floating point mantissa you're using. It's much easier to remember the name. You'll suffer inaccuracy from using a constant that only goes to a paltry 8 decimal places. And you're using floating point numbers which gives you inherent accuracy. For rotating integers 90 degrees, using floating point math is just immoral :-) You're getting errors not from the inaccuracy of your constant though, but of the inherent inaccuracy of floating point arithmetic. (For example, what does your computer think sin(4*atan2(1,1)) is?) When truncating that to an integer (as you are recklessly doing) you get numbers that are off by 1.

P.S. What the hello? What do rx and ry mean as members of the Point class? ... WTF?

Rashakil Fol
Super Senior Demiposter
Team Colleague
2,658 posts since Jun 2005
Reputation Points: 1,135
Solved Threads: 177
 

If you're rotating 270 degrees (or any multiple of 2pi/4 radians), there's no reason to be using trig functions. Just replace (x,y) -> (y,-x). That's what your code simplifies to, once you replace cos(angle) with 0 and sin(angle) with 1. You don't really need to know trig for this, just congruent triangles :-)

Also, make a habit of thinking in radians (which is just a way of describing angles as a fraction of a full circle). It's useful. Always look upon degrees as inferior, except when navigating. It helps if you remember that 2pi is a fundamental constant, while pi is merely 2pi/2, and a quarter circle is 2pi/4, etc. The people who decided that 3.141... was worthy of a name while 6.283... was not were noobs.

Also, in your implementation above, you really shouldn't hard-code the constant 2pi/4. Write it as SOME_NAME_FOR_PI/2. The only reason for this is that your constant doesn't have all the digits you need -- and you don't want to go around copying some random mathematical constants all over the place, to 16 decimal places or whatever is needed to completely fill the floating point mantissa you're using. It's much easier to remember the name. You'll suffer inaccuracy from using a constant that only goes to a paltry 8 decimal places. And you're using floating point numbers which gives you inherent accuracy. For rotating integers 90 degrees, using floating point math is just immoral :-) You're getting errors not from the inaccuracy of your constant though, but of the inherent inaccuracy of floating point arithmetic. (For example, what does your computer think sin(4*atan2(1,1)) is?) When truncating that to an integer (as you are recklessly doing) you get numbers that are off by 1.

P.S. What the hello? What do rx and ry mean as members of the Point class? ... WTF?

Ah cool, thanks. I just got my c++ teacher to look at it and he had no clue why I was getting the wrong output either. so we simplified the function to:

void Point::rotate ( double rx , double ry )
{
    //angle = 1.57079633 ;
    //x = rx * cos(angle) + ry * sin(angle) ;
    //y = ry * cos(angle) - rx * sin(angle) ;
    x = ry;
    y = -rx;
}



much easier. I was wanting to allow the user to input an angel so that they wouldn't be restricted to just 90 degrees, but oh'well. thanks for the help guys.

oh, and rx and ry weren't supposed to be there, thanks for point that out rash!

ps) if someone could figure out why my equations weren't outputting the right stuff, my teacher asked me to tell him what the problem was.

Duki
Nearly a Posting Virtuoso
1,475 posts since Jun 2006
Reputation Points: 817
Solved Threads: 32
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You