-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathring.go
More file actions
118 lines (104 loc) · 1.91 KB
/
ring.go
File metadata and controls
118 lines (104 loc) · 1.91 KB
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
// v0.1.0
package imgpath
import (
"errors"
)
type IndexRing struct {
index int
length int
cycled bool
}
// NewIndexRing creates a new IndexRing of size `l`. `l` must be greater than one.
func NewIndexRing(l int) (*IndexRing, error) {
if l <= 1 {
return nil, errors.New("size should be at least 2")
}
return &IndexRing{length: l}, nil
}
func (ir IndexRing) Cycled() bool {
return ir.cycled
}
// Next returns the current value of the index and points to the next one.
func (ir *IndexRing) Next() int {
ii := ir.index
ir.index++
if ir.index >= ir.length {
ir.index = 0
ir.cycled = true
}
return ii
}
func (ir *IndexRing) Reset() {
ir.index = 0
ir.cycled = false
}
type continuousOutput struct {
length int
start int
angle int // in degree
score int
dark bool
}
func continuousBright(ts []int) continuousOutput {
co := continuous(ts, func(in int) bool { return in > 0 })
co.dark = false
return co
}
func continuousDark(ts []int) continuousOutput {
co := continuous(ts, func(in int) bool { return in < 0 })
co.dark = true
return co
}
func continuous(ts []int, fn func(in int) bool) continuousOutput {
var co continuousOutput
ir, err := NewIndexRing(len(ts))
if err != nil {
return co
}
var l, start int
continuous := false
score := 0xFF
for {
ii := ir.Next()
if fn(ts[ii]) {
l++
if l >= len(ts) {
// continuous line.
return continuousOutput{
length: 0,
start: 0,
angle: 0,
score: 0,
dark: false,
}
}
score = min(score, abs(ts[ii]))
if !continuous {
continuous = true
start = ii
}
continue
}
if continuous {
continuous = false
if l > co.length {
co.length = l
co.start = start
co.score = score
a := (3*start + l) % len(ts)
co.angle = 180 * a / len(ts)
}
l = 0
score = 0xFF
}
if ir.Cycled() {
return co
}
}
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}