SFML community forums

Help => Graphics => Topic started by: Mangocheese on March 22, 2010, 02:07:27 pm

Title: Point inside polygon shape?
Post by: Mangocheese on March 22, 2010, 02:07:27 pm
Hello,

Is there any way to test if a point is within a polygon shape?

Also,

When a sprite is rotated, does it rotate the bounding box aswell?

Thanks!
Title: Point inside polygon shape?
Post by: Mindiell on March 22, 2010, 02:22:56 pm
As far as I know :
- No
- No, the bounding box is an horizontal rectangle with the sprite in it

For your first point, this method check if a point is inside a polygon. Coords is a vector containing the points of the polygon. A point is a simple two values structure. This is done with a vector test : saying that if each edge of the polygon has the point to the right, the point is inside the polygon :
Code: [Select]
////////////////////////////////////////////////////////////
/// Check if a point is inside the polygon's area
////////////////////////////////////////////////////////////
template <typename T>
bool sfPoly<T>::Contains(T X, T Y) const
{
    for (unsigned int i=0;i<Coords.size()-2;i+=2)
    {
        if (((Y-Coords[i+1])*(Coords[i+2]-Coords[i]) - (X-Coords[i])*(Coords[i+3]-Coords[i+1]))<0)
        {
            return (false);
        }
    }
    //The last test is special
    unsigned int j = Coords.size();
    if (((Y-Coords[j-1])*(Coords[0]-Coords[j-2]) - (X-Coords[j-2])*(Coords[1]-Coords[j-1]))<0)
    {
        return (false);
    }
    return (true);
}
Title: Point inside polygon shape?
Post by: Mangocheese on March 22, 2010, 03:01:32 pm
Thanks, that piece of code helped out a lot!
Title: Point inside polygon shape?
Post by: gsaurus on March 22, 2010, 05:07:40 pm
However I think it's a must add in case polygon class becomes independent of it's drawable representation on SFML2 :wink:
Title: Point inside polygon shape?
Post by: Mangocheese on March 24, 2010, 05:37:58 am
I've done a bit of research and created some code (with help from http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/).

Below is my code, sloppy as it is, it does the trick. I hope it is helpful to those who need it. For this code, I found that I had to add the point twice into the vector. Can anyone refine the process, or am I on the right track?

Code: [Select]

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

const double pi = 3.14;
const double twopi = 6.28;

struct Point
{
int x, y;
};

bool InsidePolygon(vector<Point> Poly, int sides, Point mouseCoods);
double Angle2D(double x1, double y1, double x2, double y2);

int main()
{
sf::RenderWindow App(sf::VideoMode(800,600,32), "Inside Polygon Test");

App.SetFramerateLimit(60);

sf::Event appEvent;
vector<Point> vPolygon;

sf::Shape Polygon;

while(App.IsOpened())
{
while(App.GetEvent(appEvent))
{
if(appEvent.Type == sf::Event::Closed)
{
App.Close();
}

if(appEvent.Type == sf::Event::MouseButtonPressed)
{
if(appEvent.MouseButton.Button == sf::Mouse::Left)
{
Point temp;

temp.x = appEvent.MouseButton.X;
temp.y = appEvent.MouseButton.Y;

if(InsidePolygon(vPolygon, vPolygon.size(), temp))
{
cout << "Inside." << endl;
}
}
if(appEvent.MouseButton.Button == sf::Mouse::Right)
{
Point temp;
temp.x = appEvent.MouseButton.X;
temp.y = appEvent.MouseButton.Y;

Polygon.AddPoint(temp.x, temp.y);

vPolygon.push_back(temp);
vPolygon.push_back(temp);
}
}
}

App.Clear();

App.Draw(Polygon);

App.Display();
}

return 0;
}

bool InsidePolygon(vector<Point> Poly, int sides, Point mouseCoods)
{
int i;
double angle=0;
Point p1,p2;

for (i=0;i<sides;i++) {
p1.x = Poly[i].x - mouseCoods.x;
p1.y = Poly[i].y - mouseCoods.y;
p2.x = Poly[(i+1)%sides].x - mouseCoods.x;
p2.y = Poly[(i+1)%sides].y - mouseCoods.y;
angle += Angle2D(p1.x,p1.y,p2.x,p2.y);
}

if (abs(angle) < pi)
return(FALSE);
else
return(TRUE);
}

double Angle2D(double x1, double y1, double x2, double y2)
{
   double dtheta,theta1,theta2;

   theta1 = atan2(y1,x1);
   theta2 = atan2(y2,x2);
   dtheta = theta2 - theta1;
   while (dtheta > pi)
      dtheta -= twopi;
   while (dtheta < -pi)
      dtheta += twopi;

   return(dtheta);
}


Thanks.  :D
Title: Point inside polygon shape?
Post by: stubler on April 30, 2010, 04:52:00 am
Thanks from me as well.