Results 1 to 4 of 4

Thread: R_inPolygon

  1. #1
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default R_inPolygon

    I found a function online to return whether or not a point is inside of a polygon, and I thought I would share it here:

    Original link: http://wiki.freepascal.org/Geometry_in_Pascal

    Original code:
    pascal Code:
    function IsPointInPolygon(AX, AY: Integer; APolygon: array of TPoint): Boolean;
    var
      xnew, ynew: Cardinal;
      xold,yold: Cardinal;
      x1,y1: Cardinal;
      x2,y2: Cardinal;
      i, npoints: Integer;
      inside: Integer = 0;
    begin
      Result := False;
      npoints := Length(APolygon);
      if (npoints < 3) then Exit;
      xold := APolygon[npoints-1].X;
      yold := APolygon[npoints-1].Y;
      for i := 0 to npoints - 1 do
      begin
        xnew := APolygon[i].X;
        ynew := APolygon[i].Y;
        if (xnew > xold) then
        begin
          x1:=xold;
          x2:=xnew;
          y1:=yold;
          y2:=ynew;
        end
        else
        begin
          x1:=xnew;
          x2:=xold;
          y1:=ynew;
          y2:=yold;
        end;
        if (((xnew < AX) = (AX <= xold))         // edge "open" at left end
          and ((AY-y1)*(x2-x1) < (y2-y1)*(AX-x1))) then
        begin
          inside := not inside;
        end;
        xold:=xnew;
        yold:=ynew;
      end;
      Result := inside <> 0;
    end;

    Converted to fit our needs:(very small changes)

    Simba Code:
    function R_inPolygon(Area: TPointArray): Boolean;
    var
      xnew, ynew, xold, yold, X1, Y1, X2, Y2: Cardinal;
      i, numpoints, inside, X, Y: Integer;
    begin
      numpoints := Length(Area);
      X := R_GetTileGlobal.x;
      Y := R_GetTileGlobal.y;
      if (numpoints < 3) then Exit;
      xold := Area[numpoints - 1].x;
      yold := Area[numpoints - 1].y;
      for i := 0 to (numpoints - 1) do
      begin
        xnew := Area[i].x;
        ynew := Area[i].y;
        if (xnew > xold) then
        begin
          X1 := xold;
          X2 := xnew;
          Y1 := yold;
          Y2 := ynew;
        end
        else
        begin
          X1 := xnew;
          X2 := xold;
          Y1 := ynew;
          Y2 := yold;
        end;
        if (((xnew < X) = (X <= xold)) and ((Y - Y1) * (X2 - X1) < (Y2 - Y1) * (X - X1))) then
          inside := not inside;
        xold := xnew;
        yold := ynew;
      end;
      Result := inside <> 0;
    end;


    You need > 3 points for it to properly work.

  2. #2
    Join Date
    Dec 2011
    Location
    New York, USA
    Posts
    1,242
    Mentioned
    12 Post(s)
    Quoted
    193 Post(s)

    Default

    A while ago I was thinking of (using some basic calculus stuff) finding where the slopes between points in a polygon are positive or negative using the derivative, and then doing some stuff that im too high to explain to create a function that returns a string that, kind of like a dtm, represents a series of booleans and points and stuff to create like an artificial simba polygon,

    good stuff tho mr barbrady, move along people nothing to see here

  3. #3
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Nebula View Post
    A while ago I was thinking of (using some basic calculus stuff) finding where the slopes between points in a polygon are positive or negative using the derivative, and then doing some stuff that im too high to explain to create a function that returns a string that, kind of like a dtm, represents a series of booleans and points and stuff to create like an artificial simba polygon,

    good stuff tho mr barbrady, move along people nothing to see here
    Can you expand on that later when your not high?

  4. #4
    Join Date
    Dec 2007
    Posts
    2,112
    Mentioned
    71 Post(s)
    Quoted
    580 Post(s)

    Default

    why not use Sign? didnt really look at the math behind that function but from my engine, cba converting...

    Code:
    	public float Sign(PointD PointD_A, PointD PointD_B, PointD PointD_C) {
    		return (PointD_A.X() - PointD_C.X()) * (PointD_B.Y() - PointD_C.Y())
    				- (PointD_B.X() - PointD_C.X()) * (PointD_A.Y() - PointD_C.Y());
    	}
    
    	public boolean PointInTri(PointD PointD_P, PointD PointD_A,
    			PointD PointD_B, PointD PointD_C) {
    
    		boolean[] boolArrTemp = new boolean[3];
    
    		boolArrTemp[0] = (Sign(PointD_P, PointD_A, PointD_B) <= 0.0F);
    		boolArrTemp[1] = (Sign(PointD_P, PointD_B, PointD_C) <= 0.0F);
    		boolArrTemp[2] = (Sign(PointD_P, PointD_C, PointD_A) <= 0.0F);
    
    		return (boolArrTemp[0] == boolArrTemp[1])
    				&& (boolArrTemp[1] == boolArrTemp[2]);
    	}

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •