zhangzengfei
2023-09-04 e8e536d1cb52d2126c8c7ce2ba1c7a76f7208678
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
 
import (
    "fmt"
    "math"
)
 
type ProgramsInfo struct {
    Id            string
    CreatedAt     string
    UpdatedAt     string
    Name          string
    Desc          string
    Type          string
    Arch          string
    LatestVersion string
    LatestPackage string
}
 
var Data = `{"code":200,"data":[],"msg":"请求处理成功","success":true}`
 
type Point struct {
    Log float64 //经度X
    Lat float64 //维度Y
}
 
func main() {
    ps := []Point{{116.3325833222656, 40.04070204153866}, {116.41635407421873, 40.042804758324685}, {116.42184723828123, 39.98495642053631}, {116.3380764863281, 39.98179964655109}}
    n1 := Point{116.36966217968748, 40.01651613780475}
    //n1 := Point{116.3710354707031,39.92916527606944}
    fmt.Print(IsPointInPolygon(n1, ps))
 
}
 
func IsPointInPolygon(point Point, points []Point) bool {
    N := len(points)
    boundOrVertex := true //点在多边形顶点或者边上,算作多边形内
    intersectCount := 0
    precision := 2e-10 //浮点类型计算时候与0比较时候的容差
    var p1, p2 Point
    p := point //当前点
    p1 = points[0]
    for i := 0; i <= N; i++ {
        if p == p1 {
            return boundOrVertex
        }
 
        p2 = points[i%N]
        if p.Log < math.Min(p1.Log, p2.Log) || p.Log > math.Max(p1.Log, p2.Log) {
            p1 = p2
            continue
        }
        if p.Log > math.Min(p1.Log, p2.Log) && p.Log < math.Max(p1.Log, p2.Log) {
            if p.Lat <= math.Max(p1.Lat, p2.Lat) {
 
                if p1.Log == p2.Log && p.Lat >= math.Min(p1.Lat, p2.Lat) {
                    return boundOrVertex
                }
 
                if p1.Lat == p2.Lat {
                    if p1.Lat == p.Lat {
                        return boundOrVertex
                    } else {
                        intersectCount++
                    }
                } else {
                    xinters := (p.Log-p1.Log)*(p2.Lat-p1.Lat)/(p2.Log-p1.Log) + p1.Lat
                    if math.Abs(p.Lat-xinters) < precision {
                        return boundOrVertex
                    }
 
                    if p.Lat < xinters {
                        intersectCount++
                    }
                }
            }
 
        } else {
            if p.Log == p2.Log && p.Lat <= p2.Lat {
                p3 := points[(i+1)%N]
                if p.Log >= math.Min(p1.Log, p3.Log) && p.Log <= math.Max(p1.Log, p3.Log) {
                    intersectCount++
                } else {
                    intersectCount += 2
                }
            }
        }
        p1 = p2
    }
 
    if intersectCount%2 == 0 { //偶数在多边形内
        return false
    } else { //奇数在多边形外
        return true
    }
}
 
//func IsPointInPolygon(point Point, points []Point) bool {
//    var iSum, iCount, iIndex int32
//    var dLog1, dLog2, dLat1, dLat2, dLog float64
//    if len(points) < 3 {
//        return false
//    }
//    iCount = int32(len(points))
//    for iIndex = 0; iIndex < iCount; iIndex++ {
//        dLog1 = points[iIndex].Log
//        dLat1 = points[iIndex].Lat
//        if iIndex == iCount-1 {
//            dLog2 = points[0].Log
//            dLat2 = points[0].Lat
//        } else {
//            dLog2 = points[iIndex+1].Log
//            dLat2 = points[iIndex+1].Lat
//        }
//        //判断A点是否在边的两端点的水平平行线之间,在则可能有交点,开始判断交点,开始判断交点是否在左射线上
//        if ((point.Lat >= dLat1) && (point.Lat < dLat2)) || ((point.Lat >= dLat2) && (point.Lat < dLat1)) {
//            if math.Abs(dLat1-dLat2) > 0 {
//                //得到A点向左射线与边的交点的x坐标
//                dLog = dLog - ((dLog1-dLog2)*(dLat1-point.Lat))/(dLat1-dLat2)
//                //如果交点在A点左侧(说明是左射线与边的交点),则射线与边的全部交点数加一
//                if dLog < point.Log {
//                    iSum++
//                }
//            }
//        }
//    }
//    if (iSum % 2) != 0 {
//        return true
//    }
//    return false
//}