widen map obunds so that rotation works

...without showing missing white bits in the corners when moving
diagonally
This commit is contained in:
Daniel Barlow 2025-06-08 19:10:11 +01:00
parent 56f070ceee
commit 53e377cabd

View File

@ -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)))