commit 53e377cabdc3856c9b5fbf851b4b0e64bc8b5dde
parent 56f070ceeeb37d6278b36f60349b3ce159543c4c
Author: Daniel Barlow <dan@telent.net>
Date: Sun, 8 Jun 2025 19:10:11 +0100
widen map obunds so that rotation works
...without showing missing white bits in the corners when moving
diagonally
Diffstat:
1 file changed, 30 insertions(+), 25 deletions(-)
diff --git a/pkgs/maps/main.fnl b/pkgs/maps/main.fnl
@@ -77,13 +77,32 @@ label.readout {
(fn map-bounds-tile [tile-x tile-y]
- (let [min-tile-x (math.floor (- tile-x (/ viewport-width tile-size 2)))
- max-tile-x (math.floor (+ tile-x (/ viewport-width tile-size 2)))
- min-tile-y (math.floor (- tile-y (/ viewport-height tile-size 2)))
- max-tile-y (math.floor (+ tile-y (/ viewport-height tile-size 2)))
+ ;; we fetch enough tiles around the current location that the screen
+ ;; can be freely rotated without needing to fetch more.
+
+ ;; when facing north, we have e.g.
+ ;; 720 width is 2.8 * 256 pixel tiles
+ ;; 800 height is 3.125 tiles
+ ;;
+ ;; however:
+ ;; - when the map is rotated 90 degrees we instead have
+ ;; 3.125 tiles horizontally and 2.8 vertically
+ ;; - at e.g a 45 degree angle ... something else?
+ ;;
+ ;; the furthest points visible from the centre of the screen are the
+ ;; corners. So, we draw a circle about the centre which goes
+ ;; through those points. To ensure we have enough tiles to fill the
+ ;; screen at any angle, we fetch every tile that's (partly
+ ;; or entirely) inside that circle
+
+ (let [radius (/ (math.sqrt (+ (^ viewport-width 2) (^ viewport-height 2)))
+ tile-size 2)
+ min-tile-x (math.floor (- tile-x radius))
+ max-tile-x (math.floor (+ tile-x radius))
+ min-tile-y (math.floor (- tile-y radius))
+ max-tile-y (math.floor (+ tile-y radius))
num-tiles-x (+ 1 (- max-tile-x min-tile-x))
num-tiles-y (+ 1 (- max-tile-y min-tile-y))]
-
{
:min { :x min-tile-x :y min-tile-y }
:max { :x max-tile-x :y max-tile-y }
@@ -95,28 +114,15 @@ label.readout {
}
}))
-;; 720 width is 2.8 * 256 pixel tiles
-;; 800 height is 3.125 tiles
+;; diagonal radius is 538 pixels, 2.1 tiles
(let [bounds (map-bounds-tile 65539.5 45014.5)]
- ;; tile 65539, 45014 is centred on screen. left of it there is space
- ;; for one tile and right of it likewise.
- ;; vertical space for other tiles is (/ (- viewport-height tile-size) 256)
- ;; => 2.125 tiles, shared equally to top and bottom therefore
- ;; 1.0625 tiles above and 1.0625 tiles below
-
- (expect= bounds.min {:x 65538 :y 45012})
- (expect= bounds.max {:x 65540 :y 45016}))
+ (expect= bounds.min {:x 65537 :y 45012})
+ (expect= bounds.max {:x 65541 :y 45016}))
(let [bounds (map-bounds-tile 65539.0 45014.0)]
- ;; top left corner of tile 65539, 45014 is centred on screen.
- ;; to its left there are 360 pixels, so we need two tiles
- ;; to its right there are 104 pixels, so one tile
- ;; above there are 400 pixels: two tiles
- ;; below are 144 pixels: one tile
-
- (expect= bounds.min {:x 65537 :y 45012})
- (expect= bounds.max {:x 65540 :y 45015})
+ (expect= bounds.min {:x 65536 :y 45011})
+ (expect= bounds.max {:x 65541 :y 45016})
)
(fn map-bounds [lat lon zoom]
@@ -260,8 +266,7 @@ label.readout {
(g:set_source_surface map-surface (- offset-x) (- offset-y))
(g:set_operator cairo.Operator.SOURCE)
- (g:rectangle 0 0 viewport-width viewport-height)
- (g:fill)))
+ (g:paint)))