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

Kevin Fishburne kevinfishburne at ...1887...
Tue Oct 8 06:43:05 CEST 2013


On 10/06/2013 07:08 AM, Jesus wrote:
> 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

Excellent, thank you.

I'll explain what I'm trying to do so maybe it will shed some light on 
how this algorithm (or a similar one) could be more useful if it allowed 
specifying the lower-bound instead of assuming it was always zero.

Imagine an old-school, top-down, tile-based RPG where the initial 
rendering pass rendered all tiles in the "tile grid" (tiles visible to 
the player). If you move left, the tile grid is shifted one tile to the 
right and a new column of tiles is drawn on the left side of the tile 
grid. This is inefficient because it requires the tile grid to be 
shifted each time the player moves. In my case the tile grid is a 2D 
array of OpenGL textures (one texture per tile), not a single image/bitmap.

A more efficient solution is to maintain tile grid "offsets", specifying 
the player's x and y positions relative to the initial rendering of the 
tile grid (0, 0). So after the initial render, when the player moves 
left, the tile grid's x offset would become -1 and the new column of 
tiles would wrap around the tile grid and overwrite the right-most 
column. When rendering a frame and reading the tile grid, the typical 
nested x/y For...Next loop would use the offsets with wrapping so the 
tile grid textures were read in the correct sequence. This requires that 
at least the lower-bound of the wrapping function be able to accept 
negative numbers, if not the upper-bound as well.

Here's what I'm using at the moment. The commented out sections are an 
algorithm I found online, which returns values outside the specified 
wrapping range:

---

Public Function Wrap_Short(Minimum As Short, Maximum As Short, Value As 
Short) As Short

   ' Constrain value to specified range.

   ' General declarations.
   Dim Spread As Short = Maximum - Minimum + 1 ' Range between minimum 
and maximum values.

   ' Check if value is already within specified range.
   If Value >= Minimum And Value <= Maximum Then Return Value

   'If Value < Minimum Then
   '  Value += Spread * ((Minimum - Value) / Spread + 1)
   'Else
   '  Value = (Minimum + (Value - Minimum) % Spread)
   'Endif
   ' Return wrapped value.
   'Return Value

   ' Wrap if value is too large.
   If Value > Maximum Then
     Do
       Value = Value - Spread
     Loop Until Value <= Maximum
   Endif

   ' Wrap if value is too small.
   If Value < Minimum Then
     Do
       Value = Value + Spread
     Loop Until Value >= Minimum
   Endif

   ' Return wrapped value.
   Return Value

End

---

Since this wrapping function is performed twice per tile per frame and 
uses a Do...Loop to brute force the wrapping, it's insanely inefficient. 
The commented out code is super-efficient compared to my crap method. 
Any ideas here? Here's the reference for the commented out algorithm:

http://stackoverflow.com/questions/707370/clean-efficient-algorithm-for-wrapping-integers-in-c

It's also possible that I mistranslated the C code in the above link, as 
I don't know C.

-- 
Kevin Fishburne
Eight Virtues
www: http://sales.eightvirtues.com
e-mail: sales at ...1887...
phone: (770) 853-6271





More information about the User mailing list