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?

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

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

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