What is the best way to detect if the mouse is hovering over an Object2D object? It appears I cannot use anything like the REALbasic.Rect as that does not seem to support rotation.

Thanks

What is the best way to detect if the mouse is hovering over an Object2D object? It appears I cannot use anything like the REALbasic.Rect as that does not seem to support rotation.

Thanks

Maybe it?

http://math.stackexchange.com/questions/190111/how-to-check-if-a-point-is-inside-a-rectangle

Has several generalized solutions for arbitrary polygons, and that was the first search result…

Any suggestions? Should I use the RGBSurface? Should I write a class with some complex math algorithms? Should I use MBS plugins?

Thanks

[quote=145417:@Jason King]Maybe it?

http://math.stackexchange.com/questions/190111/how-to-check-if-a-point-is-inside-a-rectangle

Has several generalized solutions for arbitrary polygons, and that was the first search result…[/quote]

Thanks. I will have a look at this.

And how can I convert this to Xojo code?

(0<AM?AB<AB?AB)?(0<AM?AD<AD?AD)

Thanks

```
function Point_In_Rect(px as integer,py as integer,x as integer,y as integer,w as integer,h as integer) as Boolean
return (px>=x) and (px<=x+w) and (py>=y) and (py<=y+h)
end function
```

[quote=145423:@Dave S]```
function Point_In_Rect(px as integer,py as integer,x as integer,y as integer,w as integer,h as integer) as Boolean
return (px>=x) and (px<=x+w) and (py>=y) and (py<=y+h)
end function
```

[/quote]

Thanks a milli.

[quote=145423:@Dave S]

This will only work for rectangles which have not been rotated

It does if you normalize the points first…

True. I just wanted to make sure Oliver realized that it was not a drop in and go solution if he did not normalize the points.

[quote=145422:@Oliver Scott-Brown]And how can I convert this to Xojo code?

(0<AM?AB<AB?AB)?(0<AM?AD<AD?AD)

Thanks[/quote]

Using a vector2d class I have for another project I translated that to Xojo code for you. For future reference the dot is the dot product of the vectors and ^ is logical and.

I would do this by untransforming the click point so it’s relative to the untransformed rect, then you can do the AABB (axis aligned bounding box) hit test.

[code]//In a Window with Canvas1…

theRect As RectShape

Sub Open()

theRect = new RectShape

theRect.Width = 100

theRect.Height = 50

theRect.X = 200

theRect.Y = 200

theRect.Rotation = 30 * 6.28318 / 360 //30 degrees

theRect.Scale = 1.5

End Sub

Sub Paint(g As Graphics, areas() As REALbasic.Rect) //Canvas1

g.ForeColor = &c808080

g.FillRect 0, 0, g.Width, g.Height

g.DrawObject theRect

End Sub

Function MouseDown(X As Integer, Y As Integer) As Boolean //Canvas1

doHitAndUpdate(X, Y)

return true

End Function

Sub MouseDrag(X As Integer, Y As Integer) //Canvas1

doHitAndUpdate(X, Y)

End Sub

Sub doHitAndUpdate(x As integer, y As integer)

if hitRect(theRect, X, Y) then

theRect.FillColor = &c00FF00

else

theRect.FillColor = &c000000

end

Canvas1.Invalidate

End Sub

Function hitRect(r As RectShape, px As integer, py As integer) As boolean

dim tx, ty As integer

tx = (px - r.X) / r.Scale //untranslate and unscale

ty = (py - r.Y) / r.Scale

dim sina, cosa As double //calc rotate coefficients

sina = sin(-r.Rotation)

cosa = cos(-r.Rotation)

dim rx, ry As double //unrotate to final untransformed point

rx = tx * cosa - ty * sina

ry = tx * sina + ty * cosa

return Abs(rx) <= r.Width * 0.5 and Abs(ry) <= r.Height * 0.5 //AABB hit test

End Function[/code]

If the rect is nested in Group2Ds the entire sequence of transforms needs to be undone. And if you use DrawObject offsets they need to be accounted for too.

Thanks. Really appreciate the effort.

Ha, I love it when built in features are overlooked And it works for Group2D nested rects too.

Wow thanks. I am sorry to all those people who worked hard to help me solve this problem but it looks like there is already something pretty awesome that is built-in for this. Appreciate the link too Bradley.

Thanks

How would I go about doing an intersects function like REALbasic.Rect? There seems to be an inconsistency with Xojo where using the ‘Intersects’ method is available in REALbasic.Rect but not RectShape and same goes for the ‘Contains’ method but for RectShape.

So how could I detect the collision between two RectShapes?

Thanks

I tried this:

```
Function Intersects(extends item1 as RectShape, item2 as RectShape) As boolean
dim x10 as double = item1.x
dim y10 as double = item1.y
dim r as double = item1.rotation
item1.rotation = 0
dim height1 as double = item1.height / 2
dim width1 as double = item1.width / 2
item1.rotation = r
dim radrot1 as double = rad(item1.rotation)
dim x20 as double = item2.x
dim y20 as double = item2.y
r = item2.rotation
item2.rotation = 0
dim height2 as double = item2.height / 2
dim width2 as double = item2.width / 2
item2.rotation = r
dim radrot2 as double = rad(item2.rotation)
dim radius1 as double = sqrt( height1*height1 + width1*width1 )
dim radius2 as double = sqrt( height2*height2 + width2*width2 )
radius1 = sqrt( height1*height1 + width1*width1 )
radius2 = sqrt( height2*height2 + width2*width2 )
dim angle1 as double = asin( height1 / radius1 )
dim angle2 as double = asin( height2 / radius2 )
dim x1(4), y1(4), x2(4), y2(4) as double
x1(1) = x10 + radius1 * cos(radrot1 - angle1)
y1(1) = y10 + radius1 * sin(radrot1 - angle1)
x1(2) = x10 + radius1 * cos(radrot1 + angle1)
y1(2) = y10 + radius1 * sin(radrot1 + angle1)
x1(3) = x10 + radius1 * cos(radrot1 + pi - angle1)
y1(3) = y10 + radius1 * sin(radrot1 + pi - angle1)
x1(4) = x10 + radius1 * cos(radrot1 + pi + angle1)
y1(4) = y10 + radius1 * sin(radrot1 + pi + angle1)
x2(1) = x20 + radius2 * cos(radrot2 - angle2)
y2(1) = y20 + radius2 * sin(radrot2 - angle2)
x2(2) = x20 + radius2 * cos(radrot2 + angle2)
y2(2) = y20 + radius2 * sin(radrot2 + angle2)
x2(3) = x20 + radius2 * cos(radrot2 + pi - angle2)
y2(3) = y20 + radius2 * sin(radrot2 + pi - angle2)
x2(4) = x20 + radius2 * cos(radrot2 + pi + angle2)
y2(4) = y20 + radius2 * sin(radrot2 + pi + angle2)
dim axisx(4), axisy(4) as double
axisx(1) = x1(1) - x1(2)
axisy(1) = y1(1) - y1(2)
axisx(2) = x1(3) - x1(2)
axisy(2) = y1(3) - y1(2)
axisx(3) = x2(1) - x2(2)
axisy(3) = y2(1) - y2(2)
axisx(4) = x2(3) - x2(2)
axisy(4) = y2(3) - y2(2)
dim proj, minProj1, maxProj1, minProj2, maxProj2 as double
for k as integer = 1 to 4
proj = x1(1) * axisx(k) + y1(1) * axisy(k)
minProj1 = proj
maxProj1 = proj
for i as integer = 2 to 4
proj = x1(i) * axisx(k) + y1(i) * axisy(k)
if proj < minProj1 then
minProj1 = proj
elseif proj > maxProj1 then
maxProj1 = proj
end
proj = x2(1) * axisx(k) + y2(1) * axisy(k)
minProj2 = proj
maxProj2 = proj
for j as integer = 2 to 4
proj = x2(j) * axisx(k) + y2(j) * axisy(k)
if proj < minProj2 then
minProj2 = proj
elseif proj > maxProj2 then
maxProj2 = proj
end
next
if maxProj2 < minProj1 or maxProj1 < minProj2 then
return false
end if
next
return true
next
End Function
```

I attempted to convert the code from LUA to Xojo. I wrote a method to convert radians to degrees. It does not seem to work.

Got the code from:

http://forums.coronalabs.com/topic/39094-code-for-rotated-rectangle-collision-detection/

Thanks

Could someone please help me solve this problem? Are there any engines written by anybody?

Thanks

@Oliver Scott-Brown Oliver - this may help you out. I’ve been struggling with this myself and have come up with something I think should work for you. Drag Rects to test collision.

Thankyou very much. I wasn’t expecting a reply on this thread after such a while but I have been working on other aspects of the program so I forgot about this thread. But I am very glad you came to help. Thanks

Forum for Xojo Programming Language and IDE. Copyright © 2024 Xojo, Inc.