Inverse Tangent

This is a discussion on Inverse Tangent within the C++ Programming forums, part of the General Programming Boards category; what do you think r is? With the coord pair r is the distance...

  1. #16
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    what do you think r is? With the coord pair r is the distance

  2. #17
    Registered User
    Join Date
    May 2003
    Posts
    195
    Dood if you want an EASY way to calculate inverse tan, all you have to do is incorporate sequences and series from Calculus.

    Okay because the derivative of inverse tan is 1/(1+x^2)

    transforming this into an infinite series you get 1+X^2+X^4+X^6... to x^infinity.

    Integrate this and you get

    X+(X^3)/3 + (X^5)/5 + (X^7)/7

    So thats your function. Make it recurse as many times as you want and make it so that the more times you recurse the function the more accurate it is.

  3. #18
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Hey Knee I'm willing to bet Quantrizi isn't in calculas yet

  4. #19
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>you need to convert the sin and cos to from radians to degress first. sorry about that
    Code:
    x = cos(theta) * (180/pi)
    y = sin(theta) * (180/pi)
    Maybe this works, and I'm not totally sure why it would, but from my understanding... it's the angle that needs to be converted to radians, not the trig'ed result (and besides which, you're 'converting' the result to degrees from radians...).
    Code:
    theta *= (pi / 180);
    x = r * cos(theta);
    y = r * sin(theta);
    That works perfectly for what I need on converting rectangular to polar.

    I am still having trouble though trying to change polar into rectangular. Do you have any ideas on howto fix it?
    Hold it right there... That whole r * sin(theta) bit WAS converting from polar to rectangular. Rectangular means using (x,y) to represent the vector. Polar is using an angle and magnitude.

    Anyhoo, to convert to polar, you need to:
    a) atan(y / x) to give you the reference angle (in radians - so convert to degrees)
    b) If x > 0 and y > 0, leave it; if x < 0 and y > 0, add 180; if x < 0 and y < 0, add 180; if x > 0 and y < 0, add 360.
    c) Magnitude can be found with Pythagoras: mag = sqrt((x * x) + (y * y));

    And there you have polar.

    **EDIT**
    @ KneeGrow:
    Dood if you want an EASY way to calculate inverse tan, all you have to do is incorporate sequences and series from Calculus.
    ...
    So thats your function. Make it recurse as many times as you want and make it so that the more times you recurse the function the more accurate it is.
    If you mean easy as in 'simple', I disagree. If you mean it as in 'requires little math knowledge', I disagree. If you mean it as 'Easy for the computer, i.e. is fast', I disagree. The atan() function finds the result exactly, as far as a double can be precise. I don't know how accurate your function is either; if you need to recurse very far though, I can imagine that it will be VERY slow with the accumulated stack-building/destroying etc. that you'll end up with, besides which you're doing power and division operations for each recursive call - and, if you recurse too far (unlikely, I suppose, unless you have an overenthusiastic coder), you'll run into stack overflows.

    It is highly unlikely that your homemade function will be any faster than the function provided with the compiler. Chances are, the compiler-writers either used that implementation themselves, or else they found a better way of doing it. Why reinvent the wheel, when you're just going to end up with something worse?
    Last edited by Hunter2; 05-08-2004 at 03:12 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #20
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    dang it you got me. Serves me right for not actually testing it. You are correct, theta needs to be converted from degress to radians and then put into the functions. I'm gotten so used to using radians since we've been told to get used to them.

  6. #21
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>I'm gotten so used to using radians since we've been told to get used to them.
    Lucky you. I still can't stand the darned things!
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #22
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Major difference between getting used to and liking.

    I threw together my own program for this. It seems to work. The hardest part is dealing with the limited domain of atan and having to check to make sure that x isn't zero (don't want those pesky floating point errors)
    Code:
    #include <iostream>
    #include <math.h>
    
    using namespace std;
    
    void polar2rect(double &, double &, double &, double &);
    void rect2polar(double &, double &, double &, double &);
    
    int main(void)
    {
      double x, y, r, theta;
    
      polar2rect((r=5), (theta=45), x, y);
      cout<<"Number 1: "<<"\tRad: "<<r<<"\tTheta: "<<theta<<"\tx: "<<x<<"\ty: "<<y<<endl;
    
      x = y= r = theta = 0.0;
    
      rect2polar((x=0), (y=4), r, theta);
      cout<<"Number 2: "<<"\tRad: "<<r<<"\tTheta: "<<theta<<"\tx: "<<x<<"\ty: "<<y<<endl;
    }
    
    void polar2rect(double &r, double &theta, double &x, double &y)
    {
      double rtheta = theta * (3.1415926535897932384626433832795/180);
      x = r * cos(rtheta);
      y = r * sin(rtheta);
    }
    
    void rect2polar(double &x, double &y, double &r, double &theta)
    {
      double ref;
      if ( x != 0.0 )
      {
        ref = atan(y/x);
        ref *= (180/3.1415926535897932384626433832795);
        if (x < 0.0)
        {
          if ( y > 0.0 )
            theta = 180 - ref;
          else
            theta = 180 + ref;
        }
        else
          theta = ref;
      }
      else
      {
        if ( y > 0.0)
          theta = 90;
        else if ( y < 0.0)
          theta = 270;
        else
          theta = 0;
      }
      r = pow(x*x + y*y, .5);
    
    }
    Oh and no I didn't type out pi, I copied and paste from the windows calculator

  8. #23
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>Oh and no I didn't type out pi, I copied and paste from the windows calculator
    Hehehe, call me a nerd but I can recite pi to 3 more decimal places than you typed out

    I actually have a function here that I wrote a little while ago, to find the angle from one point to another. I used it for my NetMaggotz game I actually included another parameter, specifying if it was in screen coordinates or 'normal' coordinates, and if it was screen then it would reverse the y coordinates, but in this case that isn't useful.
    Code:
    float angleTo(POINTFLOAT pos, POINTFLOAT dest)
    {
    	//Check for special cases
    	if(dest.x == pos.x)
    		return (dest.y >= pos.y)? 90.f : 270.f;
    	else if(dest.y == pos.y)
    		return (dest.x >= pos.x)? 0.f : 180.f;
    
    	//If no special cases, continue...
    	float result = radiansToDegrees((float)atan((dest.y - pos.y) / (dest.x - pos.x)));
    
    	//Get positive angles, in proper quadrants
    	if(dest.x < pos.x)		//Quad II, III
    		result += 180.f;
    	else if(dest.y < pos.y)	//Quad IV
    		result += 360.f;
    	
    	return result;
    }
    radiansToDegrees basically does the " *= pi/180", except that the constant multiplier is defined as a static constant, so the division operation doesn't get run every time the function is called. I love the ternary operator

    P.S. Say, why are you using pow() instead of sqrt()? lol...
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #24
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    P.S. Say, why are you using pow() instead of sqrt()? lol...
    Personal preference. Since I'm often using math that requires finding other roots and other powers besides 2, I prefer to use pow() rather then sqrt() so that I can more easily change my roots around if need be. Also since I think of roots as just fractional exponents it makes since to me

  10. #25
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Also, wouldn't it just be easier to use M_PI?
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  11. #26
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Nah copy and paste was much easier

  12. #27
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Using a series expansion will give a varied range of inaccuracies. For example when using a series to get the distance between 2 points in 2D the error range is +/- 3% and for 3D it is +/- 6%. If you are looking for accurate values...use sqrt(). If you are looking for speedy math functions...use the FPU in assembly.

    Floating point operations are extremely fast...in some instance faster than integer operations on modern CPUs so I wouldn't worry too much about using them.

  13. #28
    I am the worst best coder Quantrizi's Avatar
    Join Date
    Mar 2002
    Posts
    644
    Knee: Thantos is correct. I'm not in calculus yet. I'm in year 3 integrated math (it's like medium-advanced math).

    Hunter: Thanks. Polar coordinates use (radius, theta) though. But still, thanks I'll try out what you've given me.

    Thantos: Thanks I'm using atan2 though, but I'll try out atan again.

    Thanks all for your help. I'll see how it goes.

  14. #29
    I am the worst best coder Quantrizi's Avatar
    Join Date
    Mar 2002
    Posts
    644
    Here's my code now (thanks to Thantos I believe it was for the rect2polar and polar2rect functions. if it wasn't thantos, sorry):

    Code:
    static void Polar2Rect(double r, double theta){
    	double rtheta = theta * (pi/180);
    
    	x = r * cos(rtheta);
    	y = r * sin(rtheta);
    
    	cout << "x = r * cos(theta)\n";
    	cout << "x = " << r << " * cos(" << theta << ")\n";
    	cout << "x = " << x << "\n\n";
    
    	cout << "y = r * sin(theta)\n";
    	cout << "y = " << r << " * sin(" << theta << ")\n";
    	cout << "y = " << y << "\n\n";
    
    	cout << "Rect: (" << x << " , " << y << ")\n\n";
    }
    
    static void Rect2Polar(double x, double y){
    	double ref, x2, y2, r2 = 0;
    
    	ref = atan(y/x);
    	ref *= (180/pi);
    
    	if((x < 0) || (x > 0)){
    		if((ref >= 0) || (ref < 90)){
    			theta = ref;
    		}
    		if(ref == 90){
    			theta = ref;
    		}
    		if((ref > 90) || (ref < 180)){
    			theta = 180 - ref;
    		}
    		if(ref == 180){
    			theta = ref;
    		}
    		if((ref > 180) || (ref < 270)){
    			theta = 180 + ref;
    		}
    		if(ref == 270){
    			theta = ref;
    		}
    		if((ref > 270) || (ref < 360)){
    			theta = 360 - ref;
    		}
    		if(ref == 360){
    			theta = 0;
    		}
    	}
    
    	x2 = x * x;
    	y2 = y * y;
    	r2 = x2 + y2;
    
    	r = sqrt(r2); 
    
    	cout << "NOTICE: sqrt(...) means square root.\n";
    	cout << "        itan(...) means inverse tangent.\n\n";
    
    	cout << "r = sqrt(x^2 + y^2)\n";
    	cout << "r = sqrt(" << x << "^2 + " << y << "^2)\n";
    	cout << "r = " << r << "\n\n";
    
    	cout << "theta = itan(y/x)\n";
    	cout << "theta = itan(" << y << "/" << x << ")\n";
    	cout << "theta = " << theta << "\n\n";
    
    	cout << "Polar: (" << r << " , " << theta << ")\n\n";
    }
    Really, my only problem is that I still can't theta to display correctly. Does anyone have any ideas on why?

  15. #30
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    712
    It is really interesting how you can complicate such simple thing
    I would suggest this:
    Code:
    #include <iostream>
    #include <cmath>
    using namespace std;
    
    const double pi=3.14159;
    static void Polar2Rect(double r, double theta){
    	double rtheta = theta * (pi/180),x,y;
    
    	x = r * cos(rtheta);
    	y = r * sin(rtheta);
    
    	cout << "x = r * cos(theta)\n";
    	cout << "x = " << r << " * cos(" << theta << ")\n";
    	cout << "x = " << x << "\n\n";
    
    	cout << "y = r * sin(theta)\n";
    	cout << "y = " << r << " * sin(" << theta << ")\n";
    	cout << "y = " << y << "\n\n";
    
    	cout << "Rect: (" << x << " , " << y << ")\n\n";
    }
    
    static void Rect2Polar(double x, double y){
    	double r,theta;
    	r=sqrt(pow(x,2)+pow(y,2));
    	if(x==0 && y>0)
    		theta=90;
    	else
    		if(x==0 && y<0)
    			theta=270;
    		else
    		{
    			
    			theta=atan(y/x);
    			theta=theta*180/pi;
    			if(x<0 && y>0)
    					theta=180-theta;
    			else
    				if(x<0 && y<0)
    					theta=180+theta;
    				else
    					if(x>0 && y<0)
    						theta=360+theta;
    
    		}
    	
    
    	cout << "NOTICE: sqrt(...) means square root.\n";
    	cout << "        itan(...) means inverse tangent.\n\n";
    
    	cout << "r = sqrt(x^2 + y^2)\n";
    	cout << "r = sqrt(" << x << "^2 + " << y << "^2)\n";
    	cout << "r = " << r << "\n\n";
    
    	cout << "theta = itan(y/x)\n";
    	cout << "theta = itan(" << y << "/" << x << ")\n";
    	cout << "theta = " << theta << "\n\n";
    
    	cout << "Polar: (" << r << " , " << theta << ")\n\n";
    }
    
    int main()
    {
    
    	
    	double x=3,y=4;
    	Rect2Polar (2,3);
    	return 0;
    }
    Note that I only changed second function which is much simpler now.
    I leave simplification of the first one to you.
    This is ok if you want theta in range [0 360] degrees.
    You could also use theta [-180 180] degrees.

Page 2 of 3 FirstFirst 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to inverse a trig?
    By Diablo02 in forum C# Programming
    Replies: 4
    Last Post: 11-07-2007, 09:11 PM
  2. Multiplying tangent and bitangent by scale matrix
    By psychopath in forum Game Programming
    Replies: 6
    Last Post: 02-08-2006, 07:28 AM
  3. ROW OPERATIONS (finding Inverse) (im going crazy)
    By alexpos in forum C Programming
    Replies: 1
    Last Post: 11-20-2005, 09:07 AM
  4. inverse matrix
    By Yumin in forum C++ Programming
    Replies: 2
    Last Post: 11-14-2005, 11:06 PM
  5. Calculating inverse tangent
    By bludstayne in forum Tech Board
    Replies: 12
    Last Post: 02-27-2004, 11:59 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21