题目是:
已知一个不规则的N边形各个顶点的坐标分别为M1(X1,Y1),M2(X2,Y2),……,MN(XN,YN),判断点A(X,Y)是否落在该N多边形形成的封闭区域中。请帮忙写一个算法!

解决方案 »

  1.   

    把这n变形创建一个region,然后用这个函数判断就可以了 
    Private Declare Function PtInRegion Lib "gdi32" Alias "PtInRegion" (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As Long
      

  2.   

    给你个例子Private Type POINTAPI
        x As Long
        y As Long
    End Type
    Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
    Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
    Private Declare Function FillRgn Lib "gdi32" (ByVal hDC As Long, ByVal hRgn As Long, ByVal hBrush As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Private Declare Function PtInRegion Lib "gdi32" (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As LongDim i As Integer
    Dim rgn As Long
    Dim pt() As POINTAPI
    Dim DrawRgn As Boolean
    Private Sub Form_Load()
        DrawRgn = True    '为绘制选区状态
        Me.ScaleMode = 3
        Me.AutoRedraw = True
    End Sub
    Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
        If Button = 1 Then
            If DrawRgn = True Then
                ReDim Preserve pt(i) As POINTAPI
                pt(i).x = x
                pt(i).y = y
                i = i + 1
                Circle (x, y), 2, vbBlue
            Else
                If PtInRegion(rgn, x, y) Then
                    Circle (x, y), 2, vbRed   '判断是否在选区内,是,则红色表示,不是,则黑色表示
                Else
                    Circle (x, y), 2, vbBlack
                End If
            End If
            
        End If
        
    End SubPrivate Sub Form_DblClick()
        Dim Brh As Long
        rgn = CreatePolygonRgn(pt(0), UBound(pt), 1)  '创建选区
        Brh = CreateSolidBrush(vbYellow)
        FillRgn Me.hDC, rgn, Brh     '填充选区
        DeleteObject Brh
        DrawRgn = False
    End Sub
    Private Sub Form_Unload(Cancel As Integer)
        DeleteObject rgn
    End Sub
      

  3.   

    如果自己写的话,我有一段vb.net的代码,她的原理是:
    如果从该点作垂直向下方向上的射线与多边形的边的交点个数为奇数,则该点在多边形内。
        '**************************************************************************************
        '
        ' 函数功能::        检查某点是否在指定的多边行内,已重载
        ' point:           PointF    待测试的点
        ' 修改者:          laviewpbt
        ' 修改时间:        2006-5-1 20:38
        '
        '**************************************************************************************    Public Overloads Function Contains(ByVal point As PointF) As Boolean
            If m_path.PointCount = 0 Or m_path.PathPoints.Length = 0 Then
                Return False
            End If
            Return Contains(point, m_path.PathPoints)
        End Function
        '**************************************************************************************
        '
        ' 函数功能::      检查某点是否在指定的多边行内,多边形由cornerPoints参数指定的点组成
        ' 实现原理:        如果从该点作垂直向下方向上的射线与多边形的边的交点个数为奇数,则该
        '                   点在多边行内
        ' point:           PointF    待测试的点
        ' cornerPoints():  PointF    多边行的顶点
        ' 修改者:          laviewpbt
        ' 修改时间:        2006-5-1 20:32
        '
        '**************************************************************************************    Public Overloads Shared Function Contains(ByVal point As PointF, ByVal cornerPoints() As PointF) As Boolean
            Dim intersections As Integer = 0
            Dim i As Integer
            For i = 1 To cornerPoints.Length - 1
                If DoesIntersect(Point, cornerPoints(i), cornerPoints(i - 1)) Then
                    intersections += 1
                End If
            Next
            If DoesIntersect(Point, cornerPoints(cornerPoints.Length - 1), cornerPoints(0)) Then
                intersections += 1   '起点中终点的线段
            End If
            Return intersections Mod 2 <> 0
        End Function
        '**************************************************************************************
        '
        ' 函数功能::      检查从某个点沿垂直向下的方向延伸的射线与通过指定两点的线段是否相交
        ' point:           PointF    待测试的点
        ' point1:          PointF    线段的起点之一
        ' point2:          PointF    线段的起点之一
        ' 修改者:          laviewpbt
        ' 修改时间:        2006-5-1 20:32
        '
        '**************************************************************************************    Private Shared Function DoesIntersect(ByVal point As PointF, ByVal point1 As PointF, ByVal point2 As PointF) As Boolean
            Dim x2 As Single = point2.X
            Dim y2 As Single = point2.Y
            Dim x1 As Single = point1.X
            Dim y1 As Single = point1.Y
            If (point.X >= x1 And point.X <= x2) OrElse (point.X >= x2 And point.X <= x1) Then   '在此条件下可能会相交
                Dim y As Single = y1 + (y2 - y1) / (x2 - x1) * (point.X - x1)  '计算以point.x为X坐标,作垂直线与两点确定直线的交点的Y坐标
                Return y >= point.Y   '注意屏幕坐标系Y轴垂直向下
            End If
            Return False    '其他情况下不会相交
        End Function
      

  4.   

    看来我能解决问题,先谢“laviewpbt(人一定要靠自己)”,回头解决后马上结帐……