Skip to content

Commit b07f13f

Browse files
committed
solved rounding errors
1 parent 2b63373 commit b07f13f

File tree

7 files changed

+59
-56
lines changed

7 files changed

+59
-56
lines changed
Binary file not shown.

HW.xcodeproj/xcuserdata/adriannenu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626
ignoreCount = "0"
2727
continueAfterRunningActions = "No"
2828
filePath = "HW/Utils.swift"
29-
timestampString = "539736603.915446"
29+
timestampString = "539741299.7905951"
3030
startingColumnNumber = "9223372036854775807"
3131
endingColumnNumber = "9223372036854775807"
32-
startingLineNumber = "57"
33-
endingLineNumber = "57"
32+
startingLineNumber = "59"
33+
endingLineNumber = "59"
3434
landmarkName = "latLonToTile(coord:)"
3535
landmarkType = "7">
3636
</BreakpointContent>
@@ -202,7 +202,7 @@
202202
ignoreCount = "0"
203203
continueAfterRunningActions = "No"
204204
filePath = "HW/API.swift"
205-
timestampString = "539738325.9896801"
205+
timestampString = "539741299.792313"
206206
startingColumnNumber = "9223372036854775807"
207207
endingColumnNumber = "9223372036854775807"
208208
startingLineNumber = "43"

HW/Constants.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ import Foundation
1111
class Constants {
1212
static let TILE_RANGE = 3
1313
static let DEBUG = true
14+
static let DEBUG_LAST = (53.45878, -2.22999)
1415
}

HW/LocationMaster.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import CoreLocation
1111

1212
class LocationMaster: NSObject, CLLocationManagerDelegate {
1313
private let locationManager = CLLocationManager()
14-
private static var last: Vector2 = Vector2.zero
15-
static var debugLast: Vector2 = Vector2(53.45878, -2.22999)
14+
private static var last: (Double, Double) = (0.0, 0.0)
1615

1716
override init() {
1817
super.init()
@@ -31,13 +30,13 @@ class LocationMaster: NSObject, CLLocationManagerDelegate {
3130
}
3231

3332
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
34-
LocationMaster.last = Vector2(Float(manager.location!.coordinate.latitude), Float(manager.location!.coordinate.longitude))
33+
LocationMaster.last = (manager.location!.coordinate.latitude, manager.location!.coordinate.longitude)
3534

3635
}
3736

38-
static func getLast() -> Vector2 {
37+
static func getLast() -> (Double, Double) {
3938
if Constants.DEBUG {
40-
return LocationMaster.debugLast
39+
return Constants.DEBUG_LAST
4140
}
4241
return LocationMaster.last
4342
}

HW/MapTile.swift

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,27 @@ import SwiftyJSON
1313

1414
class MapTile {
1515
var data: SwiftyJSON.JSON = JSON.null
16-
let tileKey: Vector2
17-
let position: Vector2
18-
let latLon: Vector2
19-
let latLonInMeters: Vector2
16+
let tileKey: (Int, Int)
17+
let position: (Int, Int)
18+
let latLon: (Double, Double)
19+
let latLonInMeters: (Double, Double)
2020
var node: SCNNode!
2121
var lines: [(Double, Double)] = []
2222

23-
init(tileKey: Vector2, mapNode: SCNNode, primordialTile: Vector2) {
23+
init(tileKey: (Int, Int), mapNode: SCNNode, primordialTile: (Int, Int)) {
2424
self.tileKey = tileKey
25-
self.position = Vector2(tileKey.x - primordialTile.x, primordialTile.y - tileKey.y) * 611
25+
self.position = ((tileKey.0 - primordialTile.0) * 611, (primordialTile.1 - tileKey.1) * 611)
2626
self.latLon = Utils.tileToLatLon(tile: tileKey)
2727
self.latLonInMeters = Utils.latLonToMeters(coord: self.latLon)
2828

2929
Logging.info(data: "TILE \(tileKey) @ \(self.position)")
3030

3131
node = SCNNode()
32-
node.position = SCNVector3(x: position.x, y: position.y, z: 0)
32+
node.position = SCNVector3(x: Float(position.0), y: Float(position.1), z: 0)
3333
mapNode.addChildNode(node)
3434

3535

36-
API.get(endpoint: "http://tile.mapzen.com/mapzen/vector/v1/all/16/\(Int(tileKey.x))/\(Int(tileKey.y)).json?api_key=mapzen-YMzZVyX", callback: { (data) in
36+
API.get(endpoint: "http://tile.mapzen.com/mapzen/vector/v1/all/16/\(Int(tileKey.0))/\(Int(tileKey.1)).json?api_key=mapzen-YMzZVyX", callback: { (data) in
3737
self.data = data
3838
DispatchQueue.main.async {
3939
self.render()
@@ -86,11 +86,13 @@ class MapTile {
8686
for feature in data[field]["features"].array! {
8787
if feature["geometry"]["type"].string! == "LineString" {
8888
let coords = feature["geometry"]["coordinates"].array!
89-
let thePoint = Utils.latLonToMeters(coord: Vector2(x: coords[0].array![1].float!, y: coords[0].array![0].float!)) - latLonInMeters
90-
context.move(to: CGPoint(x: Double(abs(thePoint.x)), y: Double(abs(thePoint.y))))
89+
let pointLatLon = Utils.latLonToMeters(coord: (coords[0].array![1].double!, coords[0].array![0].double!))
90+
let thePoint = (pointLatLon.0 - latLonInMeters.0, pointLatLon.1 - latLonInMeters.1)
91+
context.move(to: CGPoint(x: abs(thePoint.0), y: abs(thePoint.1)))
9192
for point in coords {
92-
let thePointInMeters = Utils.latLonToMeters(coord: Vector2(x: point.array![1].float!, y: point.array![0].float!)) - latLonInMeters
93-
let thePoint = CGPoint(x: Double(abs(thePointInMeters.x)), y: Double(abs(thePointInMeters.y)))
93+
let pointLatLon = Utils.latLonToMeters(coord: (point.array![1].double!, point.array![0].double!))
94+
let thePointInMeters = (pointLatLon.0 - latLonInMeters.0, pointLatLon.1 - latLonInMeters.1)
95+
let thePoint = CGPoint(x: abs(thePointInMeters.0), y: abs(thePointInMeters.1))
9496
context.addLine(to: thePoint)
9597
context.move(to: thePoint)
9698
}

HW/Utils.swift

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,49 +29,47 @@ class Utils {
2929
return Vector2(x: json[0].float!, y: json[1].float!)
3030
}
3131

32-
static func distanceInMetersBetween(latLon1: Vector2, latLon2: Vector2) -> Vector2 {
33-
return latLonToMeters(coord: latLon1) - latLonToMeters(coord: latLon2)
32+
static func distanceInMetersBetween(latLon1: (Double, Double), latLon2: (Double, Double)) -> (Double, Double) {
33+
let m1 = latLonToMeters(coord: latLon1)
34+
let m2 = latLonToMeters(coord: latLon2)
35+
return (m1.0 - m2.0, m1.1 - m2.1)
3436
}
3537

36-
static func tileToMeters(tile: Vector2) -> Vector2 {
38+
static func tileToMeters(tile: (Int, Int)) -> (Double, Double) {
3739
return latLonToMeters(coord: tileToLatLon(tile: tile))
3840
}
3941

40-
static func latLonToMeters(coord: Vector2) -> Vector2 {
41-
let earthRadius: Float = 6378137
42-
let originShift = (2 * Float.pi * earthRadius / 2)
42+
static func latLonToMeters(coord: (Double, Double)) -> (Double, Double) {
43+
let earthRadius: Double = 6378137
44+
let originShift = (2 * Double.pi * earthRadius / 2)
4345

44-
let x = (coord.y * originShift / 180.0)
45-
var y = (log(tan((90 + coord.x) * Float.pi / 360)) / (Float.pi / 180))
46+
let x = (coord.1 * originShift / 180.0)
47+
var y = (log(tan((90 + coord.0) * Double.pi / 360)) / (Double.pi / 180))
4648
y = (y * originShift / 180.0)
4749

48-
return Vector2(abs(x), abs(y))
50+
return (abs(x), abs(y))
4951
}
5052

51-
static func latLonToTile(coord: Vector2) -> Vector2 {
52-
let zoom: Float = pow(2, 16);
53+
static func latLonToTile(coord: (Double, Double)) -> (Int, Int) {
54+
let zoom: Double = pow(2, 16);
5355

54-
let x = Float(floor(((coord.y + 180) / 360) * zoom))
55-
let y = Float(floor((1 - log(tan(deg2rad(angle: coord.x)) + 1 / cos(deg2rad(angle: coord.x))) / Float.pi)/2 * zoom))
56-
return Vector2(x, y)
56+
let x = floor(((coord.1 + 180) / 360) * zoom)
57+
let y = floor((1 - log(tan(deg2rad(angle: coord.0)) + 1 / cos(deg2rad(angle: coord.0))) / Double.pi)/2 * zoom)
58+
return (Int(x), Int(y))
5759
}
5860

59-
static func tileToLatLon(tile: Vector2) -> Vector2 {
60-
let n: Float = pow (2, 16)
61-
let lon_deg = (tile.x / n * 360.0 - 180.0)
62-
let lat_deg = rad2deg (angle: atan (sinh (Float.pi * (1 - 2 * tile.y / n))))
63-
return Vector2(lat_deg, lon_deg)
61+
static func tileToLatLon(tile: (Int, Int)) -> (Double, Double) {
62+
let n: Double = pow (2, 16)
63+
let lon_deg = (Double(tile.0) / n * 360.0 - 180.0)
64+
let lat_deg = rad2deg (angle: atan (sinh (Double.pi * (1 - 2 * Double(tile.1) / n))))
65+
return (lat_deg, lon_deg)
6466
}
6567

66-
static func rad2deg(angle: Float) -> Float {
67-
return angle * (180.0 / Float.pi)
68+
static func rad2deg(angle: Double) -> Double {
69+
return angle * (180.0 / Double.pi)
6870
}
6971

70-
static func deg2rad(angle: Float) -> Float {
71-
return (Float.pi / 180) * angle;
72-
}
73-
74-
static func timestamp() -> Int64 {
75-
return Int64(NSDate().timeIntervalSince1970)
72+
static func deg2rad(angle: Double) -> Double {
73+
return (Double.pi / 180) * angle;
7674
}
7775
}

HW/World3D.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import CoreMotion
1515
import SceneKit
1616

1717
class World3D: UIViewController {
18-
static var mapTiles = [Vector2: MapTile]()
18+
static var mapTiles = [String: MapTile]()
1919

20-
private var primordialTile: Vector2!
20+
private var primordialTile: (Int, Int)!
2121
private var playerNode: SCNNode!
2222
private var locationMaster: LocationMaster!
2323
private var locationTimer: Timer!
@@ -54,16 +54,19 @@ class World3D: UIViewController {
5454

5555
for i in -Constants.TILE_RANGE...Constants.TILE_RANGE {
5656
for j in -Constants.TILE_RANGE...Constants.TILE_RANGE {
57-
let tileKey = currentTile + Vector2(Float(i), Float(j))
58-
if World3D.mapTiles[tileKey] == nil {
59-
World3D.mapTiles[tileKey] = MapTile(tileKey: tileKey, mapNode: sceneView.scene!.rootNode, primordialTile: primordialTile)
57+
let tileKey = (currentTile.0 + i, currentTile.1 + j)
58+
if World3D.mapTiles["\(tileKey.0)\(tileKey.1)"] == nil {
59+
World3D.mapTiles["\(tileKey.0)\(tileKey.1)"] =
60+
MapTile(tileKey: tileKey, mapNode: sceneView.scene!.rootNode, primordialTile: primordialTile)
6061
}
6162
}
6263
}
6364

64-
let playerOffsetInsideTile = Utils.distanceInMetersBetween(latLon1: Utils.tileToLatLon(tile: currentTile), latLon2: playerLatLon) - Vector2(611, 611)/2
65-
let playerPosition = World3D.mapTiles[currentTile]!.position + playerOffsetInsideTile * Vector2(1, -1)
66-
self.playerNode.position = SCNVector3(x: playerPosition.x, y: playerPosition.y, z: 16)
65+
let playerOffset = Utils.distanceInMetersBetween(latLon1: Utils.tileToLatLon(tile: currentTile), latLon2: playerLatLon)
66+
let playerOffsetInsideTile = (playerOffset.0 - 611/2, playerOffset.1 - 611/2)
67+
let playerPosition = (Double(World3D.mapTiles["\(currentTile.0)\(currentTile.1)"]!.position.0) + playerOffsetInsideTile.0,
68+
(Double(World3D.mapTiles["\(currentTile.0)\(currentTile.1)"]!.position.1) + playerOffsetInsideTile.1) * -1)
69+
self.playerNode.position = SCNVector3(x: Float(playerPosition.0), y: Float(playerPosition.1), z: 16)
6770

6871
Logging.info(data: "Player @ P\(playerPosition) OIT\(playerOffsetInsideTile)")
6972
}

0 commit comments

Comments
 (0)