-
Notifications
You must be signed in to change notification settings - Fork 2
/
event_queue.go
107 lines (91 loc) · 2.77 KB
/
event_queue.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
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
package voronoi
// Priority queue adapted from the examples of the container/heap package.
import (
"container/heap"
"fmt"
"sort"
)
// EventType represent the type of the event - either site or circle event.
type EventType int
const (
EventSite EventType = 0
EventCircle EventType = 1
)
// Event represents a site or circle event.
type Event struct {
X, Y int // X and Y of the site, or X and Y of the bottom point of the circle.
index int // The index in the slice. Maintained by heap.Interface methods. Needed by Remove method.
EventType EventType // The type of the event. Site = 0 and Circle = 1.
Site *Site // Pointer to the related site. Only relevant for site events.
Node *Node // The related arc node. Only relevant for circle events.
Radius int // Radius of the circle.
}
// A EventQueue is a priority queue that implements heap.Interface and holds Events.
type EventQueue []*Event
// NewEventQueue creates a new queue and initializes it with events for the given list of sites.
func NewEventQueue(sites SiteSlice) EventQueue {
sort.Sort(sites)
eventQueue := make(EventQueue, len(sites))
for i := 0; i < len(sites); i++ {
site := &sites[i]
eventQueue[i] = &Event{
EventType: EventSite,
Site: site,
X: site.X,
Y: site.Y,
index: i,
}
}
heap.Init(&eventQueue)
return eventQueue
}
func (pq EventQueue) String() string {
s := ""
for i, event := range pq {
prefix := ""
if event.EventType == EventCircle {
prefix = "C"
} else {
prefix = "S"
}
if i > 0 {
s += ", "
}
s += fmt.Sprintf("{%d#%s %d,%d}", event.index, prefix, event.X, event.Y)
}
return "{" + s + "}"
}
// Len returns the number of events in the queue.
func (pq EventQueue) Len() int { return len(pq) }
// Less compares two events and is needed as implementation of the Sort interface.
func (pq EventQueue) Less(i, j int) bool {
// We want Pop to give us the event with highest 'y' position.
return pq[i].Y < pq[j].Y || (pq[i].Y == pq[j].Y && pq[i].X < pq[j].X)
}
// Swap swaps two events, updating their index in the slice.
func (pq EventQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
pq[i].index = i
pq[j].index = j
}
// Push appends an item to the queue and reorders items if necessary.
func (pq *EventQueue) Push(x interface{}) {
n := len(*pq)
event := x.(*Event)
event.index = n
*pq = append(*pq, event)
heap.Fix(pq, n)
}
// Pop removes the last element from the queue and sets its index to -1.
func (pq *EventQueue) Pop() interface{} {
old := *pq
n := len(old)
event := old[n-1]
event.index = -1 // for safety
*pq = old[0 : n-1]
return event
}
// Remove removes the element with the specified index from the queue.
func (pq *EventQueue) Remove(event *Event) {
heap.Remove(pq, event.index)
}