Skip to content

Commit f818dbc

Browse files
author
Oleksandr Glagoliev
committed
Add logger
1 parent dd781e7 commit f818dbc

File tree

4 files changed

+77
-17
lines changed

4 files changed

+77
-17
lines changed

Sources/FortunesAlgorithm/FortuneSweep.swift

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,21 @@ public class FortuneSweep {
2727
/// Service Data Structures
2828
private var eventQueue: PriorityQueue<Event>!
2929
private var beachline: Beachline!
30-
private var sweepLineY = Double(0)
30+
private var sweepLineY: Double = 0
3131
private var firstSiteY: Double?
3232

3333
private var container: Rectangle!
3434
private var clipper: Rectangle!
3535

36+
/// Debug Data structures
37+
private var logger: FortuneSweepLogging?
38+
private var currentStep: Int = 0
3639
/// Result Data Structure
37-
private(set) var diagram = Diagram()
40+
private(set) var diagram: Diagram!
3841

39-
public init() { }
42+
public init(logger: FortuneSweepLogging? = nil) {
43+
self.logger = logger
44+
}
4045

4146
public func compute(
4247
sites: Set<Site>,
@@ -48,9 +53,13 @@ public class FortuneSweep {
4853
let filtered = sites
4954
.filter { clipper.contains($0) }
5055
.map { Event(point: $0) }
56+
5157
/// Diagram is a whole plane. Do nothing
52-
if filtered.isEmpty { return }
53-
58+
if filtered.isEmpty {
59+
logger?.log("Computation done. No sites inside defined area!", level: .info)
60+
return
61+
}
62+
currentStep = 0
5463
sweepLineY = 0
5564
firstSiteY = nil
5665
beachline = Beachline()
@@ -74,6 +83,9 @@ public class FortuneSweep {
7483
/// 1. Pop an event from the event queue
7584
/// 2. Check the event type and process the event appropriately
7685
private func step() {
86+
currentStep += 1
87+
logger?.log("Step: \(currentStep)", level: .info)
88+
7789
if let event = eventQueue.pop() {
7890
switch event.kind {
7991
case .site:
@@ -88,6 +100,8 @@ public class FortuneSweep {
88100
/// Processes **Site event** and performs all the necessary actions
89101
/// - Parameter event: **Site Event** to process
90102
private func processSiteEvent(_ event: Event) {
103+
logger?.log("Site Event: \(event.point)", level: .info)
104+
91105
/// #Step 1:
92106
/// Update **Sweepline** position
93107
sweepLineY = event.point.y
@@ -100,12 +114,12 @@ public class FortuneSweep {
100114
/// Case 1: (Always present once)
101115
/// Beachline is empty. Create beachline root Arc and return
102116
if beachline.isEmpty {
117+
logger?.log("Site Event first occurence. Root arc inserted for Site: \(event.point)", level: .info)
103118
let root = beachline.insertRootArc(point: event.point)
104119
firstSiteY = event.point.y
105120

106-
let padding: Double = 20
121+
let padding: Double = 20 // Arbitrary padding to make sure that container contains clipping rect
107122
container = .rect(from: clipper, with: padding)
108-
// container = clipper
109123

110124
/// Create new **Cell** record in **Voronoi Diagram**
111125
container.expandToContainPoint(event.point)
@@ -121,6 +135,8 @@ public class FortuneSweep {
121135
/// - *y* coordinate will lay somewhere far above the points.
122136
/// We replace *y* with an arbitrary value big enough to cover our case. (`yVal`)
123137
if firstSiteY == sweepLineY {
138+
logger?.log("Site Event degenerate case (Existing Sites share Y coodinate (\(sweepLineY)) with new Site) for Site: \(event.point)", level: .warning)
139+
124140
container.expandToContainPoint(event.point)
125141
let yVal: Double = -1000000//.leastNormalMagnitude
126142
let arc = beachline.handleSpecialArcInsertionCase(event.point)
@@ -137,7 +153,7 @@ public class FortuneSweep {
137153
arc.leftHalfEdge = diagram.createHalfEdge(arc.cell!)
138154
arc.leftHalfEdge?.origin = p
139155
makeTwins(prev.rightHalfEdge, arc.leftHalfEdge)
140-
156+
141157
/// There is no sense to check for circle event when we encounter degenerate case because all the sites are colinear
142158
return
143159
}
@@ -156,6 +172,8 @@ public class FortuneSweep {
156172
container.expandToContainPoint(event.point)
157173
diagram.createCell(newArc)
158174

175+
176+
159177
/// #Step 3:
160178
/// If the arc we broke has circle event, than this event is false-alarm and has to be removed
161179
removeCircleEvent(newArc.prev)
@@ -212,6 +230,8 @@ public class FortuneSweep {
212230

213231
prev.rightHalfEdge = lTwin
214232
next.leftHalfEdge = rTwin
233+
234+
logger?.log("Site Event degenerate case (Breapoint has the same X coordinate as a Site: \(event.point)", level: .warning)
215235
} else {
216236
/// Regular and most likely case. Here we break the arc, create **HalfEdge** records and set proper pointers between them
217237
next.cell = prev.cell
@@ -282,6 +302,8 @@ public class FortuneSweep {
282302
/// Processes circle event and performs all the necessary actions
283303
/// - Parameter event: **Circle Event**
284304
private func processCircleEvent(_ event: Event) {
305+
logger?.log("Circle Event: \(event.point)", level: .info)
306+
285307
guard let arc = event.arc,
286308
let left = arc.prev,
287309
let right = arc.next
@@ -327,6 +349,8 @@ public class FortuneSweep {
327349
/// - arc: **Beachline** arc to add event
328350
/// - circle: Circle represented by three points
329351
private func createCircleEvent(_ arc: Arc) {
352+
logger?.log("Create Circle Event for Arc: \(arc.point!)", level: .info)
353+
330354
let left = arc.prev
331355
let right = arc.next
332356
guard let circle = checkCircleEvent(left: left, mid: arc, right: right) else {
@@ -356,6 +380,8 @@ public class FortuneSweep {
356380

357381
eventQueue.removeAll(event)
358382
arc.event = nil
383+
384+
logger?.log("Remove Circle Event for Arc: \(arc.point!)", level: .info)
359385
}
360386

361387

@@ -364,9 +390,7 @@ public class FortuneSweep {
364390
/// 2. Complete incomplete cells
365391
/// 3. Clip cells to clipping rectangle
366392
private func terminate() {
367-
// if diagram.cells.count == 1 {
368-
// return
369-
// }
393+
logger?.log("Event Queue is empty. Diagram bounding started.", level: .info)
370394

371395
// Step 1:
372396
// Bound incomplete arcs
@@ -404,6 +428,8 @@ public class FortuneSweep {
404428
// Clip cells
405429
clipCell(cell, clippingRect: clipper)
406430
}
431+
432+
logger?.log("Done!", level: .info)
407433
}
408434

409435
/// Some of the cells will not be completed (Are not looped linked list of half-edges)
@@ -502,7 +528,8 @@ public class FortuneSweep {
502528
var finish = false
503529
while !finish {
504530
guard let segmentToClip = he?.toSegment() else {
505-
fatalError("[FATAL ERROR]: Cannot create segment from the `HalfEdge`!")
531+
logger?.log("Fatal Error! Malformed Half-Edge!", level: .critical)
532+
fatalError()
506533
}
507534

508535
let (isOriginClipped, isDestinationClipped, segment) = lb_clip(segmentToClip, clipper: clippingRect.toClipper())
@@ -679,10 +706,10 @@ extension Site {
679706

680707
extension Vector2D {
681708
var normal: Vector2D {
682-
return Vector2D(dx: -dy, dy: dx)
709+
Vector2D(dx: -dy, dy: dx)
683710
}
684711

685712
var point: Site {
686-
return Site(x: dx, y: dy)
713+
Site(x: dx, y: dy)
687714
}
688715
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// Logging.swift
3+
// Voronoi
4+
//
5+
// Created by Oleksandr Glagoliev on 28.03.2020.
6+
// Copyright © 2020 Oleksandr Glagoliev. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
12+
/// <#Description#>
13+
public enum FortuneSweppLogLevel {
14+
case info
15+
case warning
16+
case error
17+
case critical
18+
}
19+
20+
21+
public protocol FortuneSweepLogging {
22+
23+
/// Depending on implemntation prints/saves log messages
24+
/// - Parameters:
25+
/// - text: Log message
26+
/// - level: Log level
27+
func log(_ message: String, level: FortuneSweppLogLevel)
28+
}

Sources/FortunesAlgorithm/Debug.swift renamed to Sources/FortunesAlgorithm/FortuneSweepProcessVisualizing.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
import Foundation
2626

27-
public protocol VoronoiDebugging: class {
27+
public protocol FortuneSweepProcessVisualizing: class {
2828
var notVisitedSites: [Site] { get set }
2929
var visitedSites: [Site] { get set }
3030
var sweeplineY: Double { get set }
@@ -39,8 +39,7 @@ public protocol VoronoiDebugging: class {
3939
rBound: Double
4040
)
4141
] { get set }
42-
var box: Rectangle? { get set }
43-
var potentialEdges: [LineSegment] { get set }
42+
var clipper: Rectangle? { get set }
4443
var numSteps: Int? { get set }
4544
var curStep: Int { get set }
4645
}

Sources/FortunesAlgorithm/Geometry/Site.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ public struct Site {
3636
}
3737
}
3838

39+
extension Site: CustomStringConvertible {
40+
public var description: String {
41+
return "(x: \(x), y: \(y))"
42+
}
43+
}
44+
3945
extension Site: Hashable {
4046
public static func == (lhs: Site, rhs: Site) -> Bool {
4147
lhs.x == rhs.x

0 commit comments

Comments
 (0)