could be sped up by doing math to find intesections points of the borders but that sounds boring
58 lines
1.4 KiB
OCaml
58 lines
1.4 KiB
OCaml
open Containers
|
|
|
|
type t =
|
|
{ x : int
|
|
; y : int
|
|
}
|
|
[@@deriving eq, ord, hash]
|
|
|
|
let pp (fmt : Format.formatter) v = Format.fprintf fmt "(%i, %i)" v.x v.y
|
|
let show v = Format.asprintf "%a" pp v
|
|
let origin = { x = 0; y = 0 }
|
|
let up = { x = 0; y = -1 }
|
|
let down = { x = 0; y = 1 }
|
|
let right = { x = 1; y = 0 }
|
|
let left = { x = -1; y = 0 }
|
|
let directions = [ up; down; left; right ]
|
|
let of_tuple (x, y) = { x; y }
|
|
let to_tuple { x; y } = x, y
|
|
let ( + ) a b = { x = a.x + b.x; y = a.y + b.y }
|
|
let ( - ) a b = { x = a.x - b.x; y = a.y - b.y }
|
|
let ( = ) = equal
|
|
let abs a = Int.{ x = abs a.x; y = abs a.y }
|
|
|
|
let iter_region a b callback =
|
|
for y = min a.y b.y to max a.y b.y do
|
|
for x = min a.x b.x to max a.x b.x do
|
|
callback { x; y }
|
|
done
|
|
done
|
|
;;
|
|
|
|
let fold_region a b callback init =
|
|
let acc = ref init in
|
|
iter_region a b (fun pos -> acc := callback !acc pos);
|
|
!acc
|
|
;;
|
|
|
|
let bounds padding points =
|
|
let lx, hx, ly, hy =
|
|
points
|
|
|> List.fold_left
|
|
(fun (lx, hx, ly, hy) { x; y } ->
|
|
let lx = min lx x in
|
|
let hx = max hx x in
|
|
let ly = min ly y in
|
|
let hy = max hy y in
|
|
lx, hx, ly, hy)
|
|
(Int.max_int, 0, Int.max_int, 0)
|
|
in
|
|
let lx = Int.(lx - padding) in
|
|
let hx = Int.(hx + padding) in
|
|
let ly = Int.(ly - padding) in
|
|
let hy = Int.(hy + padding) in
|
|
of_tuple (lx, ly), of_tuple (hx, hy)
|
|
;;
|
|
|
|
let in_bounds l h p = p.x >= l.x && p.x <= h.x && p.y >= l.y && p.y <= h.y
|