返回列表 上一主題 發帖

[發問] 落點問題....(我目前從未到過的領域)

回復 1# ui123
B區補完(6,6),(5,5)形成凹多邊形
判斷的演算法可以參考 http://www.csie.ntnu.edu.tw/~u91029/Polygon.html
裡面 判斷一個點是否在簡單多邊形內部裡面 這一段

TOP

本帖最後由 stillfish00 於 2013-11-13 00:27 編輯

回復 4# ui123
他是C/C++寫的,改成VBA大約如下
  1. Function pointInPoly(ptx As Double, pty As Double, arPoly) As Boolean
  2.     Dim i As Long, j As Long
  3.     Dim pix As Double, piy As Double
  4.     Dim pjx As Double, pjy As Double
  5.    
  6.     For i = 1 To UBound(arPoly) - 1
  7.         j = i + 1
  8.         pix = arPoly(i, 1): piy = arPoly(i, 2)
  9.         pjx = arPoly(j, 1): pjy = arPoly(j, 2)
  10.         
  11.         '不包含點在多邊形線上
  12.         If Not (piy > pty) = (pjy > pty) Then
  13.             If ptx < (pjx - pix) * (pty - piy) / (pjy - piy) + pix Then pointInPoly = Not pointInPoly
  14.         End If
  15.     Next
  16. End Function
複製代碼
利用他寫一個自訂函數RegionABC
  1. Function RegionABC(x As Double, y As Double, RegionA As Range, RegionB As Range, RegionC As Range) As String
  2.     '不包含點在ABC邊緣
  3.     If pointInPoly(x, y, RegionA.Value) Then RegionABC = "A": Exit Function
  4.     If pointInPoly(x, y, RegionB.Value) Then RegionABC = "B": Exit Function
  5.     If pointInPoly(x, y, RegionC.Value) Then RegionABC = "C": Exit Function
  6.     RegionABC = "不在ABC"
  7. End Function
複製代碼
先補齊B區的點,
使用,例如在O4公式打上  "=RegionABC(M4,N4,$C$4:$D$8,$C$10:$D$16,$C$18:$D$22)"

TOP

回復 10# ML089
自訂函數
  1. Function PolyArea(rngPoly As Range)
  2.     Dim i As Long, j As Long
  3.     Dim pix As Double, piy As Double
  4.     Dim pjx As Double, pjy As Double
  5.     Dim arPoly, area As Double
  6.         
  7.     arPoly = rngPoly.Value
  8.     If UBound(arPoly, 2) <> 2 _
  9.         Or arPoly(1, 1) <> arPoly(UBound(arPoly), 1) _
  10.         Or arPoly(1, 2) <> arPoly(UBound(arPoly), 2) Then PolyArea = CVErr(xlErrRef): Exit Function
  11.    
  12.     area = 0
  13.     For i = 1 To UBound(arPoly) - 1
  14.         j = i + 1
  15.         pix = arPoly(i, 1): piy = arPoly(i, 2)
  16.         pjx = arPoly(j, 1): pjy = arPoly(j, 2)
  17.         
  18.         area = area + pix * pjy
  19.         area = area - piy * pjx
  20.     Next
  21.     PolyArea = Abs(area) / 2
  22. End Function
複製代碼

TOP

回復 19# ui123
修改如下,可含邊上的點,有優先順序(靠前的優先)
區域不限ABC三區可在參數自行增加,但要依參數順序。
  1. Function pointInPoly(ptx As Double, pty As Double, arPoly) As Boolean
  2.     Dim i As Long, j As Long
  3.     Dim pix As Double, piy As Double
  4.     Dim pjx As Double, pjy As Double
  5.    
  6.     For i = 1 To UBound(arPoly) - 1
  7.         j = i + 1
  8.         pix = arPoly(i, 1): piy = arPoly(i, 2)
  9.         pjx = arPoly(j, 1): pjy = arPoly(j, 2)
  10.         
  11.         '多邊形邊上
  12.         If (pix - ptx) * (pjy - pty) - (piy - pty) * (pjx - ptx) = 0 And _
  13.             (pix - ptx) * (pjx - ptx) + (piy - pty) * (pjy - pty) <= 0 Then _
  14.         pointInPoly = True: Exit Function
  15.         
  16.         '多邊形內部
  17.         If Not (piy > pty) = (pjy > pty) Then
  18.             If ptx < (pjx - pix) * (pty - piy) / (pjy - piy) + pix Then pointInPoly = Not pointInPoly
  19.         End If
  20.     Next
  21. End Function

  22. Function RegionABC(x As Double, y As Double, ParamArray polyRegion())
  23.     '3rd參數為A區,4th參數為B區。。。依此類推,越靠前的優先。
  24.     Dim i As Long, arPoly
  25.         
  26.     For i = LBound(polyRegion) To UBound(polyRegion)
  27.         arPoly = polyRegion(i).Value
  28.         
  29.         If UBound(arPoly, 2) <> 2 _
  30.             Or arPoly(1, 1) <> arPoly(UBound(arPoly), 1) _
  31.             Or arPoly(1, 2) <> arPoly(UBound(arPoly), 2) Then RegionABC = CVErr(xlErrRef): Exit Function
  32.         
  33.         If pointInPoly(x, y, arPoly) Then
  34.             RegionABC = Chr(65 + i - LBound(polyRegion))    '依順位顯示A,B,C,D
  35.             Exit Function
  36.         End If
  37.     Next i
  38.     RegionABC = "不在範圍內"
  39. End Function
複製代碼

TOP

回復 19# ui123
A區面積 =PolyArea(C4:D8)
這只是ML089大在10樓要我另外幫忙寫的算面積的函數。

TOP

        靜思自在 : 能付出愛心就是福,能消除煩惱就是慧。
返回列表 上一主題