Convert analogue nub X,Y to angle?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Convert analogue nub X,Y to angle?

Post by Art »

Hi Guys,
About a year ago I found code to output an angle in degrees
from the analogue controller input, and now can't seem to find it when I'd like to use it.

Anyone know where this is? It may not have been on this forum...
Cheers, Art.
If not actually, then potentially.
cheriff
Regular
Posts: 258
Joined: Wed Jun 23, 2004 5:35 pm
Location: Sydney.au

Post by cheriff »

May not be what you saw before, but if I cast my mind way back and remember a little trig, and assuming (0,0) is when the nub is centered:

Code: Select all

import math
def foo(x,y):
    rad = math.atan(y/x)
    degrees = rad * (360 / (2*math.pi))
    magnitude = math.sqrt(x*x + y*y)

    #fixup for 2nd, 3rd and 4th quadrants
    if &#40;x<0&#41; and &#40;y<0&#41;&#58;
        degrees = degrees + 180
    elif &#40;x<0&#41;&#58;
        degrees = degrees + 180
    elif &#40;y<0&#41;&#58;
        degrees +=360

    return &#40;magnitude, degrees&#41;
I used python since its easier to tweak as I was getting it right, but should be fairly simple to derive a C version.

I *think* it's right .. seems OK for the handful of values I tested. If you want the value in [-180,180) rather that [0,360) you can tweak the fixups as needed.

Someone may have a nicer way, however :)
Damn, I need a decent signature!
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

Thanks, I will give it a shot :)
I'm after 360 degree circle yes.
If not actually, then potentially.
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

I tried this, point the stick straight up, and it does output zero.
as I turn the nub clockwise, the degrees var goes up to about 90 degrees, but by that time, the output should be about 260 degrees.
It also crashes if it gets to just under 90 degrees.
by this time the nub is almost pointing left

Code: Select all

		sceCtrlSetSamplingMode&#40;1&#41;; 
		sceCtrlPeekBufferPositive&#40;&pad, 1&#41;;

	yyy = pad.Ly;
	xxx = pad.Lx;

   	rad = atan&#40;yyy/xxx&#41;;
    	degrees = rad * &#40;360 / &#40;2*3.141592&#41;&#41;;


    if &#40;xxx<0 && yyy<0&#41; &#123;
        degrees = degrees + 180;
   &#125; else if &#40;xxx<0&#41; &#123;
        degrees = degrees + 180;
   &#125; else if &#40;yyy<0&#41; &#123;
        degrees +=360;
	&#125;
If not actually, then potentially.
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

This is gonna crash if xxx is 0. Why not use atan2?

Jim
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

Code: Select all

         sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
         xxx= pad.Lx - 130;
         yyy= pad.Ly - 130;
         rotation = atan2 &#40;xxx,yyy&#41; / &#40;3.141592/180&#41;;
I've tried this one, but it crashes instantly.

EDIT.. no it works ;)

I just forgot
sceCtrlSetSamplingMode(1);
sceCtrlPeekBufferPositive(&pad, 1);
If not actually, then potentially.
cheriff
Regular
Posts: 258
Joined: Wed Jun 23, 2004 5:35 pm
Location: Sydney.au

Post by cheriff »

Jim wrote:This is gonna crash if xxx is 0. Why not use atan2?

Jim
Nice, I didnt know about atan2. you learn something new every day Thanks!
Damn, I need a decent signature!
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

The one I posted outputs with the y axis upside down.
Here's one I corrected.. probably a sloppy way to fix:

Code: Select all


float rotation;
float precalc;
precalc = 3.141592/180;
SceCtrlData pad;

			sceCtrlSetSamplingMode&#40;1&#41;;
			sceCtrlPeekBufferPositive&#40;&pad, 1&#41;; 

			jxxx= pad.Lx - 130;
			jyyy= pad.Ly - 130;
			if &#40;jyyy<0&#41; &#123;jyyy = fabs&#40;jyyy&#41;;&#125; else &#123;jyyy = 0 - jyyy;&#125;

			rotation = atan2 &#40;jxxx,jyyy&#41; / &#40;precalc&#41;;
			if &#40;rotation<0&#41; &#123;rotation = 360 - fabs&#40;rotation&#41;;&#125;
Art.
If not actually, then potentially.
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

Code: Select all

         jyyy= pad.Ly - 130; 
         if &#40;jyyy<0&#41; &#123;jyyy = fabs&#40;jyyy&#41;;&#125; else &#123;jyyy = 0 - jyyy;&#125; 
Instead of this, write

Code: Select all

         jyyy = 130-pad.Ly;
Jim
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

The PSP stick goes from 0 to 255, with the "center" being (theoretically) 128. So 128,128 is the nominal center when the stick isn't being pushed. This varies GREATLY by the PSP and how old it is and how much the user has used the stick. I've found a slop of plus or minus 32 is barely enough to cover the majority of PSPs. So you should really only respond to the stick if it's less than 96 or greater than 160.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

I could give you something for this, but its considerably larger than what you're doing above. I don't really know how to simplify analytical geometrical calculations other than following the procedure to find the angle between the lines (128,128),(128,0) and (128,128),(analog value). Then adjust it for the 4 quadrants.
Post Reply