Sin/Cos Lookup Tables

Blitz3D Forums/Blitz3D Programming/Sin/Cos Lookup Tables

Apocalypse(Posted 2004) [#1]
Are Blitz3D's math functions already optimized with lookup tables or does it force an actual calculation each time the functions are called?


BlitzSupport(Posted 2004) [#2]
A calculation...


Bot Builder(Posted 2004) [#3]
If ALL the lookup tables were stored in ram, people would need way more than they should. so - no. And anyway, the calculations are pretty fast.


BlitzSupport(Posted 2004) [#4]
The calculations are *trivially* fast... :)


Richard Betson(Posted 2004) [#5]
I use look-ups all the time for real-time FX. If your sin/cos or other math is complex then look-up tables are the way to go!

We had this discussion some time ago and look-up's kicked ass. :)

L8r,


Richard Betson(Posted 2004) [#6]
In fact here is a test app to show the difference:

No Look-Up: 1187 mils
WITH Look-Up: 39 mils :)

;By Richard Betson
Graphics 640,480,16,2

;x and y precalc array
Dim look_up_x(800,600)
Dim look_up_y(800,600)

;make look_up table
look_up()



;Calc each part of the example math NOT USING A LOOK UP
calc_time=MilliSecs()
Calc_No_Look_up()
total_calc_millisecs=MilliSecs()-calc_time


;Calc each part of the example math WITH A LOOK UP
look_up_time=MilliSecs()
For x=1 To 800
	For y=1 To 600
	x1=look_up_x(x,y)
	y1=look_up_y(x,y)
	Next
Next
total_look_up_millisecs=MilliSecs()-look_up_time



Color 255,128,255

While Not KeyHit(1)

Text 10,60,"Here are the results:"
Text 10,80,"Total Time in Millisecs it took to calc example math NOT USING a LOOK-UP"
Text 10,100,"Calc No Look_up Time:"+total_calc_millisecs
Text 10,120,"Total Time in Millisecs it took to calc example math WITH a LOOK-UP"
Text 10,140,"Look_up Time :"+total_look_up_millisecs

Text 10,180,"Hit Escape to exit"
Wend
End


Function Calc_No_Look_up()
For x=1 To 800
	For y=1 To 600

		rad#=Abs((x-ttx)*(x-ttx))+Abs((y-tty)*(y-tty))
		If rad>0
			rad= Sqr(rad)
		Else
			rad=0
		EndIf
		If rad=0 Then rad=1
		dx#=((x-ttx)/rad)
		dy#=((y-tty)/rad)
		rad=((1/Cos((rad)/ttx*2))+(rad+2))
		x1=Int(dx*rad)+ttx
		y1=Int((dy#)*rad)+tty

	Next
Next

End Function


Function look_up() ; Makes a look-up table that hold the x and y data precalced
For x=1 To 800
	For y=1 To 600
	
	;This is just an example calc. Something I have used befor like this
		rad#=Abs((x-ttx)*(x-ttx))+Abs((y-tty)*(y-tty))
		If rad>0
			rad= Sqr(rad)
		Else
			rad=0
		EndIf
		If rad=0 Then rad=1
		dx#=((x-ttx)/rad)
		dy#=((y-tty)/rad)
		rad=((1/Cos((rad)/ttx*2))+(rad+2))
		x1=Int(dx*rad)+ttx
		y1=Int((dy#)*rad)+tty

	If x1>=tw-1 Then x1=tw-1
	If y1>=th-1 Then y1=th-1
	If x1<=1 Then x1=1
	If y1<=1 Then y1=1
	
	;Save this data (map x and y pos. precalced)
	look_up_x(x,y)=x1
	look_up_y(x,y)=y1
	
	Next
Next

End Function



Apocalypse(Posted 2004) [#7]
It's nice to see people who still appreciate the time saving lessons of old when CPU power was at a premium. It's these types of time saving measures that really allow highly detailed games to be done without lossing frame rate.

It may take almost not time to calculate one COS(23) but when you need to run it 10,000 times that starts to add up. By pre-computing a lookup table, the time is actually the cost of reading a memory location (1 cycle).

Thanks Richard.


slenkar(Posted 2004) [#8]
I got 9 seconds without

2 seconds with tables


Bot Builder(Posted 2004) [#9]
I'm not saying it's not worth doing - just that blitz shouldn't precalc it. It's even better if you can have lookup tables for whole equations.


wedoe(Posted 2004) [#10]
It's nice to see people who still appreciate the time saving lessons of old when CPU power was at a premium.
Oldtimers (when it comes to programming) like myself do this on a spinal reflex.


Richard Betson(Posted 2004) [#11]
Lol @wedoe...

Not many of us left. :)

L8r,


Bot Builder(Posted 2004) [#12]
I'm not an oldtimer- but I started on the atari and went on up to a 300mhz compie with QB. -that's gotta count for somthing :)


sswift(Posted 2004) [#13]
I get no look up: 64
Look up: 53

Your 900mhz Celeron is to blame. I have a 2400+ AMD.

As you can see, with a modern CPU, the difference is trivial because accessing ram takes almost as long as just doing the calculations. I wouldn't be at all surprised to find out that a 3ghz system did the calculations faster than the lookup.


Shambler(Posted 2004) [#14]
I get 54 / 20 with a 2700+ AMD thats almost 3* faster.


Barnabius(Posted 2004) [#15]
2018 ms with no look-up
16 ms with look-up

P4, 2400 MHz

sswift is right about accessing the ram being rather slow compared to modern FPU in a typica CPU but let's not forget that small look-up table can easily end up completely inside the L2 cache and we all know how fast accessing the L2 cache is. Looks like the "old way" of doing it wins again, even with ultra modern hardware. :)

Barney (started assembly programming on KIM-1)


Floyd(Posted 2004) [#16]

2018 ms with no look-up , P4 2400 MHz

There's something seriously wrong with that. I get 140 ms with a 1000MHz Athlon.


sswift(Posted 2004) [#17]
Yeah I bet banabius is running with debug on.


"I get 54 / 20 with a 2700+ AMD thats almost 3* faster."

So?

He's doing the calculation 480,000 times. In what realistic situation, other than a full screen polar distortion function like I put in my little pong game, would you possibly want to call sin or cos 480,000 times a frame? I can't think of any.

That's what Blitzsupport meant when he said it was "trivially" fast. It's not worth optimizing in 99% of situations where you'd use sin or cos, cause you'll never notice a difference. :-)


Warren(Posted 2004) [#18]
I'm an old timer and I see almost no benefit to obfuscating my code with look up tables. Yes, they are faster in pathological test cases but in real life situations? Hardly.


BlitzSupport(Posted 2004) [#19]
Yeah, I should point out that I post my drivel with real-world game situations in mind, not pointless theoretical benchmarks!


Richard Betson(Posted 2004) [#20]
These would be impossible in "real-time" with out look-up's:

http://www.blitzbasic.com/Community/posts.php?topic=29481

http://www.blitzbasic.com/Community/posts.php?topic=19509

http://blitz.idigicon.com/project_detailb.asp?ProjectName=Water%20FX%20-%20Real%20Time


some more examples I use look-up's in:


http://www.blitzbasic.com/Community/posts.php?topic=27171

http://www.blitzbasic.com/Community/posts.php?topic=29496


Look-up's are the easyest way to improve any complex real-time FX. I use them all the time! Try this example with out look-up's. :)


;The Perfect Sign - Copyright 2003, Richard R Betson
;vidiot@... -- www.redeyeware.50megs.com
;Speed with lookups! Use at your own risk. All rights reserved.



Graphics 800,600,16
stp=45
Dim mb#(201,201,stp+1,2)

Text 300,290,"Making look-up's"

SetBuffer BackBuffer()



timer=CreateTimer(75)

lu(stp)
cr1=MilliSecs()+10000
cr2=MilliSecs()+20000
cr3=MilliSecs()+30000


While Not KeyHit(1)

LockBuffer BackBuffer()

For y=0 To 200
	For x=0 To 200

	clr=((225-(y/2)) Shl 8 Or (146+(y/4)) Or  (155+(x/2)) Shl 16 )
	
	a#=mb#(x,y,ii,0)
	b#=mb#(x,y,ii,1)

	If a>1 And a<799 And b>-299 And b<399
		WritePixelFast a+110,b+240,clr
	EndIf

	Next
Next
UnlockBuffer BackBuffer

	fps=fps+1
	If fps_t<MilliSecs()
	fp$=" "+Str$(fps)
	fps_t=1000+MilliSecs()
	fps=0
	EndIf
	Color 255,0,0
	Text 10,10,"The Perfect Sign -  Richard R Betson"
	
	
	
	;Text 10,35,"FPS: "+fp$



If KeyDown(68)=1
	SaveBuffer(BackBuffer(),"screen.bmp")
EndIf

WaitTimer(timer)

Flip False
Cls
ii=ii+1
If ii>stp Then ii=0
Wend


End



Function LU(stp)


For i=0 To stp

.jmp

If t<MilliSecs()
t=MilliSecs()+50
mt#=(MilliSecs()/8)*1.2


For y=0 To 200
	For x=0 To 200
		rad#=Abs(((x-100))*(x-100))+Abs((y-100)*(y-100))

		If rad>0
			rad= Sqr(rad)
		Else
			rad=0
		EndIf

		a#=(x*2)+(Sin((y-100-mt))/y) + y-(Cos(y-100-mt)/y)
		b#=(y)-100-(Sin((rad*20)-(mt))*(rad/5.9)) + y/2-(Cos((rad*34)-(mt))/(rad/40))
		mb#(x,y,i,0)=a#
		mb#(x,y,i,1)=b#
	Next
Next
Else
Goto jmp
EndIf

Next

End Function



L8r,


Micha(Posted 2004) [#21]
Interesting to see how the debug mode slows things.

Debug mode off :
No Look-Up: 1595 mils
WITH Look-Up: 11 mils :)

Debug mode on :
No Look-Up: 1802 mils
WITH Look-Up: 85 mils

System :
P4 3 Ghz, 512 MB Ram
Ati 9800 pro
Win XP


BlitzSupport(Posted 2004) [#22]
Yeah, those are good demonstrations, but again not really representative of real-world game situations. Of course look-ups have their place (eg. cool little graphics demos like these that need to use the Sin/Cos commands 1000s of times per loop). The original poster didn't specify his requirements, though -- you'd very rarely use Sin/Cos that much in an actual game.


Ice9(Posted 2004) [#23]
That code isn't doing a lookup in a sin table it's doing a lookup for an equation. Sin lookup tables are pointless.

I get 1226 no lookup and 1252 on lookups

Since you are usually doing angles with sin this is
tested with a double precision angle. I added the
text string because both would fluctuate with less
than a millisecond of time 0,1 0,0 1,0 and so on.
Graphics 640,480,16,2

;x and y precalc array
Dim look_up_x#(36000)

;make look_up table
look_up()



;Calc each part of the example math NOT USING A LOOK UP
theta#=0
calc_time=MilliSecs()
	For x=1 To 36000
		theta#=theta#+0.01
		rad#= Sqr(theta#)
		Text 0,0,rad#
	Next
total_calc_millisecs=MilliSecs()-calc_time


;Calc each part of the example math WITH A LOOK UP
look_up_time=MilliSecs()
For x=1 To 36000
	rad#=look_up_x(x)
	Text 0,0,rad#
Next
total_look_up_millisecs=MilliSecs()-look_up_time



Color 255,128,255

While Not KeyHit(1)

Text 10,60,"Here are the results:"
Text 10,80,"Total Time in Millisecs it took to calc example math NOT USING a LOOK-UP"
Text 10,100,"Calc No Look_up Time:"+total_calc_millisecs
Text 10,120,"Total Time in Millisecs it took to calc example math WITH a LOOK-UP"
Text 10,140,"Look_up Time :"+total_look_up_millisecs

Text 10,180,"Hit Escape to exit"
Wend
End



Function look_up() ; Makes a look-up table that hold the x and y data precalced
For x=1 To 36000
	theta#=theta#+0.01	
	look_up_x(x)= Sqr(theta#)	
Next

End Function



wedoe(Posted 2004) [#24]
Hello !!!!

Is this turning into a religion ? What is this ?
Seems to me some people here want the raving lunatics that want
to spare a few cycles of CPU time to change their mind at any cost !

I know one doesn't have much use for this in most situations nowdays,
but it can never be wrong to make your program faster, no matter how little.

I always spare cycles if I can, so shoot me !


Warren(Posted 2004) [#25]
but it can never be wrong to make your program faster, no matter how little.

Well, actually, in a professional situation - it can be. Optimizing code needlessly is the quickest way to get your fellow programmers to hate you.


wedoe(Posted 2004) [#26]
That can only be true if you work with people that are not very professional.


Warren(Posted 2004) [#27]
No.

OK, so, you optimize a piece of code that doesn't need it. Let's say that code develops a problem that someone needs to go in and fix. Because of your optimizations, the code is now harder to read and the bug takes longer to fix thus costing the team time and money. Time and money that was essentially tossed into a bucket and burned because someone decided to optimize a piece of code that didn't need it.

Now ... who's the unprofessional one in this situation? The optimizer who believed that optimization is never the wrong choice.


Ice9(Posted 2004) [#28]
But sin/cos tables aren't optimizations. You're going to
see equal amounts of time using lookups as you are if you don't when you're finding a vanilla sin or cos.
Equation tables are a great optimization and are very useful. Richard Betsons example is a great example of its use.

One way I optimize for effects is to calculate one sin each loop and store an offset for a bobing rotating effect in some of my pickup items. I store the ofset in the type of the foo. This saves me a sin calc or a lookup for each and replaces them with a simple addition.


AbbaRue(Posted 2004) [#29]
On that first example I get 1693 without lookup, and 11 with lookup table.

On this note, the usual situation were I use lookup tables is when I can't find a simple formula to get the numbers I need.
Or when I only need a small number of answers. And am going to use those same answers over and over again.
Eg. I was designing a game that only allowed 16 different positions to turn 360 deg. So as to allow for less calculations.
In this case a lookup table of 16 values would be quite efficient.
If you have dozens of entities in a world, that are moving around, only allowing 16 directions for them to face, makes for a lot less calculations.
Just calculate the directions once and store them in a lookup table.
All things have a place under the right circumstances.
Also, todays cpu's have built in functions that run very fast. Many people don't know this but most computers on the market have a buss speed of less then 200 Mhz.
So even though the cpu is running at 3 GHz, they read and write to memory at less then 200 MHz. And the fastest computer on the common market today has a buss speed of 800 MHz.
That means that the fastest you can read and write memory is at 800 MHz. So if you can use internal cpu math funcions to calculate, that could be much faster then accessing memory in a lookup table.
Definitly if your formula is in cpu cash while calculating.


Bot Builder(Posted 2004) [#30]
also, generally lookup tables are easy to read. trig tables can be sin_, tan_ and atan_.

I think optimisations are good if you are optimising a frequently called function. or even an unfrequently called one. If it's a team project, why not write some comments that tell how the optimisation works?


Warren(Posted 2004) [#31]
Eh, the message is getting lost in semantics - as always.

The point is : don't optimize unless you need to. Measure twice, cut once.


Bot Builder(Posted 2004) [#32]
depends on your definition of needing.

For instance, runing on a crappy computer would 'need' more optimisations. A great compie would 'need' less optimisations. So it depends on how many users you want to lose.


wedoe(Posted 2004) [#33]
Now ... who's the unprofessional one in this situation?
I guess we both are, if you also have made money out of programming.
But there is no reason you shouldn't comment your code is it ?
If the other programmers you refer to is equally professional they
would always optimize code also, this way all the programmers think
alike and the source is no sweat to read at all.

But I do get your point, no problem there, I just disagree.

On top of that I have a problem making "bad" code, it kind
of physically hurts inside to see my name on a routine that
IMO is not as good as it should be. Vanity I guess.

On the other side, I have never programmed in a company with more than
just a handful of programmers and we almost never looked into the others code.

Than again I see your point of view as a source to make bloatware
and if there is something I really really have a problem with, it's bloatware.


Warren(Posted 2004) [#34]
Than again I see your point of view as a source to make bloatware
and if there is something I really really have a problem with, it's bloatware.

I'm advocating bloatware?! You're completely missing my point.

Moving on...


John Pickford(Posted 2004) [#35]
Epicboy is 100% correct here. Code optimisation should only be done when necessary and then as a last resort. I'm an old school coder from the speccy days and I'm well accustomed to very low level optimisation.

I also know the value of clear, readable, updatable code. Optimisation ALWAYS have a detrimental effect on the code in some way. Usually it makes the code far less general purpose, capitalising on the current specific use.

My philosphy is to optimise the algorithm not the code. If something is slow, there's usually a more efficient approach which will gain you far more speed than tweaking code.

Mr Betsons example is misleading, it shows good use of a look-up table (and nobody is arguing against those) but not of a sin\cos look up table which itself is worthless.


Richard Betson(Posted 2004) [#36]
@weboe


Seems to me some people here want the raving lunatics that want
to spare a few cycles of CPU time to change their mind at any cost !



I should point out that my 900 Celeron is an overclocked 600.. lol

l8r,


wedoe(Posted 2004) [#37]
My philosphy is to optimise the algorithm not the code.
Well put.

If you see my postings above, I have no problem with others
coding by a different mindset than I do, I just don't see
why some religiously try to covert people like me to program
in a way they think is approprate.

@EpicBoy: The bloatware comment were a bit stupid, I'm sorry.
You didn't comment on anything else I wrote tho.

I think someone must put a gun to my head to make me stop
caring about optimizing code, like I said before, it's a spinal reflex :)


Koriolis(Posted 2004) [#38]
A lot of people don's seem to have ever heard the maxim "premature optimisation is the root of all evil", or understood it.
I'm glad though to see Wedoe recognize what EpicBoy didn't advocate against optimization, but against unneeded or premature optization.
In fact Wedoe, I used to have the same "spinal reflexs" as you. I just learned to recognize which of those spinal reflexs are outdated and counterproductive.

And for those that still don't get it, that doesn't mean at all that lookup tables are to be blindly banned, but equally don't use them blindly, do so only where needed (inner loops that must be really fast, and supposing that on the platform you're targetting it's faster enough to be worth it), and when needeed (that is, rarely at the very beginning of your develoment, but most likely as a last optimzation stage).


Richard Betson(Posted 2004) [#39]

I use look-ups all the time for real-time FX. If your sin/cos or other math is complex then look-up tables are the way to go!



I still stand by this. :)

L8r,


Bot Builder(Posted 2004) [#40]
Optimisation doesn't necessarily make your code less readable. in some cases, more readable. For instance, the code optimiser/cleaner I'm working on will give you options whether or not to make optimisations that detrement readability. You may be thinking 'How is it possible to optimize code with a program?' Well, it is admitadly diffucult, however not so hard that it isn't worth a try. Basically, first work out simple stuff like indentation(done), add quote checking(quote lint), add mistyping errors(in the works; to find mistyped variables/functions). Then do stuff like static expression evaluation(done - even though blitz does it for you while compiling), varible modification evaluation, etc. Then do complex stuff like specific optimisations that target various things.

The majorly un-nice to readability would be to make all variables global so that the program doesn't have to recreate them every function call. This would only be recommended before an exe release.


Bocote(Posted 2004) [#41]
Of course it is possible to optimise a program using another program, after all that is what optimising compilers do. One of my compilers makes dramatic differences to code size and execution speed, just by enabling its optimisation. Interestingly butchering code in a vain attempt to make it “optimal” can often make it worse because it gets in the way of the optimiser.

I have seen someone who wrote X + X + X because it was quote – “faster than 3 * X” – he was amazed at just how much slower his “optimised” and less clear equation was.

I say don’t optimise unless you need to and then try to think of a better algorithm don’t go in for coding tricks.


Bocote(Posted 2004) [#42]
Making variables global instead of local can seriously degrade performance. Not sure on Blitz – but on stack frame processors accessing local variables can be done with small and very efficient instructions where as accessing Global variables required length far or indirect instructions.

I reduced the code size of one program from 64K bytes to 41K Bytes and the execution speed more than doubled at the same time. This was done by using more local variables so allowing the compile to use the processors most efficient memory access every time a variable was used instead of using a larger inefficient access to the global memory space. So I improved the structure of the code, made it more readable, reduced it size by 1/3 and more than doubled it execution speed.

So if you want to butcher your code in the name of optimisation think again, I have seen “professional” programmers in dismay after weeks of code butchering in the name of “optimisation” only to find little improvement and sometimes even total disbelief from them when they find their newly “optimised” code runs slower than it did before.


Bot Builder(Posted 2004) [#43]
heh. I always thought globals would run faster !?!?! oh well. good thing I haven't done that yet. I bet X+X is faster than 2*X :P .... Although it has to access the variable twice? hmm. oh well. one thing we know is that * is faster than ^2


Koriolis(Posted 2004) [#44]
one thing we know is that * is faster than ^2
You can't even say that in general (though it may be in blitz). It is equally often said that x*2 is slower than x shl 1. That's not so sure. Why? Because all the optimizations you're planning to do in your program are not new and are the kind of things optimizong compilers can do very easily. Here, a compiler can recognize that "2" is a constant integer expression, and evaluates to 2 (!). Thus it can use a left shift by itself to achieve the same result (I have absolutely no idea if blitz does this, though someone reported it does; it's easy to check, and if it doesn't then you can keep this trick in your bag of useful optimization). This means that with compilers that have even a minimal optimizing phase, you can avoid to manually replace pultiplications by 2 by left shifts yourself (thuse keeping a more understanble and straightforwardcode). In this case, better keep left shifts for operations that conceptually really operate on bits and let the compiler do these optimizations.


John Pickford(Posted 2004) [#45]
The "2" thing is a good example.

In the old days of Z80 I would left shift every time. But nowadays with faster processors I value clearer code and dev time over run time. I stick to x=x*2 in my code. If the compiler catches it and compiles to a left shift then great (Blitz does).


Bocote(Posted 2004) [#46]
I’m not saying local variables are faster than global – just that they often are, so if it matters to you check before assuming you need to use the less desirable global variable in the name of efficiency. Local variables can also all use the same memory locations – very important on processors that have very little memory.

Your assumption that 2 * X is slower than X + X is based on the assumption that a multiply is slower than an add. I don’t know for the Pentium but that is not always the case. In the vast majority of expressions in your program you will never notice the difference anyway.


semar(Posted 2004) [#47]
I would add my advice here, because a sin/cos look-up table solved me a nasty problem.

I coded an asteroids clone. As add-on, I wrote a record and playback system which can record an entire game session, and then playback it automatically (if you are curious, you can download it by following the link in my signature).

The problem was that the session files saved on a pc, given impredictable result on another pc: the astroship hit asteroids, or missed it sometime, so the playback worked only on the pc where it was saved, and this was not exactly what I planned.

I've finally solved that problem, and discovered two important aspects:
1) the imagewidth and imageheight commands, give different values on different pcs - and this was one source of the trouble
2) the sin and cos - used for the astroship's bullets movement - give also different values on different pcs - and this was the second source of imprecision with the bullets.

So my advice is to use look-up table if you need the same precision on different pcs, as well as to use constant values for imagewidth and imageheight.

Sergio.


wedoe(Posted 2004) [#48]
3) If you use sin/cos for absolute placement on the screen you won't have to worry
the pattern by the movement is looking like a spring and the object actually
moves off screen after a while because of the lack of enough numbers after zero in the math.


Beaker(Posted 2004) [#49]
Imagewidth and Imageheight give different results?! You sure? Are you sure you weren't using floats where you should've used Ints? I've never seen that before. If so, thats a nasty bug.


semar(Posted 2004) [#50]
@MasterBeaker,
yes I'm sure, I used integers, and I have reported it in the old-fashioned bug forum...

The difference was about one pixel, but enough to miss (or hit) a sprite...

However, I'm quite convinced that it's more video card related rather than Blitz. Different gfx cards could act in different manner with anti-aliased 2D images.

Sergio.


Beaker(Posted 2004) [#51]
Were you resizing them? What do you mean by anti-aliased?


poopla(Posted 2004) [#52]
He means the edges were all fuzzy. duuuuhhhhh :P.


semar(Posted 2004) [#53]
Were you resizing them?

Nope.

What do you mean by anti-aliased?

An image made with pshoppro, where the image itself is drawn with antialias. So yes, the edges were all fuzzy.

I have to tell, however, that I tried also with 'normal' images - just plan non-antialiased sprites for the asteroids - but get the same error.

Crazy gfx cards !

Sergio.


jhocking(Posted 2004) [#54]
Could you perhaps post an example which demonstrates ImageWidth and ImageHeight reporting different values on different machines? I haven't actually tested it but I find it hard to believe that those commands are variable in the way you describe; they just return the pixel dimensions of an image, and the number of pixels in a given image never change (assuming you never alter the image.)

Oh, and maybe do it in a new thread? This one is getting pretty lengthy and the example would be off-topic.


Koriolis(Posted 2004) [#55]
I hardly believe it too. I'd like to see it, and then we could make a bug report, because there is *absolutely no reason* why it would behave like this.


Beaker(Posted 2004) [#56]
Unless of course its only on one gfx card in the whole world. :)


semar(Posted 2004) [#57]
I did report this issue time ago - I think more than one year - and reported also a snippet to demonstrate it. The thread was opened and discussed on the bugs forum, and I guess that Mark is well aware about it, because he too answered to the thread, like other Blitzers.

Basically, if you want to try by yourself:
- create an image with a paint program - NOT from within the program itself
- load it from within Blitz
- print out ImageWidth and ImageHeight
- compare the values on different pcs.

I've experienced a difference of one pixel between an athlon with nvidia card, and an Intel laptop (don't remember the gfx card now).

Oh, and maybe do it in a new thread? This one is getting pretty lengthy and the example would be off-topic.

@jhocking
sorry for that, I just wanted to spot out another reason to the advantage of using pre-calc values; I didn't want to turn this topic in a bug report, really..

Sergio.


Techlord(Posted 2004) [#58]
;SIN/COS Lookup Table
Dim Sin2#(360)
Dim Cos2#(360)
For loop=0 To 359
	Sin2#(loop)=Sin(loop)
	Cos2#(loop)=Cos(loop)
Next
Use like Blitz Sin/Cos:
y=Sin2#(degrees)*100
Very fast...very harmless.


Ross C(Posted 2004) [#59]
Only problem you have, is where your doing angle calculations in blitz3d. If you put sin(1048), easy. You get the result.

With look-ups, you need to be sure that after every calculation, you wrap the angle wrap around, so it doesn't exceed 359 or go below 0. Which is a pain :)


wedoe(Posted 2004) [#60]
With look-ups, you need to be sure that after every calculation, you wrap the angle wrap around, so it doesn't exceed 359 or go below 0. Which is a pain :)


Mod



Hotcakes(Posted 2004) [#61]
Good answer, perhaps could have given two or three words more info tho <grin>


wedoe(Posted 2004) [#62]
OK

degrees=degrees Mod 360


[edited]

:)


Koriolis(Posted 2004) [#63]
You mean mod 360 I guess?
And using mod on each access of the table defeats the purpose of speed. That's why the usual way of doing it is to have 256 (or 512, or...) values instead of 360 (thus allowing to just shift mask the 'angle', and having everything conforming to that.


wedoe(Posted 2004) [#64]
Yeah, should have been 360 and it was a comment to the use for placing gfx according to precalculated sin/cos, not lookup-tables in general. :)
Using as lookup-table for speed a more computerfriendly number is of coz much quicker.


Apocalypse(Posted 2004) [#65]
I didn't realize this would be such a contentious subject when I asked the question. I did mean using the tables in the situation Frank Taylor described. Interesting thread tho. :-)


John Pickford(Posted 2004) [#66]
The table described isn't very practical, you can only use a whole number for the angle. That would be of little use in any of my projects.

If the angle is a float then there's a lot more complexity in using a look up table, certainly enough to negate the speed increase.

Ultimately Sin\Cos are fast and unlikely to be any kind of bottleneck in your game.

Sure, I could sit an devise a demo in which the speed of Sin\Cos is critical but that proves nothing.


pepsc(Posted 2004) [#67]
hello all what u do is make a table from 0 to 511 then use "and" i would love to see the tables that were in blitz user magazine again "bum" any body got that code


Warren(Posted 2004) [#68]
"Have Fun" doing what? Parsing your post? :)


poopla(Posted 2004) [#69]
Lol. Epicboys hiden rage comes out once more :P.

(just playing)


Techlord(Posted 2004) [#70]
.


Warren(Posted 2004) [#71]
What's hidden about it?


Hotcakes(Posted 2004) [#72]
Yeh man settle down, I'm beginning to suspect maybe FlameDuck has hijacked your handle here <cheeky grin>


Warren(Posted 2004) [#73]
Does a smiley not mean what I think it does? That was a joke. Geez, people...


N(Posted 2004) [#74]
Joke or not, that was a good example of bad typing :P


BlackJumper(Posted 2004) [#75]
2) the sin and cos - used for the astroship's bullets movement - give also different values on different pcs - and this was the second source of imprecision with the bullets.

So my advice is to use look-up table if you need the same precision on different pcs...


Of course the lookup table is generated at startup of the app, so different processors generating different results won't be solved by this ??


semar(Posted 2004) [#76]
Of course the lookup table is generated at startup of the app, so different processors generating different results won't be solved by this ??

Indeed BlackJumper,
the trick here is to build up a look-up table once, on your development pc, and store the values in Data statements.

Then, pick the values from the data statements to fill up two arrays like my_sin() and my_cos(), and use my_sin(angle) instead of sin(angle) to retrieve the values.

In this way you are sure that all the pcs will use the same values - because they are not calculated, but red from data statements - that is, they are constant.

This is the way I solved the 'different values on different pcs' issue.

Hope this has sense for you,
Sergio.


BlackJumper(Posted 2004) [#77]
@semar:
Another option here is to create pseudo-Sin functions from a McLaurin-Taylor expansion series. Normally this is summed to an infinite number of terms, but can be reasonably approximated with only 5 - 10 terms, depending on the accuracy required...



This involves calcualtions of powers and of factorials (big hits on processor) but that makes them perfect for storing in a lookup table rather than constant calculation. And since you are controlling the accuracy by choosing the number of terms I would assume they will be constant across processors {unless the power calculations for floats give different answers :-( }