heisenbergman


« on: June 08, 2013, 08:38:25 PM » 

What I mean is for a coordinate system below for example: Is there already a known system to convert: 0 degrees = (1,0) 90 degrees = (0,1) 180 degrees = (1,0) 270 degrees = (0,1) and will be able to convert all degrees in between? Thanks!



Logged




zacaj


« Reply #1 on: June 08, 2013, 08:49:48 PM » 

x=cos(a) y=sin(a)



Logged

My twitter: @zacaj_Well let's just take a look at this "getting started" page and see Download and install cmake
Noooooooo



Xishem


« Reply #2 on: June 08, 2013, 08:51:05 PM » 




Logged




heisenbergman


« Reply #3 on: June 08, 2013, 09:00:27 PM » 

holy trigonometry. I knew I should have paid more attention in trig class. Thanks.



Logged




John Sandoval


« Reply #4 on: June 08, 2013, 09:01:07 PM » 

note that a is probably going to need to be in radians



Logged




ஒழுக்கின்மை


« Reply #5 on: June 08, 2013, 09:25:07 PM » 

note that a is probably going to need to be in radians
yep; to convert from degrees to radians do this: cos(degrees*pi/180)*distance  this will convert degrees to change of x sin(degrees*pi/180)*distance  this will convert degrees to change of y in other words, let's say you wanted to move an object 17 pixels in a direction of 257 degrees what you'd do is x += cos(257*pi/180)*17; y += sin(257*pi/180)*17; if you're using game maker, this is equivalent to lengthdir_x() and lengthdir_y()



Logged




heisenbergman


« Reply #6 on: June 08, 2013, 09:30:24 PM » 

^ Yup, thanks for the additional info John and Paul! I ended up figuring that out when my 4bullet shot ended up shooting in weird angles instead of from the top, bottom, left & right like I expected :p Luckily Java has handy functions for converting degrees to radians and vice versa Things work the way I expect it to now.



Logged




Dacke


« Reply #7 on: June 09, 2013, 08:50:20 AM » 

You may want to take the chance to learn how to work in radians instead of degrees It's especially easy if you realize that π (pi) is wrong and start using τ (tau) instead: http://tauday.com/90° is a quarter of a circle > τ/4 radians.180° is a half of a circle > τ/2 radians270° is 3/4 of a circle > τ*3/4 radians



Logged




Oskuro


« Reply #8 on: June 09, 2013, 10:27:27 AM » 

Very typical java optimization technique (of evil!): private static final double[] sin_table, cos_table;
static { sin_table = new double[360]; cos_table = new double[360];
for(int i = 0; i < 360; i++) { sin_table[i] = Math.sin((double)i); cos_table[i] = Math.cos((double)i); }
}
public static double fast_sine(double angle) { //TODO: Filter value to account for negative angles, or angles larger than 360 return sin_table[(int)angle]; }
public static double fast_cosine(double angle) { //TODO: Filter value to account for negative angles, or angles larger than 360 return cos_table[(int)angle]; }
Of course, you lose precision, and it can be tweaked, but if you're using a limited number of valid angles in your game, you can get away with the precision loss and speed up things a lot.



Logged




Schrompf


« Reply #9 on: June 09, 2013, 10:30:09 AM » 

Have you profiled it? This is a rhetorical question because I know you haven't. Otherwise you wouldn't say that.



Logged

Let's Splatter it and then see if it still moves.



Kekskiller
Guest


« Reply #10 on: June 09, 2013, 11:28:25 AM » 

I don't think that any function utilizing more than a single java bytecode/whatever instruction is going to be faster than an sin/cos instruction you can get via asm these days. Plus I'd assume that java's math calls are optimized to this level. Unless of course I'm again trying to find something in java it never had.



Logged




JakobProgsch


« Reply #11 on: June 09, 2013, 12:14:22 PM » 

Look up tables are somewhat of a misguided optimization. Unless you can guarantee they stay in cache (and if you want to spare the cache for that purpose) the cost of a memory access is most likely significantly more expensive than just computing sin/cos.



Logged




Oskuro


« Reply #12 on: June 09, 2013, 02:13:13 PM » 

Hence why they are static (initialized and kept in memory at class load). Also, as far as I know, directly accessing a an array index is considerably faster (around 50x) than calling Math.cos/Math.sin, but it is true, I haven't profiled it (yet), I'm basing it off of the advice of people more experienced than me.As for memory footprint, it all depends on how it is used. Say a game only needs to care for angles in 45º increments, that's 8 possible angles that will take a small amount of memory (essentially two size 8 arrays).



Logged




ஒழுக்கின்மை


« Reply #13 on: June 09, 2013, 04:20:29 PM » 

this sounds specific to java tho; in, say, GML the lookup table might be slower



Logged




ham and brie


« Reply #14 on: June 09, 2013, 04:23:21 PM » 

Also, as far as I know, directly accessing a an array index is considerably faster (around 50x) than calling Math.cos/Math.sin, but it is true, I haven't profiled it (yet),
If you do profile it, do it with real game code, not a simple test program that just does something like time how long doing many lookups in a row takes. The problem with the simple method is that it would be much faster than the real code, because it won't have the cache misses that make the lookup tables slow.



Logged




heisenbergman


« Reply #15 on: June 09, 2013, 06:23:39 PM » 

Very typical java optimization technique (of evil!): private static final double[] sin_table, cos_table;
static { sin_table = new double[360]; cos_table = new double[360];
for(int i = 0; i < 360; i++) { sin_table[i] = Math.sin((double)i); cos_table[i] = Math.cos((double)i); }
}
public static double fast_sine(double angle) { //TODO: Filter value to account for negative angles, or angles larger than 360 return sin_table[(int)angle]; }
public static double fast_cosine(double angle) { //TODO: Filter value to account for negative angles, or angles larger than 360 return cos_table[(int)angle]; }
Of course, you lose precision, and it can be tweaked, but if you're using a limited number of valid angles in your game, you can get away with the precision loss and speed up things a lot. Thanks for the suggestion. Doing this didn't occur to me since Math.sin() and Math.cos() are quite straightforward. Off the top of my head, accessing from array would seem faster, but I don't think that using either method would be a critical performance gain/loss unless one's game is heavily reliant on it. Still, nice to know of an alternative like this.



Logged




Schrompf


« Reply #16 on: June 10, 2013, 12:04:59 AM » 

It is NOT an alternative. Just forget about it, ok?
Reasoning: If you use sin/cos like this in normal code, the first level cache is usually filled with the current data. A tablebased approach would require parts of the table to be loaded to first level cache, and would flush other data from there. But the table needs to be in L1 cache to be efficient, even a L2 access would already take longer than the basic math to calculate a sin/cos. It's just a few multiplications and additions after all. Look up taylor series if you want to see how few operations exactly. And all of those happen in registers without memory access, some parts even parallelized by the CPU's OOO pipeline.
If you use a table, at least map cos to sin to cut half of the table. After all it's just a phase shift, and you need to wrap around the input value anyways.
But you're right: it won't make a difference in almost any code you'll ever write. That's why my original suggestion still holds: first measure (as in: profile) then optimize.



Logged

Let's Splatter it and then see if it still moves.



heisenbergman


« Reply #17 on: June 10, 2013, 12:21:39 AM » 

^ Hey, no need to be so dismissive of his suggestion If you visited the link that Oskuro provided, no less than the administrator of JavaGaming.org and the creator of LibGDX (one of the more popular Java game development frameworks today) seem to subscribe to this approach that Oskuro suggested. At the very least, it's worth some consideration.



Logged




Schrompf


« Reply #18 on: June 10, 2013, 12:28:33 AM » 

Feel free to profile it and see for yourself. There are situations where a table might yield better performance  for example, if you're crunching through a large array of unrelated data. Then the cache usage is irrelevant because all other data is touched exactly once. But I assume this to be a rare case. In the "normal" case with complex logic and data from everywhere involved, you'd lose with a table.
I personally don't give a fuck who's an administrator and where. That just means they manage a forum. What I see here is deprecated wisdom. Ten years ago a table might have saved the day. Today's CPUs are far more complex and incredibly more smart, and the burden has shifted heavily towards memory access.



Logged

Let's Splatter it and then see if it still moves.



Kekskiller
Guest


« Reply #19 on: June 10, 2013, 12:30:15 AM » 

It would definitely make sense if it's a more complex formula. But then you're getting close to why memoization is so rarely used: formulas are often not complex enough tobe worth it. Not to mention the array one would need for all the parameters.



Logged




