Looking for a snap to grid function

Monkey Forums/Monkey Programming/Looking for a snap to grid function

Tri|Ga|De(Posted 2012) [#1]
I have a grid thats filled up with 32x32 squares.

How do I snap a 32x32 sprite when i place it any where on the grid?

I'm trying to figure it out by myself right now and if I come up with a solution before anyone else writes one, I will post it here.


Tri|Ga|De(Posted 2012) [#2]
Found something in this thread

But its not working precisely as I want.

Lets say I have a grid of 32x32 squares 4 horizontal and 4 vertical.
I have a function like this.

Function Snap2Grid:String(xval:float, yval:float)
	Local xs:Float
	Local ys:Float
	
	xs = (Ceil(xval/32 -0.5) * 32)-16
	ys = (Ceil(yval/32 -0.5) * 32)-16
	
	Return "Result = " + xs + ", " + ys
End


A point in the middle of one of those squares is 80,46

I then add 8 pixels to that point and I get a point in 88, 56

If I call my function like this Print( snap2Grid(88, 56) ) it returns Result = 80, 48 and thats okay. I want it to return the center of the square every time.

Now if I subtract 8 pixels to the starting point I get a point in 72, 40.
If I call my function with these values it returns Result = 48, 16 and thats not what I need.

So my question is:

How to I get my function to return the middle of the square every time I call it with a point inside the square?

I hope you get what I'm asking for.


[EDIT]
I think I found what I was looking for.
Function Snap2Grid:String(xval:Int, yval:Int)
	Local xs:Int
	Local ys:Int
	
	xs = Ceil(xval/32)*32 + 16
	ys = Ceil(yval/32)*32 + 16
	
	Return "Result = " + xs + ", " + ys
End

[/EDIT]


Dima(Posted 2012) [#3]
I think you should ditch the Ceil function. Result of dividing integers drops the decimal like a Floor function so in your case Ceiling actually does nothing. But if you were to change ints to floats the result would break using Ceil, because 31/32 would return 1 and not 0.

' correct integer and float snaps to 0
Print 31/32
Print Floor(31.0/32.0)

' incorrect float snaps to 1
Print Ceil(31.0/32.0)


You could use a function like this to snap each axis separately:
Function Snap:Int(val:int)
   return val/32*32 + 16
End



NoOdle(Posted 2012) [#4]
Local gridX : Int = MouseX() / 32
Local snapX : Int = gridX * 32

and if you want to snap to the centre of a grid tile, you simply do this:
Local gridX : Int = ( MouseX + 16 ) / 32
Local snapX : Int = ( ax * 32 ) + 16