|
判断点是否在自由曲线内.rar
(50.25 KB, 下载次数: 67)
- Type Point
- x As Double
- y As Double
- End Type
- Public Sub GetStdLine(ps As Point, pe As Point, ByRef a As Double, ByRef b As Double, ByRef c As Double)
- '根据两个点的坐标求经过两点的直线的标准方程参数A、B、C
- Dim xs As Double, ys As Double, xe As Double, ye As Double
- xs = ps.x: ys = ps.y: xe = pe.x: ye = pe.y
- Dim p1 As Double, p2 As Double
- p1 = xs * ye: p2 = xe * ys
- If (p1 = p2) Then
- If (xs = 0) Then
- If (xe = 0) Then
- a = 1: b = 0: c = 0
- ElseIf (ys = 0) Then
- a = ye: b = -xe: c = 0
- End If
- ElseIf (ye = 0) Then
- If (ys = 0) Then
- a = 0: b = 1: c = 0
- ElseIf (xe = 0) Then
- a = -ys: b = xs: c = 0
- End If
- End If
- Else
- a = (ys - ye) / (p1 - p2): c = 1
- If (ys = 0) Then
- If (ye = 0) Then
- b = 1: c = 0
- Else
- b = -(a * xe + 1) / ye
- End If
- Else
- b = -(a * xs + 1) / ys
- End If
- End If
- End Sub
- Public Function InPoly(poly() As Point, p As Point) As Boolean
- '判断点是否在多边形内部
- Dim i As Integer, f As Integer, xi As Double
- Dim a As Double, b As Double, c As Double
- Dim ps As Point, pe As Point
- For i = 0 To UBound(poly)
- ps = poly(i)
- If (i < UBound(poly)) Then pe = poly(i + 1) Else pe = poly(0)
- GetStdLine ps, pe, a, b, c
- If (a <> 0) Then
- xi = -(b * p.y + c) / a
- If (xi = p.x) Then
- InPoly = True: Exit Function
- ElseIf (xi < p.x) Then
- f = f + Sgn(pe.y - p.y) - Sgn(ps.y - p.y)
- End If
- End If
- Next i
- InPoly = (f <> 0)
- End Function
- Public Function IsIn(Sx As Range, Sy As Range, x As Range, y As Range)
- Dim poly() As Point, p As Point, i As Integer, Xx, Yy
- Dim arr(), j As Long
- Xx = WorksheetFunction.Transpose(Sx): Yy = WorksheetFunction.Transpose(Sy)
- ReDim poly(0 To UBound(Xx) - 1)
- For i = 0 To UBound(Xx) - 1
- poly(i).x = CDbl(Xx(i + 1)): poly(i).y = CDbl(Yy(i + 1))
- Next i
- For i = 1 To x.Columns(1).Cells.Count
- p.x = CDbl(x.Cells(i, 1)): p.y = CDbl(y.Cells(i, 1))
- If InPoly(poly, p) Then
- ReDim Preserve arr(1, j)
- arr(0, j) = p.x: arr(1, j) = p.y
- j = j + 1
- End If
- Next
- IsIn = arr
- End Function
- Sub main()
- Dim dd
- dd = WorksheetFunction.Transpose(IsIn([g3:g113], [h3:h113], [b3:b490], [c3:c490]))
- Range("d:e").ClearContents
- Range("d3").Resize(UBound(dd), 2) = dd
- End Sub
复制代码 |
|