[Gambas-user] "wrapping" function based on recent Mod thread

Jesus ea7dfh at ...2382...
Sun Oct 6 13:08:08 CEST 2013


El 06/10/13 05:40, Kevin Fishburne escribió:
> Jesus Guardon said in the recent thread "Modulo operator returns wrong
> results ":
>
>      Hi Paul et all
>
>      When working with some video games, there are a feature called
>      wraparound or screen wrap. It consists on objects leaving one side of
>      the screen that immediately reappear on the opposite side, maintaining
>      speed and trajectory. For this task usually modular arithmetic is used,
>      involving the Mod operator.
>
>      As I said before, on Python at least, it works as expected with
>      negative
>      numbers, and not only integers.
>
>      Lets imagine a spaceship in a drawing area 800px wide that reaches past
>      the left edge of the screen. Just before it passes, say at pixel 2 in X
>      coordinates, the operation would be:
>
>      2 Mod 800 = 2
>
>      So, nothing has changed in its position. But when the ship is at
>      negative coordinates, say again -2:
>
>      -2 Mod 800 = 798
>
>      That's exactly the opposite side of the drawing area, which is what I
>      had expected. If -2 would be returned instead, it won't work.
>
>      However this is not an issue for me, since this can be solved this way:
>
>      Private Sub fmod(Dd As Float, d As Float) As Float
>
>            If Dd < 0 Then
>                Return Abs((Frac(Dd / d)) * d - d)
>            Else
>                Return (Frac(Dd / d)) * d
>            Endif
>
>      End
>
>      So no need to modify gambas at all, ;-)
>
> ---
>
> A couple of questions. First which is the upper-bound (screen
> width/height) and which is the current value (position), Dd or d?
> Second, is there a way using this algorithm to specify the lower-bound?
> The solutions I've found online for "wrapping" a number between an
> arbitrary lower- and upper-bound don't work when the value being wrapped
> is negative. The algorithm I'm using is horribly inefficient, as it uses
> loops.
>

Hi, Kevin

Well, as you know, screen coordinates start in the upper left corner and 
grow towards the right in the X axis and towards the bottom in the Y 
axis. Sorry if it's too obvious.

So all operations on an hypothetical spaceship, must be done on separate 
axis, for instance X at first and Y at last (this is not critical, 
though). So the above function is a try to mimic the Mod operator which 
accepts the dividend (Dd) and divisor (d) returning the remainder even 
if dividend is negative.

So, if you prefer, the arguments for the above function should read:

fmod(actualPosition, screenLimit) and need to be calculated for each 
axis separately.

ship_pos.X = fmod(ship_pos.X, screenWidht)
ship_pos.Y = fmod(ship_pos.Y, screenHeight)

That is! Also, it accepts float numbers and return (cast float)integers.

You could view it in action here[0], though it is in Spanish. The 
example project is available for download at the end of the post.

[0] http://blog.gambas-es.org/aceleracion-y-friccion/

Hope this helps, best regards!

Jesús Guardón





More information about the User mailing list