Polygon algorithm

In delphi, we can draw a polygon by using array of TPoint :

  Canvas.Polygon(Points: Array of TPoint);

How can we know that a TPoint is "inside" that polygon ? I meant like "hit test" function.

For rectangle (x1,y1,x2,y2), I can use this "If" clause :

   // Testing P.X and P.Y
   if (P.X >= x1) And (P.Y >= y1) And (P.X <= x2) And (P.Y <= y2) then HIT := TRUE;

Anyone know the algorithm ?
klompenAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Russell LibbySoftware Engineer, Advisory Commented:

You could create a region, and use the PtInRegion to determine if the point falls inside the polygon.

eg:

function PtInPolygon(Point: TPoint; Polygon: Array of TPoint): Boolean;
var  hrgnPoly:      HRGN;
begin

  // Create polygon region
  hrgnPoly:=CreatePolygonRgn(Polygon, Succ(High(Polygon)), WINDING);

  // Make sure the region was created
  if (hrgnPoly = 0) then
     // Failure
     result:=False
  else
  begin
     // Check to see if point lies inside of the region
     result:=PtInRegion(hrgnPoly, Point.X, Point.Y);
     // Delete the region
     DeleteObject(hrgnPoly);
  end;

end;

Example usage (draws a triangle on the form and checks to see if mouse down event is in the triangle):

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin

  if PtInPolygon(Point(X, Y), [Point(100, 100), Point(140, 1), Point(180, 100)]) then
     ShowMessage('Point in polygon');

end;

procedure TForm1.FormPaint(Sender: TObject);
begin
 
  // Draw the polygon so you have something visual to go by
  Canvas.Polygon([Point(100, 100), Point(140, 1), Point(180, 100)]);

end;


Also, for the rectangle, there is a PtInRect function that you could use...

Hope this helps,
Russell

0
mgazzaCommented:
or use this function

function PointInPoly(APoint : TPoint ; APoly : array of TPoint) : boolean;
Var
  i, j : integer;
  npol : integer;
begin
  Result := false;
  npol := length(APoly);
  for i := 0 to npol - 1 do begin
    j := (i + 1) mod npol;
    if ((((APoly[i].Y <= APoint.Y) and (APoint.Y < APoly[j].Y)) or
         ((APoly[j].Y <= APoint.Y) and (APoint.Y < APoly[i].Y))) and
        (APoint.X < (APoly[j].X - APoly[i].X) * (APoint.Y - APoly[i].Y) /
                    (APoly[j].Y - APoly[i].Y) + APoly[i].X)) then
      Result := not Result;
  end;
end;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sftwengCommented:
You might like to explore the math behind a concept called the "convex hull", e.g., at http://mathworld.wolfram.com/ConvexHull.html
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.