# Working with rotated Object2D and mouse positions

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?

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]``` 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]
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?

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.

If you’re working with RectShapes (or any of its subclasses) use the Contains method:

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 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 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

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.

Thanks