Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / missing maths sgn() function (with workaround)

Author
Message
Marl
13
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 2nd Dec 2011 16:09
You never notice things not being there until you need them eh?

I couldn't find sgn() or an equivalent function ( which returns -1 for negative numbers, 1 for positive numbers and 0 for zero).

So here's a workaround if you find you need it;


There is another way to do it, but it's not as neat and probably a lot slower because of the division, but here it is for completeness;
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 2nd Dec 2011 17:50
The first method is very neat and smart, very nice. The second is wrong and could cause a divide by zero error:


bitJericho
22
Years of Service
User Offline
Joined: 9th Oct 2002
Location: United States
Posted: 2nd Dec 2011 17:54 Edited at: 2nd Dec 2011 17:58
baxslash, you do not take into account sgn returning 0 on an input of 0.



If you want 0 or greater to return 1 and all negative numbers to return 0, then this code is best:




baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 2nd Dec 2011 17:58 Edited at: 2nd Dec 2011 18:01
Oops, yes you're right. I just noticed the divide by zero and didn't think about returning zero.

EDIT: I'm even more stupid than I thought. It was right in the first place. Sometimes my mind plays tricks on me I thought sgn would only return a positive or negative, nevermind...

EDIT2: TFI Friday

Marl
13
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 2nd Dec 2011 19:54
Quote: "The first method is very neat and smart, very nice."

Thank you very much.

Boolean Algebra is something I'm quite fond of, you can dodge a lot of nested conditionals under the right circumstances.
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 2nd Dec 2011 23:34
Quote: "The second is wrong and could cause a divide by zero error"


There's a more fundamental reason why this is not true
Try forcing a divide by zero in AppGameKit, you'll be surprised

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 2nd Dec 2011 23:49
OK, I did and there was no error. Not sure if I like that or not...

I'd be interested in knowing how they managed that? Is there a way of checking the values of a division before it is done? Wouldn't that unnecessarily increase the workload?

Maybe I've had too many beers to think about it properly but surely doing something like:


...is much slower than:


BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 3rd Dec 2011 19:00
I can only guess that dividing by zero does so much untold destruction on some of the devices, that it has to be avoided at all costs. However, the answer should be 999999.... rather than zero.

Hodgey
15
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 4th Dec 2011 02:14
Quote: "OK, I did and there was no error. Not sure if I like that or not..."

Neither am I. I think it would be nice if the error was reported through the GetErrorOccurred() command as well as being set to 0.

Cliff Mellangard 3DEGS
Developer
18
Years of Service
User Offline
Joined: 20th Feb 2006
Location: Sweden
Posted: 4th Dec 2011 13:10
No one that have good functions for something that wraps an angle ?

Iam forced to use dummy sprites for this now.

Iam missing the wrapvalue command from dbp

I couldt find it anywhere in the commands list of agk?
Impetus73
13
Years of Service
User Offline
Joined: 28th Aug 2011
Location: Volda, Norway
Posted: 4th Dec 2011 14:24
if angle#>360.0 then angle#=angle#-360.0

loop it, if you happens to increase in such enormous steps that it still is above 360.

----------------
AGK user - novice
Did Amiga / AMOS programming in the 90's, just started programming again with AGK.
Cliff Mellangard 3DEGS
Developer
18
Years of Service
User Offline
Joined: 20th Feb 2006
Location: Sweden
Posted: 4th Dec 2011 14:29
Quote: "if angle#>360.0 then angle#=angle#-360.0

loop it, if you happens to increase in such enormous steps that it still is above 360."

I had the same idea first but it seams to miss small steps when it wraps it like that.

After a while so did the angles dont match when i compared it with the dummy sprite angle?

But will try to give it a go again

Thanks my norwegian friend
Marl
13
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 4th Dec 2011 20:57
You could try fmod() when you change the angle.

I've not used it so can't vouch for it's accuracy (or indeed my use of it).
Cliff Mellangard 3DEGS
Developer
18
Years of Service
User Offline
Joined: 20th Feb 2006
Location: Sweden
Posted: 5th Dec 2011 21:48
Pretty good! but it dosent like negative values like turning the other direction

But it works if i do this!

function Wrap(ang#)
result# = fmod ( ang#+(360.0*360.0) , 360.0 )
endfunction result#

For it to fail so do you nead to turn it constantly in only one direction for a long while.
360x360 = 129 600
Is it stupid to do it like that?

The differrence compared to using an sprite dummy is minimal

Thanks for the feedback to you both
bitJericho
22
Years of Service
User Offline
Joined: 9th Oct 2002
Location: United States
Posted: 5th Dec 2011 22:20
You should probably file a bug report. I'm fairly certain a negative value should wrap around. For example, -90 should return 270 with mod 360.


Marl
13
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 6th Dec 2011 00:04 Edited at: 6th Dec 2011 00:12
If precision is important, I would resist adding such a large value.

Since floating point only uses a certain number of digits, using 129,600 (as opposed to say 720) will cost you three digits at the bottom end.

If my understanding of floating point is right

Edit:

Better yet would be not to use negative angles at all.

Instead of subtracting 10 degrees, you add 350 degrees and wrap it. Then it should never go minus.

ie. #angle = fmod ( angle# + (360.0 + change#) , 360.0 )

(of course this is no good if you're simply reading the angle of a self-rotating object)

Login to post a reply

Server time is: 2024-11-22 20:08:19
Your offset time is: 2024-11-22 20:08:19