Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Angle from X,Y (http://www.chiefdelphi.com/forums/showthread.php?t=27685)

Astronouth7303 10-04-2004 18:41

Angle from X,Y
 
How do you find the angle from (X, Y)? :confused:

And how do you optimize this for realtime on the FRC? :confused:

And One Of Astronouth's Rare Contensts: Why would I care? :D

Yan Wang 10-04-2004 18:45

Re: Angle from X,Y
 
Angle from (x,y) (I'm assuming on a normal Cartesian Plane) to what in relation to what as a vertex?

ie. angle between (x,y) and x-axis with origin as vertex.

Astronouth7303 10-04-2004 18:47

Re: Angle from X,Y
 
The angle between (0,0) and (x,y) in relation to the x axis (A horizantal line, y=0)

FotoPlasma 10-04-2004 19:04

Re: Angle from X,Y
 
The inverse tangent function (arctan) will give you the angle from the origin to a point. For example: given (x,y), arctan(y/x) = the angle from the origin to the point (x,y).

If you search CD for something like "arctan" or "trig" or "trigonometry", you should get a fair amount of results already covering implementation of trigonometric functions on the FRC controller.

I don't have any experience using these, myself, but I've heard that a few teams have had success with using an arbitrary degree Taylor series approximation of trig functions.

Astronouth7303 10-04-2004 20:28

Re: Angle from X,Y
 
Doesn't arc tangent return an angle for a given slope? As in: -90 to 90.
I'm talking about 360 degrees. Like a Rectangular to Polar converter thing.

Joe Ross 10-04-2004 20:40

Re: Angle from X,Y
 
Quote:

Originally Posted by Astronouth7303
Doesn't arc tangent return an angle for a given slope? As in: -90 to 90.
I'm talking about 360 degrees. Like a Rectangular to Polar converter thing.

You then look at the signs of X and Y to see if what quadrant the angle is in.

Astronouth7303 10-04-2004 20:58

Re: Angle from X,Y
 
:WHAP: Duh
Code:

unsigned int GetAngle(signed int X, signed int Y)
{
  signed int Angle = arctan(Y/abs(X));
 unsigned char OtherSide = IsNegetive(X);
 unsigned int Value = 0;
 
 if (OtherSide)
  Value = 180 - Angle + 360;
 else
  Value = Angle + 360;
 
 Value %= 360;
 return Value;
}

Unfortunately, you have to use a float for Angle because angles between -45 and 45 are as important as the others. I suppose I could flip X and Y around for that.

[Changed that tan to arctan]

michael_obrien 10-04-2004 22:23

Re: Angle from X,Y
 
I don't know much about programming, but I screwed around with winamp AVS for a while, and on that there was a function known as "atan2(x,y)" which was the same as atan but it automatically corrected for quadrants... isn't there anything simular in C? I mean, C is much more powerful than that AVS junk from what I understand, it should at least have the same capabilities.

The Lucas 10-04-2004 22:51

Re: Angle from X,Y
 
Quote:

Originally Posted by Astronouth7303
:WHAP: Duh

Unfortunately, you have to use a float for Angle because angles between -45 and 45 are as important as the others. I suppose I could flip X and Y around for that.

[Changed that tan to arctan]

You don't need a float to represent (Y/X). Just try ((Y*100)/X) and scale your arctangent function to reflect this. This works well if you are using a lookup table. However, I would use a float if I was using a McLaurin series. Otherwise you are likely to overload a long the when you start getting into the higher powers (100^5 is way too big). Also you might want to check to make sure X is not zero before dividing by it.

Quote:

Originally Posted by michael_obrien
I don't know much about programming, but I screwed around with winamp AVS for a while, and on that there was a function known as "atan2(x,y)" which was the same as atan but it automatically corrected for quadrants... isn't there anything simular in C? I mean, C is much more powerful than that AVS junk from what I understand, it should at least have the same capabilities.

IFI doen not provide us with libraries of functions like this, but C certainly has them. The standard atan function requires more prcessing and floating point math than most FIRST programmers want to put in thier RC

Matt Reiland 12-04-2004 16:29

Re: Angle from X,Y
 
This is the formula that LeoM posted a while back to get the angle from rectangular coordinates. Worked extremely well back in 2002

Temp1 was the positive distance in X direction
Temp2 was the positive distance in Y direction
temp3 = (temp2*127) / SQR((temp1*temp1)+(temp2*temp2)) 'Make values on a 127 unit circle

ss_degrees = ((1-(temp3/118))*(((temp3+181)*temp3+744)/769))+((temp3/118)*(((((3*temp3-707)*temp3+42611)/20))+((temp3-115)/3)))

ss_degrees = (ss_degrees*180)/128 'Convert to Degrees

Astronouth7303 13-04-2004 07:33

Re: Angle from X,Y
 
Ay. The problem is I don't get what it's doing.

Astronouth7303 13-04-2004 07:34

Re: Angle from X,Y
 
My current code is like this:
Code:

#define abs(Num) ( ((Num) < 0) ? (0 - (Num)) : (Num) )
#define IsNegetive(Num) ( ((Num) < 0) ? 255 : 0 )
#define IsPositive(Num) ( ((Num) > 0) ? 255 : 0 )



/* 360 degrees = 256
  0 =  0 (0x00)
 45 =  32 (0x20)
 90 =  64 (0x40)
135 =  96 (0x60)
180 = 128 (0x80)
225 = 160 (0xA0)
270 = 192 (0xC0)
315 = 224 (0xE0) */

unsigned char GetAngle(signed char X, signed char Y)
{
  signed int  Angle = 0;
 unsigned char OtherSide = (X < 0) ? 255 : 0;
 unsigned char Value = 0;
 unsigned char Simple = (X == 0) | (Y == 0) | (X == Y);
 
 //Perform Simple tests
 if (Simple)
 {
  if (X == 0)
  if (Y < 0)
    Angle = 192; // Down
  else if (Y > 0)
    Angle = 64; //Up
  else // Y == 0
    Angle = 0; //None, default
 
  if (Y == 0)
  if (X < 0)
    Angle = 128; // Left
  else if (X > 0)
    Angle = 0; //Right
  else // X == 0
    Angle = 0; //None, default
 
  if (X == Y)
  {
  switch( (IsNegetive(X) & 2) | (IsNegetive(Y) & 1) )
  {
    case 0: //++
    Angle = 32;
    break;
    case 2: //-+
    Angle = 96;
    break;
    case 3: //--
    Angle = 160;
    break;
    case 1: //+-
    Angle = 224;
    break;
  }
  }
 }

 //Again for goto, no braces
 if (Simple) goto Done; //I hope that's right
 
 if (X > Y) //Preserve accuracy
  Angle = 64 - atan(abs(X)/Y);
 else
  Angle = atan(abs(X)/Y);
 
 Angle = OtherSide ? (127 - Angle) : Angle;
 Value = (unsigned char)((Angle + 255) % 255);
 
Done:
 return Value;
}

Nobody's answered the last question!

Greg Ross 13-04-2004 13:35

Re: Angle from X,Y
 
Quote:

Originally Posted by Astronouth7303
Nobody's answered the last question! [regarding optimization]

Jamie,

The best advice I've ever heard about optimization is "Don't -- until you need to." You generally want to get your code working, and only then worry about optimizing -- if necessary.

Astronouth7303 13-04-2004 21:22

Re: Angle from X,Y
 
I was refeing to post 1:
Quote:

Originally Posted by Astronouth7303
And One Of Astronouth's Rare Contensts: Why would I care? :D


Greg Ross 13-04-2004 21:56

Re: Angle from X,Y
 
Quote:

Originally Posted by Astronouth7303
Quote:

Originally Posted by Astronouth7303
And One Of Astronouth's Rare Contensts: Why would I care? :D

I was refeing to post 1:

OK. And now I'm confused. I don't understand "And One Of Astronouth's Rare Contensts", so I don't know how to answer "Why would I care?" :confused: (I originally thought that line was part of your signature, so I just ignored it.)

Astronouth7303 14-04-2004 07:24

Re: Angle from X,Y
 
It was a joke. The prize: Absolutely nothing!

Basically, I'm asking if anyone knows why you would want it on the controller.

Astronouth7303 14-04-2004 18:21

Atan Function
 
Here is my Arc Tangent code:
Code:

#define ATAN_COUNT 64
char rom ATAN_ARRAY[64] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16,
17, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 32, 34,
36, 37, 39, 41, 43, 46, 48, 50, 53, 56, 59, 62, 66,
69, 74, 78, 83, 88, 95, 101, 109, 118, 128, 140, 154,
171, 192, 218, 253, 299, 367, 473, 663, 1106, 3319};

char atan (char Num)
{
        char Index = 0;
        char Value = 0;
        char IsDone = 0;
       
        LOOP:
                if (ATAN_ARRAY[Index] > Num)
                        Value--;
                if (ATAN_ARRAY[Index] >= Num)
                        IsDone = 255;
                else if (Index >= ATAN_COUNT - 1) //was ATAN_COUNT + 1
                {
                        IsDone = 255;
                        Value = 64;
                }
               
                if (IsDone)
                        goto LOOP_DONE;
                else
                { Value++; Index++; }
                goto LOOP;
        LOOP_DONE:
       
        return Value;
}

The lookup table is compressed. If I were to use a regular variety than it would be 3320 elements long! Instead, I put the location of the element that the value changes. That's why I loop. I think this will work, but I'm not sure.

[edit]that chould be ATAN_COUNT - 1 not ATAN_COUNT + 1 at line 19[/edit]

scottm87 19-04-2004 21:58

Re: Angle from X,Y
 
hmmm you can also use vectors, and find the angle with the formula (u * v)/(|u||v|) (the dot product of u and v divided by the product of the magnitudes). This is useful if you are already using vectors, which are probably better suited for motion and such anyways.

dtk 19-04-2004 22:08

Re: Angle from X,Y
 
Quote:

Originally Posted by scottm87
hmmm you can also use vectors, and find the angle with the formula (u * v)/(|u||v|) (the dot product of u and v divided by the product of the magnitudes). This is useful if you are already using vectors, which are probably better suited for motion and such anyways.


The result of that equation gives you the cos of the angle between the vectors. That is cos(x). You would still need to use an inverse trig function to find the angle (x).

I'm going to have to go ahead and give you -15 points for that one. o_O

-Daniel


All times are GMT -5. The time now is 13:43.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi