Clamping?

BlitzMax Forums/BlitzMax Programming/Clamping?

zoqfotpik(Posted 2012) [#1]
Is there a canonical way to implement constraints so that one has cleaner code, eg. for collisions with walls?

If x < 0 + radius	
		vx = vx * -1
		x = 0 + radius
	EndIf
	
	If y < 0 + radius 
		vy = vy * -1
		y = 0 + radius
	EndIf
	
	If x > WIDTH - radius 
		vx = vx * -1
		x = WIDTH - radius
	EndIf
	
	If y > HEIGHT - radius 
		vy = vy * -1
		y = HEIGHT - radius
	EndIf


I'd like to be able to do this in a simpler way. Is there such a method? EG.
Clamp (x, 0, WIDTH)


I suppose you could have this send a return value of -1 if the input was under the first parameter, 1 if it was over the second parameter, and zero if it was in between both parameters.

Thoughts?


Yasha(Posted 2012) [#2]
You could do this:

Function CLAMP(x:Int Var, lo:Int, hi:Int)
	If x < lo Then x = lo ; Else If x > hi Then x = hi
End Function

Local a:Int = 5, b:Int = 10, c:Int = 20
CLAMP a, b, c

Print a


I... am not a fan of this, myself (too used to C-style pointers to like C++-style references), but it works and will save you the most keystrokes. It's not a macro, though, and treating it like one is a bit misleading. Personally I'd rather just use "x = Clamp(x, ..." most of the time.


zoqfotpik(Posted 2012) [#3]
Ah, I see what you're doing there. It still doesn't execute the secondary effect though-- but again that could be done with a return value (executing different cases depending on -1 | 0 | 1)

It may be just one of those things where it's simpler to just type it out and encapsulate it than worry about it.

Last edited 2012


Yasha(Posted 2012) [#4]
I guess you could do this:

Function CLAMP(x:Int Var, lo:Int, hi:Int)
	If x < lo
		x = lo ; Return 1
	ElseIf x > hi
		x = hi ; Return 1
	EndIf
	Return 0
End Function

vx :* (-CLAMP(x, ...))


That's getting into unreadably-dense code though. Not really a generic function any more.


zoqfotpik(Posted 2012) [#5]
Can you explain this syntax? That is to say the :*

vx :* (-CLAMP(x, ...))


Last edited 2012


Mahan(Posted 2012) [#6]
vx :* (-CLAMP(x, ...))

equals
vx = vx * (-CLAMP(x, ...))


iirc


Yasha(Posted 2012) [#7]
Yup.

Much like the function itself, it means you only need to type the name once. It also means its location only has to be fetched once, which may be important if the variable is a field at the end of a long method chain or something like that.


zoqfotpik(Posted 2012) [#8]
Is there any way to define inline functions in Blitzmax?


zoqfotpik(Posted 2012) [#9]
[double post]

Last edited 2012


Yasha(Posted 2012) [#10]
No.

If you really really need that sort of thing, you might have to investigate some kind of macro processor solution. Minimac is a nice general purpose one. The C preprocessor probably isn't suitable, since ' and # have different meanings in BlitzMax and would conflict with it.

Last edited 2012