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