-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathpoint.go
65 lines (51 loc) · 1.38 KB
/
point.go
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
// Package cluster implements DBScan clustering on (lat, lon) using K-D Tree
package cluster
// Point is longitue, latittude
type Point [2]float64
// PointList is a slice of Points
type PointList []Point
// Cluster is a result of DBScan work
type Cluster struct {
C int
Points []int
}
// sqDist returns squared (w/o sqrt & normalization) distance between two points
func (a *Point) sqDist(b *Point) float64 {
return DistanceSphericalFast(a, b)
}
// LessEq - a <= b
func (a *Point) LessEq(b *Point) bool {
return a[0] <= b[0] && a[1] <= b[1]
}
// GreaterEq - a >= b
func (a *Point) GreaterEq(b *Point) bool {
return a[0] >= b[0] && a[1] >= b[1]
}
// CentroidAndBounds calculates center and cluster bounds
func (c *Cluster) CentroidAndBounds(points PointList) (center, min, max Point) {
if len(c.Points) == 0 {
panic("empty cluster")
}
min = Point{180.0, 90.0}
max = Point{-180.0, -90.0}
for _, i := range c.Points {
pt := points[i]
for j := range pt {
center[j] += pt[j]
if pt[j] < min[j] {
min[j] = pt[j]
}
if pt[j] > max[j] {
max[j] = pt[j]
}
}
}
for j := range center {
center[j] /= float64(len(c.Points))
}
return
}
// Inside checks if (innerMin, innerMax) rectangle is inside (outerMin, outMax) rectangle
func Inside(innerMin, innerMax, outerMin, outerMax *Point) bool {
return innerMin.GreaterEq(outerMin) && innerMax.LessEq(outerMax)
}