#40635 - Pacifist - Thu Apr 21, 2005 1:41 am
Has anyone got a demo that uses rotating sprites succesfully?
I'm having a hell of a time getting rotation to work properly with the dualis emulator.
even the identity matrix
10
01
which, as I understand it, should make things appear unchanged just expands one pixel to fill the whole sprite.
I've gotten some rotation to happen by using 1<<8 as a scaling factor but it ends up missmatched, eg: 360 degrees rotates the sprite about 200 degrees.
Is anyone else havinga problem with this?
#40701 - Pacifist - Thu Apr 21, 2005 6:06 pm
OK I guess I'm just an idiot but I never got this working properly.
Whatever I did I always ended up with an input angle of 128 being equivelant to 90 degrees of rotation.
I ended up rotating through 90 degrees and then flipping the sprite to the quadrant it's supposed to be in.
So anyway if anyone else has this problem and needs a workaround I can give it to them.
#40720 - ector - Thu Apr 21, 2005 9:23 pm
What does your sine and cosine tables look like?
#40781 - Pacifist - Fri Apr 22, 2005 4:33 pm
I'm using the ones in ndslib.
It does seem as though I misunderstand them somehow.
It turns out to be a mutte point for me. I don't really want to rotate based on an angle but on a vector, which I have working fine.
#40786 - ampz - Fri Apr 22, 2005 4:50 pm
Pacifist wrote: |
Whatever I did I always ended up with an input angle of 128 being equivelant to 90 degrees of rotation. |
Are you sure it is not supposed to work that way?
Using 256 (or 512) rather than 360 degrees makes alot of sense.
#40788 - Pacifist - Fri Apr 22, 2005 5:28 pm
perhapse.
I've been having alot of problems with the ndslib floating point functions. Like not being able to take the sqare root of a fixed point number larger than about 200.
I'm just chalking it up to my own inexperience with floating point math.
#40844 - Sebbo - Sat Apr 23, 2005 4:05 am
instead of using the square root function, mayb try x^(1/2)...stupid algebra
#40858 - tepples - Sat Apr 23, 2005 5:14 am
Exponentiation takes even longer than a square root.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#40860 - Cleon I - Sat Apr 23, 2005 5:17 am
I assume you mean fixed point instead of floating point for all the instances in your post. Floating point is very slow on the DS because there's no dedicated hardware for it, which is why fixed point is used. But, you probably already knew that.
First, if you don't know much about fixed point math, I suggest you go find a tutorial somewhere, since the rest of this won't make much sense otherwise.
Just taking a look at the fixed point math functions in math.h, it seems that the way it works is by using the DS's internal integer sqrt hardware. However, since the DS is expecting integers, and we're working in 1.19.12 fixed point, we have to multiply by 2^12 before taking the square root so that the decimals will work out right. The easiest way to do this is the left-shift 12 places, which essentially wipes out all but the top 8 bits of the integer-part of our number.
Example:
If we wanted to find sqrt(1234.567), we would start with:
1234.567 = + 0000000010011010010 . 100100010010 (in 1.19.12 fixed point)
Then left-shift by 12 to get:
11010010 . 100100010010000000000000 = about 210.56689 (in 8.24 fixed point)
Since this still has to fit in 32-bits, we can't keep it all so we lose some of the high bits. We also lost the sign bit, but you shouldn't be taking the sqrt of a negative number anyway, so this doesn't matter.
Now, when we plug this number into the DS's sqrt hardware, it interprets it as the integer:
11010010100100010010000000000000 = 3532726272
It then takes the square root of that integer, which turns out to be about:
00000000000000001110100000101100 = 59436
Now, if we interpret this as a 1.19.12 fixed point number, this should be our answer:
+ 0000000000000001110 . 100000101100 = 14.51074
Oops, that's not right. However, it would have been right had our number been 210.56689. Since the integer-part only gets 8 bits in the shifted number, this means you shouldn't try to take the sqare root of numbers larger than 256.
The "fix" for this is to change your fixed point format so more bits are allocated to the integer-part and fewer are in the fraction-part. That way, you don't have to shift as much before you take the sqrt, and thus lose fewer bits from the integer-part. Or, just scale everything down so nothing ever gets bigger than 256. Another option is to write your own sqrt function that preserves the upper bits (slow) or use a sqrt approximation (not as precise). Depending on your application, one of these options might be the way to go.
(Btw, all calculations were done in the Windows Calculator)
#40863 - tepples - Sat Apr 23, 2005 5:27 am
Doesn't the ARM9 have an instruction to quickly count leading zeroes? I'd suggest 1. count leading zeroes, 2. shift left, 3. square root, and 4. shift right.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#40870 - Pacifist - Sat Apr 23, 2005 6:53 am
Yes I did mean *fixed* point.
In fact since I originally wanted sqrt to find the magnatude of a vector I ended up scaling the components of the vector into something the 1.19.12 functions could handle.
Although I like the idea of decreasing the accuracy. I don't know why I didn't think of that.
#40884 - ampz - Sat Apr 23, 2005 9:20 am
tepples wrote: |
Doesn't the ARM9 have an instruction to quickly count leading zeroes? I'd suggest 1. count leading zeroes, 2. shift left, 3. square root, and 4. shift right. |
Usually you know the range of the value, so you can just use another fixed point format that suits your needs better than 1.19.12.
#40885 - Cleon I - Sat Apr 23, 2005 9:26 am
Pacifist wrote: |
I ended up scaling the components of the vector into something the 1.19.12 functions could handle. |
Glad to see you've fixed that point of error. ;)