1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
open! Import
type t = floatarray
let dimensions = 3
let x0 arr = Array.Floatarray.unsafe_get arr 0
let x1 arr = Array.Floatarray.unsafe_get arr 1
let y0 arr = Array.Floatarray.unsafe_get arr 2
let y1 arr = Array.Floatarray.unsafe_get arr 3
let z0 arr = Array.Floatarray.unsafe_get arr 4
let z1 arr = Array.Floatarray.unsafe_get arr 5
let pp_float = Format.pp_print_float
let pp ppf arr =
let triple pp1 pp2 pp3 = Fmt.(parens (triple pp1 pp2 pp3)) in
let v = ((x0 arr, x1 arr), (y0 arr, y1 arr), (z0 arr, z1 arr)) in
triple
Fmt.(pair pp_float pp_float)
Fmt.(pair pp_float pp_float)
Fmt.(pair pp_float pp_float)
ppf v
let compare_dim i arr arr' =
match i with
| 0 -> Float.compare (x0 arr) (x0 arr')
| 1 -> Float.compare (y0 arr) (y0 arr')
| 2 -> Float.compare (z0 arr) (z0 arr')
| n ->
invalid_arg ("Only three dimensions and you accessed " ^ string_of_int n)
let coords arr =
( Array.Floatarray.unsafe_get arr 0,
Array.Floatarray.unsafe_get arr 1,
Array.Floatarray.unsafe_get arr 2,
Array.Floatarray.unsafe_get arr 3,
Array.Floatarray.unsafe_get arr 4,
Array.Floatarray.unsafe_get arr 5 )
let v ~x0 ~y0 ~z0 ~x1 ~y1 ~z1 =
if x0 > x1 then invalid_arg "x0 should be less than or equal to x1";
if y0 > y1 then invalid_arg "y0 should be less than or equal to y1";
if z0 > z1 then invalid_arg "z0 should be less than or equal to z1";
let arr = Array.Floatarray.create 6 in
Array.Floatarray.unsafe_set arr 0 x0;
Array.Floatarray.unsafe_set arr 1 x1;
Array.Floatarray.unsafe_set arr 2 y0;
Array.Floatarray.unsafe_set arr 3 y1;
Array.Floatarray.unsafe_set arr 4 z0;
Array.Floatarray.unsafe_set arr 5 z1;
arr
let ranges_intersect a b a' b' =
Float.compare a' b <= 0 && Float.compare a b' <= 0
let intersects arr arr' =
let x0, x0' = (x0 arr, x0 arr') in
let x1, x1' = (x1 arr, x1 arr') in
let y0, y0' = (y0 arr, y0 arr') in
let y1, y1' = (y1 arr, y1 arr') in
let z0, z0' = (z0 arr, z0 arr') in
let z1, z1' = (z1 arr, z1 arr') in
ranges_intersect x0 x1 x0' x1'
&& ranges_intersect y0 y1 y0' y1'
&& ranges_intersect z0 z1 z0' z1'
let merge arr arr' =
let x0, x0' = (x0 arr, x0 arr') in
let x1, x1' = (x1 arr, x1 arr') in
let y0, y0' = (y0 arr, y0 arr') in
let y1, y1' = (y1 arr, y1 arr') in
let z0, z0' = (z0 arr, z0 arr') in
let z1, z1' = (z1 arr, z1 arr') in
let arr = Array.Floatarray.create 6 in
Array.Floatarray.unsafe_set arr 0 (min x0 x0');
Array.Floatarray.unsafe_set arr 1 (max x1 x1');
Array.Floatarray.unsafe_set arr 2 (min y0 y0');
Array.Floatarray.unsafe_set arr 3 (max y1 y1');
Array.Floatarray.unsafe_set arr 4 (min z0 z0');
Array.Floatarray.unsafe_set arr 5 (max z1 z1');
arr
let merge_many t =
let rec loop acc = function [] -> acc | e :: es -> loop (merge e acc) es in
match t with
| [] -> raise (Invalid_argument "can't zero envelopes")
| e :: es -> loop e es
let area arr =
let x0, x1, y0, y1, z0, z1 =
(x0 arr, x1 arr, y0 arr, y1 arr, z0 arr, z1 arr)
in
Float.abs (x1 -. x0) *. Float.abs (y1 -. y0) *. Float.abs (z1 -. z0)
let contains arr arr' =
let x0, x0' = (x0 arr, x0 arr') in
let x1, x1' = (x1 arr, x1 arr') in
let y0, y0' = (y0 arr, y0 arr') in
let y1, y1' = (y1 arr, y1 arr') in
let z0, z0' = (z0 arr, z0 arr') in
let z1, z1' = (z1 arr, z1 arr') in
Float.compare x0 x0' <= 0
&& Float.compare x1 x1' >= 0
&& Float.compare y0 y0' <= 0
&& Float.compare y1 y1' >= 0
&& Float.compare z0 z0' <= 0
&& Float.compare z1 z1' >= 0
let empty =
let arr = Array.Floatarray.create 6 in
Array.Floatarray.unsafe_set arr 0 0.;
Array.Floatarray.unsafe_set arr 1 0.;
Array.Floatarray.unsafe_set arr 2 0.;
Array.Floatarray.unsafe_set arr 3 0.;
Array.Floatarray.unsafe_set arr 4 0.;
Array.Floatarray.unsafe_set arr 5 0.;
arr