[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