euphemism

Untitled

Mar 8th, 2012
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 3.87 KB | None | 0 0
  1. function PointInPolygon(X, Y: Integer; Polygon: TPointArray): Boolean;
  2. (*******************************************************************************
  3. function PointInPolygon(X, Y: Integer; Polygon: TPointArray): Boolean;
  4. By: euphemism
  5. Last Edit: 25 Feb 2012 -- euphemism
  6. Description: Checks to see if the given point, defined by 'X', and 'Y', lies
  7.              within the given concave/convex polygon, 'Polygon'.  Each
  8.              consecutive vertex must be adjacent to the previous one.
  9. *******************************************************************************)
  10. var
  11.   I, Len, MaxX, MinX, MaxY, MinY: Integer;
  12.   Crossed0, Crossed1, Crossed2: Extended;
  13.   TestRay0, TestRay1, TestRay2: TLine;
  14.   Sides: Array of TLine;
  15. begin
  16.  
  17.   Crossed0 := 0;
  18.   Crossed1 := 0;
  19.   Crossed2 := 0;
  20.  
  21.   Result := False;
  22.  
  23.   Len := Length(Polygon);
  24.   SetLength(Sides, Len);
  25.  
  26.   MaxX := Polygon[1].x;
  27.   MinX := Polygon[0].x;
  28.  
  29.   MaxY := Polygon[1].y;
  30.   MinY := Polygon[0].y;
  31.  
  32.   for I := 0 to (Len - 2) do                                                    //This loop creates an array of the sides of the polygon.
  33.   begin
  34.  
  35.     Sides[i].A := Polygon[i];
  36.     Sides[i].B := Polygon[i + 1];
  37.   end;
  38.  
  39.   Sides[Len - 1].A := Polygon[Len - 1];                                         //These two lines set the last side of the polygon.
  40.   Sides[Len - 1].B := Polygon[0];
  41.  
  42.  
  43.   for I := 0 to (Len - 1) do                                                    //This loop finds the minimum X and Y values from the
  44.   begin                                                                         //passed vertices.  This is so we know where to shoot our test ray.
  45.  
  46.     MaxX := Max(Polygon[i].x, MaxX);
  47.     MinX := Min(Polygon[i].x, MinX);
  48.  
  49.     MaxY := Max(Polygon[i].y, MaxY);
  50.     MinY := Min(Polygon[i].y, MinY);
  51.   end;
  52.  
  53.   TestRay0.A := IntToPoint(X, Y);                                                //This sets the test rays to useable segments.
  54.   TestRay0.B := IntToPoint(MinX - 10, MinY - 10);
  55.  
  56.   TestRay1.A := IntToPoint(X, Y);
  57.   TestRay1.B := IntToPoint(MaxX + 10, MinY - 10);
  58.  
  59.   TestRay2.A := IntToPoint(X, Y);
  60.   TestRay2.B := IntToPoint(MaxX + 10, MaxY + 10);
  61.  
  62.   {$IFDEF SMART}
  63.     if ObjDTM_Debug then
  64.     begin
  65.  
  66.       SMART_DrawPolygons(False, [Polygon], clWhite);
  67.       SMART_DrawLine(False, TestRay0.A, TestRay0.B, clRed);
  68.       SMART_DrawLine(False, TestRay1.A, TestRay1.B, clRed);
  69.       SMART_DrawLine(False, TestRay2.A, TestRay2.B, clRed);
  70.     end;
  71.   {$ENDIF}
  72.  
  73.   for I := 0 to (Len - 1) do                                                    //This loop runs through all sides of the polygon and sees if the
  74.   begin                                                                         //test rays intersect each side.  If so, then we increase the 'CrossedX' values
  75.                                                                                 //Using multiple test rays ensures accuracy.
  76.     if LinesIntersect(TestRay0, Sides[i]) then
  77.       Crossed0 := Crossed0 + 1;
  78.  
  79.     if LinesIntersect(TestRay1, Sides[i]) then
  80.       Crossed1 := Crossed1 + 1;
  81.  
  82.     if LinesIntersect(TestRay2, Sides[i]) then
  83.       Crossed2 := Crossed2 + 1;
  84.   end;
  85.  
  86.   if Crossed1 <= Crossed0 then
  87.     Crossed0 := Crossed1;
  88.  
  89.   if Crossed2 <= Crossed0 then                                                  //If the test rays crossed an odd number of sides, then the point is within
  90.     Crossed0 := Crossed2;                                                       //the polygon, if they crossed an even number of sides, or no sides, the point is outside.
  91.  
  92.   Result := ((Crossed0 mod 2) = 1);                                             //This line checks to see if the test rays crossed an even or odd
  93. end;                                                                            //number of sides, and sets the result accordingly.
  94.  
  95. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
Advertisement
Add Comment
Please, Sign In to add comment