ImageRectOverlap type function

BlitzMax Forums/BlitzMax Programming/ImageRectOverlap type function

supermeerkat(Posted 2006) [#1]
Hi

I'm looking for a function in Bmax similar to B+'s ImageRectOverlap function, which tests for collision between a rectangle and an image, which igonores transparent image pixels.

Does Bmax offer a function like this, and if not could someone please give an example of the code, please?

Thanks


Fetze(Posted 2006) [#2]
Wouldn't that be similar to a boundingbox-check?
Here, that should work:

Function RectsOverlap:Byte(iParX1:Int, iParY1:Int, iParW1:Int, iParH1:Int, iParX2:Int, iParY2:Int, iParW2:Int, iParH2:Int)
	If iParX1 > (iParX2 + iParW2) Or (iParX1 + iParW1) < iParX2 Then Return False
	If iParY1 > (iParY2 + iParH2) Or (iParY1 + iParH1) < iParY2 Then Return False
	Return True
End Function



Eikon(Posted 2006) [#3]
Here's an ImageRectCollide function too
Function ImageRectCollide%(image:TImage, ix%, iy%, iframe%, rx%, ry%, rwidth%, rheight%)

	If iframe < 0 Then Return
	
   ResetCollisions
   CollideImage image, ix, iy, iframe, 0, 1

   If CollideRect(rx, ry, rwidth, rheight, 1, 0) Then Return True Else Return False
End Function



Grey Alien(Posted 2006) [#4]
Hmm, I was just using the RectsOverlap function above and found that it claims rects overlap when they are merely adjacent. For example a 10x10 rect is sitting next to another one. The first one is at 0,0 and the second one is at 10,0. So the test goes:

Is 0 > (10+10)? No so it does the next test ...
Is (0+10) < 10? No so it it checks the Y coords.

If I reduce the width that I pass in by 1 it's fine.

It can be be fixed by changing all the comparisons to >= and <=. However, I also changed the function to take floats, but that didn't seem to work as well when I passed in floating coords, hmm.

So beware...


sswift(Posted 2006) [#5]
This is the function I use in my sprite system. It will handle rotated and animated images. You'll have to make a few changes to it to make it work with images though, because you'll need to tell it the rotation and scale of both the image and rect, as well as the frame the image is displaying.

This won't interefere with any other collision code you might have because it uses the same temporary collision layer users are not intended to access which the other collision functions use.

	Method OverlapsRect%(RectX#, RectY#, RectWidth#, RectHeight#, RectRotation#=0)	

			Local Result%

			' Clear collision layer 32. 
			' Using layer 32 because it is a scratch layer used by some internal functions and will probably not be used by the user.
				ResetCollisions COLLISION_LAYER_32
	
			' Place sprite in collision layer 32.
		
				SetRotation Rotation#(True)
				SetScale ScaleX#(True), ScaleY#(True)
	
				CollideImage _Image, X#(True), Y#(True), Frame#(True), 0, COLLISION_LAYER_32
	
			' Set Result to true if rect is colliding with the image we just placed in collision layer 32.
			' (Rect is not written to collision layer.)

				SetRotation RectRotation#
				SetScale 1,1

				If CollideRect(RectX#, RectY#, RectWidth#, RectHeight#, COLLISION_LAYER_32, 0) <> Null Result = True
	
			Return Result
	
		End Method


The Rotation() ScaleX() Frame() etc functions are getting the sprite's parameters, so those are what you need to pass to the function for the image.


Grey Alien(Posted 2006) [#6]
Interesting but overkill for what I needed which was to compare some coords without using the collision layer (no rotated/scaled images for the case I was checking).

Did you see what I mean about the other method above being duff? It's not the only example there are loads on the forum, all the same! I'm wondering if they all came from the same corrupt source or if I'm being dumb here and missing something.


sswift(Posted 2006) [#7]
I wasn't tryong to help YOU Grey, this is supermeekat's thread. :-)


Grey Alien(Posted 2006) [#8]
yeah but it's *5* months old, I was just resurrecting it due to the code posted being bugged ;-p


sswift(Posted 2006) [#9]
Ah. Very tricky there. You got me!