This repository has been archived by the owner on Nov 9, 2017. It is now read-only.
/
range.clj
112 lines (94 loc) · 2.46 KB
/
range.clj
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
;; Copyright (c) Zachary Tellman. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.
(ns
^{:skip-wiki true}
cantor.range
(:use [cantor.utils])
(:require [cantor.vector :as vec])
(:import [cantor.vector Vec2 Vec3]))
;;;
(defprotocol Range
(#^vec/Tuple upper [r] "Returns the minima of the range.")
(#^vec/Tuple lower [r] "Returns the maxima of the range.")
(clone [r a b] "Returns a range of the same type with endpoints set to a and b"))
(defn overlap?
"Returns true if the two ranges overlap."
[a b]
(and
(vec/all? <= (upper a) (lower b))
(vec/all? >= (lower a) (upper b))))
(defn intersection
"Returns the intersection of the two ranges, or nil if they don't intersect."
[a b]
(when (overlap? a b)
(clone a
(vec/map* max (upper a) (upper b))
(vec/map* min (lower a) (lower b)))))
(defn union
"Returns the union of the two ranges."
[a b]
(clone a
(vec/map* min (upper a) (upper b))
(vec/map* max (lower a) (lower b))))
(defn inside?
"Returns true if vector 'p' is inside range 'r'."
[r p]
(and (vec/all? <= (upper r) p)
(vec/all? >= (lower r) p)))
(defn size
"Returns the difference between the two extremes of the range."
[r]
(vec/sub (lower r) (upper r)))
;;;
(defrecord Interval [#^double a #^double b]
Range
(upper [r] a)
(lower [r] b)
(clone [_ a b] (Interval. a b))
clojure.lang.IFn
(invoke [_ n]
(condp = n
0 a
1 b)))
(defrecord Box2 [#^Vec2 a #^Vec2 b]
Range
(upper [r] a)
(lower [r] b)
(clone [_ a b] (Box2. a b))
clojure.lang.IFn
(invoke [_ n]
(condp = n
0 a
1 b)))
(defrecord Box3 [#^Vec3 a #^Vec3 b]
Range
(upper [r] a)
(lower [r] b)
(clone [_ a b] (Box3. a b))
clojure.lang.IFn
(invoke [_ n]
(condp = n
0 a
1 b)))
;;;
(defn range?
"Returns true if 'r' is a range."
[r]
(satisfies? Range r))
(defn interval
"Creates a 1-D range."
[a b]
(Interval. a b))
(defn box2
"Creates a 2-D range, or box."
[ul lr]
(Box2. ul lr))
(defn box3
"Creates a 3-D range, or box."
[ul lr]
(Box3. ul lr))