Point in rotated rectangle, alternative method

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
monsieur_h
Citizen
Posts: 65
Joined: Tue Oct 30, 2012 4:43 pm

Point in rotated rectangle, alternative method

Post by monsieur_h » Sat Nov 24, 2012 6:17 pm

Hey I'm looking to test if a point is inside a rotated rectangle. I've searched the forum and found this topic:
viewtopic.php?f=4&t=11585&hilit=rotated+rectangle

but using a method with areas sounds like an overkill to me. What I would like to do is: rotate the rectangle back into a vertical position. Rotate the point in -angle. Test the point with a classical AABB method.

Do you see any way of doing this using basic love operations, or is it a consquence of me beeing bad at math?

User avatar
ivan
Party member
Posts: 1530
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Point in rotated rectangle, alternative method

Post by ivan » Sat Nov 24, 2012 6:52 pm

Code: Select all

-- accepts point and angle in radians
function change_angle ( x, y, a )
  local cd = math.cos ( a )
  local sd = math.sin ( a )
  return cd*x - sd*y, cd*y + sd*x
end

-- accepts a point (x, y), aabb center (rx, ry), aabb half-width/half-height (hw, hh) and an angle in radians (a)
function point_vs_raabb ( x, y, rx, ry, hw, hh, a )
  -- translate point to aabb origin
  local lx, ly = x - rx, y - ry
  -- rotate point
  lx, ly = change_angle ( lx, ly, a )

  -- perform regular point vs aabb test
  if lx < -hw or lx > hw then
     return false
  end
  if ly < -hh or ly > hh then
     return false
  end
  return true
end
This is totally untested but it should work as the math I believe is correct.
Basically you only need to transform the point and then perform a regular aabb intersection test (since the point is translated to the aabb origin the test is quite simple).
You may have to make small modifications if you want to represent the aabb in another form then a center point with half width/heights.
Also, note that the code assumes the aabb is rotated around its center.

User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Point in rotated rectangle, alternative method

Post by micha » Mon Nov 26, 2012 10:40 am

monsieur_h wrote:What I would like to do is: rotate the rectangle back into a vertical position. Rotate the point in -angle. Test the point with a classical AABB method.

Do you see any way of doing this using basic love operations, or is it a consquence of me beeing bad at math?
Yes, your suggested method works. I suggest storing the sine and cosine of the box rotation angle, so you dont have to calculate it over and over. Then this method is fast.


A different approach can be found here:
http://www.metanetsoftware.com/technique/tutorialA.html
This text is on intersection of two rectangles, but it is not difficult to take one as a point.

The condition, that a point lies on one of the two sides of a line, is simply a linear condition (involving a scalar product). This can be checked for all four edges of the rectangle. If the point is on the "correct, inner" side of all four lines, it has to be inside. If it is on the "wrong, outer" side for one edge, it is not inside the rectangle. If that does not make sense to you, never mind. Your suggested version works equally fine.

User avatar
monsieur_h
Citizen
Posts: 65
Joined: Tue Oct 30, 2012 4:43 pm

Re: Point in rotated rectangle, alternative method

Post by monsieur_h » Wed Nov 28, 2012 1:08 pm

Hey, thank you both for your time and your answers. I read ivan's first so I tried it before I read yours, micha.

I managed to make a small .love file out of it as a testbed. It works really fine, but I still misunderstand a point :
With a central rotation it is easy to find and pass the center to the point_vs_raabb() function, but I how can I do it when I have a other rotation point?

In the attached .love , you can try [LEFT] and [RIGHT] to turn the recrangle, and [SPACE] to change the offset. Pressing space illustrates the problem I have. Hover the rectangle to make it happy. :megagrin:
Attachments
happy_rect.love
(3.64 KiB) Downloaded 75 times

User avatar
ivan
Party member
Posts: 1530
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Point in rotated rectangle, alternative method

Post by ivan » Wed Nov 28, 2012 4:28 pm

monsieur_h wrote:I managed to make a small .love file out of it as a testbed. It works really fine, but I still misunderstand a point :
With a central rotation it is easy to find and pass the center to the point_vs_raabb() function, but I how can I do it when I have a other rotation point?
I would advise you against this as it will make the code unnecessarily complicated.
Are you using an "offset" simply because of the way Love2D's rendering works?
Can't you just change the position of the aabb (you have it hard-coded to 200, 200) instead of modifying the offset?

User avatar
monsieur_h
Citizen
Posts: 65
Joined: Tue Oct 30, 2012 4:43 pm

Re: Point in rotated rectangle, alternative method

Post by monsieur_h » Wed Nov 28, 2012 7:30 pm

I used the offset because I was adviced to. It seems to be the easiest way to rotate an object in love. In my game I display my rotated items like that, and use it to have an anchor point around wich I rotate my items (its rarely the center of my image). If you have a better way to do so, I take it.

In the mean time I'll try to implement your solution with my happy rectangle.

User avatar
Positive07
Party member
Posts: 1005
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Point in rotated rectangle, alternative method

Post by Positive07 » Tue Dec 04, 2012 9:32 pm

200,200 is your aabb center (rx,ry) and also the center of your rectangle, when you move that rectangle with the offset the center of your rectangle changes, lets say that the new position of the center is 250,250 you left the aabb center at 200,200 so now the center is somewhere else, you have to change rx,ry so they are the same as the center of the rectangle.
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(Github.com/Positive07)

User avatar
monsieur_h
Citizen
Posts: 65
Joined: Tue Oct 30, 2012 4:43 pm

Re: Point in rotated rectangle, alternative method

Post by monsieur_h » Wed Dec 05, 2012 9:30 am

I eventually figured that out. I managed to find the new center of the rotated rectangle using a vector, but it's an overkill to me. If I use vectors, I could directly use micha's method. In essence, that works well, but I'm unsatisfied with my solution.

I have no time to make it clean right now, but I'll get back to it one day.

Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests