Page 2 of 5 FirstFirst 1234 ... LastLast
Results 11 to 20 of 43

Thread: Test Whether A Point Is In A Polygon Or Not

  1. #11
    Junior Member
    Join Date
    Jan 2015
    Posts
    1
    Rep Power
    0

    Great Code

    Hi Rick. I registered on this forum just to thank you for your code. I am using it in an application for a client that owns around 200 cranes (mobile cranes used in industry) - a system on the crane sends it's coordinates back to my server where I have pre-defined areas of responsibilities configured. Using your code, I can now determine when a crane enters a new area and alert that foreman (who is responsible for that specific area/polygon) that he is now responsible for that new crane. Brilliant!


    https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA
    https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgwTUdEgR4bdt6crKXF4AaABAg. 9xmkXGSciKJ9xonTti2sIx
    https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgwWw16qBFX39JCRRm54AaABAg. 9xnskBhPnmb9xoq3mGxu_b
    https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgzgWvzV-kvC4TJ8O414AaABAg.9xnFzCj8HRM9xon1p2ImxO
    https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgybZfNJd3l4FokX3cV4AaABAg. 9xm_ufqOILb9xooIlv5PLY
    https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgzgWvzV-kvC4TJ8O414AaABAg.9xnFzCj8HRM9y38bzbSqaG
    https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgyWm8nL7syjhiHtpBF4AaABAg. 9xmt8i0IsEr9y3FT9Y9FeM
    https://www.youtube.com/watch?v=jTmVtPHtiTg&lc=Ugy_RiNN_kAqUvZ8W994AaABAg. 9xhyRrsUUOM9xpn-GDkL3o
    https://www.youtube.com/watch?v=jTmVtPHtiTg&lc=Ugy_RiNN_kAqUvZ8W994AaABAg
    https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgNsaS3Lp1
    https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgR1EPUkhw
    https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgNe_XC-jK
    https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgNPOdiDuv
    https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgN7AC7wAc
    https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA
    Last edited by DocAElstein; 12-14-2023 at 02:50 AM.

  2. #12
    Forum Guru Rick Rothstein's Avatar
    Join Date
    Feb 2012
    Posts
    662
    Rep Power
    13
    Quote Originally Posted by NinjaTic View Post
    Hi Rick. I registered on this forum just to thank you for your code. I am using it in an application for a client that owns around 200 cranes (mobile cranes used in industry) - a system on the crane sends it's coordinates back to my server where I have pre-defined areas of responsibilities configured. Using your code, I can now determine when a crane enters a new area and alert that foreman (who is responsible for that specific area/polygon) that he is now responsible for that new crane. Brilliant!
    Thank you for letting me know that my function has been so helpful to you in your work... I really appreciate the feedback. Funny, but when I posted that code, I figured it would be of novelty interest only to my readers; but you, and some others who posted above, have indicate that it has a variety of real-world applications... who would have thought. Thank you again for your feedback. By the way, now that you are a registered member of this forum, please come back often... both to "my little corner of the world" here and to the main forum itself (click the big Forum button under the forum's logo above) and posts question that you may have, offer solutions to question others ask when you are able to, or just look around to see what's going on.

  3. #13
    Junior Member
    Join Date
    Mar 2015
    Posts
    1
    Rep Power
    0

    To check if on boundary

    NOTE #3: Points extremely close to, or theoretically lying on, the polygon borders may or may not report back correctly... the vagrancies of floating point math, coupled with the limitations that the "significant digits limit" in VBA imposes, can rear its ugly head in those circumstances producing values that can calculate to either side of the polygon border being tested (remember, a mathematical line has no thickness, so it does not take too much of a difference in the significant digits to "move" a calculated point's position to one side or the other of such a line).

    Apologies if this gets messed up - first posting .....

    I have been doing some basic testing and find that generally when on boundary, I'm getting a false values. My thoughts on dealing with this is to check for X/Y values +/- .001% either side and if any return true, it's close enough to on the line to be true.

    Can you see any faults with that ? I'm writing code for checking aircraft Centre of Gravity limits, so hoping to be reasonably accurate,

    Love your work by the way :-)

    TheCloud

  4. #14
    Forum Guru Rick Rothstein's Avatar
    Join Date
    Feb 2012
    Posts
    662
    Rep Power
    13
    Quote Originally Posted by theCloud View Post
    I have been doing some basic testing and find that generally when on boundary, I'm getting a false values. My thoughts on dealing with this is to check for X/Y values +/- .001% either side and if any return true, it's close enough to on the line to be true.

    Can you see any faults with that ? I'm writing code for checking aircraft Centre of Gravity limits, so hoping to be reasonably accurate..
    The following is untested because I do not have a data setup to use, nor a set of prescribed boundary points to check, but I think I modified everything correctly. Since you seem to have the necessary data, I'll let you check it out.

    What I have done is resurrect an old IsNearLine function I had written about the same time I wrote the PtInPoly function (somewhere between 10 and 15 years ago now), modified its argument to accept line end points as defined in the PtInPoly function, and added a Tolerance constant (the Const statement) so you can play around with that value in order to fine-tune it. Since I had to modify part of PtInPoly to accommodate the call out to the IsNearLine function, I am posting all the code you will need below (it replaces you current copy of my PtInPoly function. To repeat, this is all untested, so I cannot guarantee it will work, but in my mind's eye, I do not see why it won't... please let me, and the readers of this thread, know how your experimentation with it works out. I would also note that I expect the calculations to go slower because of the added, repeated calls to the IsNearLine function, but I do not have a feel for how much (maybe you could let us know your impressions on that as well).

    Code:
    Public Function PtInPoly(Xcoord As Double, Ycoord As Double, Polygon As Variant) As Variant
      Dim x As Long, NumSidesCrossed As Long, m As Double, B As Double, Poly As Variant
      Const Tolerance As Double = 0.001
      Poly = Polygon
      For x = LBound(Poly) To UBound(Poly) - 1
        If Poly(x, 1) > Xcoord Xor Poly(x + 1, 1) > Xcoord Then
          m = (Poly(x + 1, 2) - Poly(x, 2)) / (Poly(x + 1, 1) - Poly(x, 1))
          B = (Poly(x, 2) * Poly(x + 1, 1) - Poly(x, 1) * Poly(x + 1, 2)) / (Poly(x + 1, 1) - Poly(x, 1))
          If IsNearLine(Poly(x, 1), Poly(x, 2), Poly(x + 1, 1), Poly(x + 1, 2), Xcoord, Ycoord, Tolerance) Then
            NumSidesCrossed = NumSidesCrossed + 1
          ElseIf m * Xcoord + B > Ycoord Then
            NumSidesCrossed = NumSidesCrossed + 1
          End If
        End If
      Next
      PtInPoly = CBool(NumSidesCrossed Mod 2)
    End Function
    
    
    Function IsNearLine(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long, _
                        PX As Variant, PY As Variant, Tolerance As Variant) As Boolean
      Dim A As Double, B As Double, C As Double, DistPtToLine As Double
      If ((PX - X1) * (PX - X1) + (PY - Y1) * (PY - Y1) < Tolerance * Tolerance) Or _
          ((PX - X2) * (PX - X2) + (PY - Y2) * (PY - Y2) < Tolerance * Tolerance) Then
        IsNearLine = True
      Else
        A = Y2 - Y1
        B = X1 - X2
        C = X2 * Y1 - Y2 * X1
        DistPtToLine = Abs((A * PX + B * PY + C) / Sqr(A * A + B * B))
        If DistPtToLine <= Tolerance Then
          If X2 > X1 And PX > X1 And PX < X2 Then
            If Y2 > Y1 And PY > Y1 And PY < Y2 Or Y2 < Y1 And PY < Y1 And PY > Y2 Then
              IsNearLine = True
            End If
          ElseIf X2 < X1 And PX < X1 And PX > X2 Then
            If Y2 > Y1 And PY > Y1 And PY < Y2 Or Y2 < Y1 And PY < Y1 And PY > Y2 Then
              IsNearLine = True
            End If
          End If
        End If
      End If
    End Function

  5. #15
    Junior Member
    Join Date
    Jun 2015
    Posts
    2
    Rep Power
    0

    Got an Error

    Hi Rick,

    First, thank you very much for creating this module.

    I'm trying to use it for a test procedure for quality control.

    The 4 sided polygon that I'm using is very small the X and Y coordinates are in the x0.3200, y0.3300 and x0.3400, y0.3500 range. Out to 4 decimal places.

    I'm getting a Compile error: ByRef argument type mismatch.

    It has highlighted the following

    Code:
    Public Function PtInPoly(Xcoord As Double, Ycoord As Double, Polygon As Variant) As Variant
      Dim x As Long, NumSidesCrossed As Long, m As Double, B As Double, Poly As Variant
      Const Tolerance As Double = 0.001
      Poly = Polygon
      For x = LBound(Poly) To UBound(Poly) - 1
        If Poly(x, 1) > Xcoord Xor Poly(x + 1, 1) > Xcoord Then
          m = (Poly(x + 1, 2) - Poly(x, 2)) / (Poly(x + 1, 1) - Poly(x, 1))
          B = (Poly(x, 2) * Poly(x + 1, 1) - Poly(x, 1) * Poly(x + 1, 2)) / (Poly(x + 1, 1) - Poly(x, 1))
          If IsNearLine(Poly
    With "Poly" as being the culprit after If IsNearLine(Poly

    I'm using a closed Polygon with 5 x & Y points the last XY being the same as the first one.

    In my particular case this is the call out =PtInPoly(B40,C40,S39:T43)

    B40 would be X and C40 Y, and S39:T43 the polygon points.

    I'm using Excel 2010.

    Thank you for your help.

    You are providing a great service to us all.

    Ps. I'm a Excel Noob.

    Google CIE 1931
    Last edited by Admin; 07-17-2015 at 08:15 AM.

  6. #16

  7. #17
    Junior Member
    Join Date
    Jan 2016
    Posts
    1
    Rep Power
    0

    Code works very well, many thanks.

    Good day Rick,

    Your code 'Public Function PtInPoly(Xcoord As Double, Ycoord As Double, Polygon As Variant) As Variant' works very well. I am writing to say thank you for creating it and also for answering questions and posting potential pitfalls.

    Next, is this code offered as freeware, shareware, or another sort of fee schedule? I am not using it for any sort of profit at the present time, but if I elect to in the future I would like to know if there are any potential strings attached. Obviously I will cite you with credit as to the creator and authorship of the code where used. Please respond at our convenience. Thank you for your time.

    Respectfully,


    Brett

    Cultural Resource Management
    Master's Candidate
    St. Cloud State University

  8. #18
    Forum Guru Rick Rothstein's Avatar
    Join Date
    Feb 2012
    Posts
    662
    Rep Power
    13
    Quote Originally Posted by Goodwood View Post
    Good day Rick,

    Your code 'Public Function PtInPoly(Xcoord As Double, Ycoord As Double, Polygon As Variant) As Variant' works very well. I am writing to say thank you for creating it and also for answering questions and posting potential pitfalls.

    Next, is this code offered as freeware, shareware, or another sort of fee schedule? I am not using it for any sort of profit at the present time, but if I elect to in the future I would like to know if there are any potential strings attached. Obviously I will cite you with credit as to the creator and authorship of the code where used. Please respond at our convenience. Thank you for your time.
    Hi Brett,

    Thank you for you nice comments... much appreciated. As for using the code... there are no strings attached... if I post something online without specifically marking it copyrighted or "restricted use" or some other such marking, then you are free to use it in anyway you see fit. With that said, if you make a commercial product using it, I would hope you would contact me and make a donation of some kind to me for my efforts, but that would be strictly voluntary on your part... to repeat, if not marked otherwise, you are free to use anything I post in anyway you see fit.

  9. #19
    Junior Member
    Join Date
    Mar 2016
    Posts
    2
    Rep Power
    0
    Hello,

    first of all, thank you for your code. Im an optical engineer, and i need to mesh a polygon (equally distribute points) to calculate the homogenity of the luminance at these points, this is why your code is helpful to me.

    However, i have a couple questions:

    • Code:
      Poly = Polygon
      why is this line needed? declaring an other variable seems to be unnecessary to me, can i use just polygon instead of poly?
    • Code:
      PtInPoly = CBool(NumSidesCrossed Mod 2)
      what is the exact purpose of CBool? NumSidesCrossed Mod 2 gives 1 or 0 (remember, PtInPoly is a variant, not boolean) which can be used as the condition input for IF, no need to make the code longer with CBoolean.
    • you mention that the first and last point of the polygon have to be the same. Since this is a _must_ condition, why not write the code in such a way, that the last point would be added as the first point. this way no error correction would be necessary, since the last point would be automatically copied from the first point.

    Last edited by qetuol; 03-14-2016 at 05:38 PM.

  10. #20
    Forum Guru Rick Rothstein's Avatar
    Join Date
    Feb 2012
    Posts
    662
    Rep Power
    13
    Quote Originally Posted by qetuol View Post
    However, i have a couple questions:

    Code:
    Poly = Polygon
    why is this line needed? declaring an other variable seems to be unnecessary to me, can i use just polygon instead of poly?
    The Polygon argument can be either a two-dimensional VBA array or a two-dimensional range. If it is a range, assigning that range to a Variant variable converts it to a two-dimensional VBA array so that the rest of the code ends up with the same kind of array as when a real two-dimensional array is inputted. The reason the assignment has to take place within the code is because the coercion to an array does not take place via the argument itself even if that argument is a Variant. So, that line of code makes the overall function flexible enough to handle a real array (assigning such an array to the Variant variable does not change its structure) or a range (because the range gets converted to a real array).



    Quote Originally Posted by qetuol View Post
    Code:
    PtInPoly = CBool(NumSidesCrossed Mod 2)
    what is the exact purpose of CBool? NumSidesCrossed Mod 2 gives 1 or 0 (remember, PtInPoly is a variant, not boolean) which can be used as the condition input for IF, no need to make the code longer with CBoolean.
    I wanted the function to return either TRUE or FALSE directly in case the function was to be used directly in a MessageBox or to fill a TextBox or any other number of uses besides as the argument to an IF function... the idea being the user can implement the function without having to take special steps to format the output for the occasion. As for why PtInPoly is a Variant and not a Boolean... that was so it could accommodate the error messages when called as a UDF directly on a worksheet.



    Quote Originally Posted by qetuol View Post
    you mention that the first and last point of the polygon have to be the same. Since this is a _must_ condition, why not write the code in such a way, that the last point would be added as the first point. this way no error correction would be necessary, since the last point would be automatically copied from the first point.
    It was a design decision to help a user not make a mistake. If the user accidentally grabbed the wrong number of rows from a table of coordinates and inputted that too short range of values, the function would alert the user to the error because the last point did not equal the first point... if I made the function close the polygon automatically, it would blindly calculate values and the user would not be aware some of the answers were incorrect... by forcing the user to make sure the polygon closed, he/she could never make a mistake of accidentally inputting too few points.
    Last edited by Rick Rothstein; 01-30-2017 at 02:57 PM.

Similar Threads

  1. This is a test Test Let it be
    By Admin in forum Test Area
    Replies: 6
    Last Post: 05-30-2014, 09:44 AM
  2. This is a test of Signature Block Variable Dim
    By alansidman in forum Test Area
    Replies: 0
    Last Post: 10-17-2013, 07:42 PM
  3. Test
    By Excel Fox in forum Den Of The Fox
    Replies: 0
    Last Post: 07-31-2013, 08:15 AM
  4. Replies: 4
    Last Post: 06-10-2013, 01:27 PM
  5. Test
    By Excel Fox in forum Word Help
    Replies: 0
    Last Post: 07-05-2011, 01:51 AM

Tags for this Thread

Posting Permissions

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