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
use num::{self, Float, NumCast};
use std::ops::{Add, Sub, Mul};
pub fn cast<T: NumCast, U: NumCast>(x: T) -> U {
num::traits::cast(x).unwrap()
}
pub fn pow4<T: Float>(x: T) -> T { x * x * x * x }
pub type Point2<T> = [T; 2];
pub type Point3<T> = [T; 3];
pub type Point4<T> = [T; 4];
pub type Vector2<T> = [T; 2];
pub type Vector3<T> = [T; 3];
pub type Vector4<T> = [T; 4];
pub fn map2<T: Copy, U, F: Fn(T) -> U>(a: Vector2<T>, f: F) -> Vector2<U> {
let (ax, ay) = (a[0], a[1]);
[f(ax), f(ay)]
}
pub fn map3<T: Copy, U, F: Fn(T) -> U>(a: Vector3<T>, f: F) -> Vector3<U> {
let (ax, ay, az) = (a[0], a[1], a[2]);
[f(ax), f(ay), f(az)]
}
pub fn map4<T: Copy, U, F: Fn(T) -> U>(a: Vector4<T>, f: F) -> Vector4<U> {
let (ax, ay, az, aw) = (a[0], a[1], a[2], a[3]);
[f(ax), f(ay), f(az), f(aw)]
}
pub fn zip_with2<T: Copy, U: Copy, V, F: Fn(T, U) -> V>(a: Vector2<T>, b: Vector2<U>, f: F) -> Vector2<V> {
let (ax, ay) = (a[0], a[1]);
let (bx, by) = (b[0], b[1]);
[f(ax, bx), f(ay, by)]
}
pub fn zip_with3<T: Copy, U: Copy, V, F: Fn(T, U) -> V>(a: Vector3<T>, b: Vector3<U>, f: F) -> Vector3<V> {
let (ax, ay, az) = (a[0], a[1], a[2]);
let (bx, by, bz) = (b[0], b[1], b[2]);
[f(ax, bx), f(ay, by), f(az, bz)]
}
pub fn zip_with4<T: Copy, U: Copy, V, F: Fn(T, U) -> V>(a: Vector4<T>, b: Vector4<U>, f: F) -> Vector4<V> {
let (ax, ay, az, aw) = (a[0], a[1], a[2], a[3]);
let (bx, by, bz, bw) = (b[0], b[1], b[2], b[3]);
[f(ax, bx), f(ay, by), f(az, bz), f(aw, bw)]
}
pub fn fold2<T: Copy, F: Fn(T, T) -> T>(a: Vector2<T>, f: F) -> T {
let (ax, ay) = (a[0], a[1]);
f(ax, ay)
}
pub fn fold3<T: Copy, F: Fn(T, T) -> T>(a: Vector3<T>, f: F) -> T {
let (ax, ay, az) = (a[0], a[1], a[2]);
f(f(ax, ay), az)
}
pub fn fold4<T: Copy, F: Fn(T, T) -> T>(a: Vector4<T>, f: F) -> T {
let (ax, ay, az, aw) = (a[0], a[1], a[2], a[3]);
f(f(f(ax, ay), az), aw)
}
pub fn add2<T: Copy + Add<T, Output = T>>(a: Point2<T>, b: Vector2<T>) -> Point2<T> { zip_with2(a, b, Add::add) }
pub fn add3<T: Copy + Add<T, Output = T>>(a: Point3<T>, b: Vector3<T>) -> Point3<T> { zip_with3(a, b, Add::add) }
pub fn add4<T: Copy + Add<T, Output = T>>(a: Point4<T>, b: Vector4<T>) -> Point4<T> { zip_with4(a, b, Add::add) }
pub fn sub2<T: Copy + Sub<T, Output = T>>(a: Point2<T>, b: Point2<T>) -> Vector2<T> { zip_with2(a, b, Sub::sub) }
pub fn sub3<T: Copy + Sub<T, Output = T>>(a: Point3<T>, b: Point3<T>) -> Vector3<T> { zip_with3(a, b, Sub::sub) }
pub fn sub4<T: Copy + Sub<T, Output = T>>(a: Point4<T>, b: Point4<T>) -> Vector4<T> { zip_with4(a, b, Sub::sub) }
pub fn mul2<T: Copy + Mul<T, Output = T> + Copy>(a: Vector2<T>, b: T) -> Vector2<T> { zip_with2(a, const2(b), Mul::mul) }
pub fn mul3<T: Copy + Mul<T, Output = T> + Copy>(a: Vector3<T>, b: T) -> Vector3<T> { zip_with3(a, const3(b), Mul::mul) }
pub fn mul4<T: Copy + Mul<T, Output = T> + Copy>(a: Vector4<T>, b: T) -> Vector4<T> { zip_with4(a, const4(b), Mul::mul) }
pub fn dot2<T: Float>(a: Vector2<T>, b: Vector2<T>) -> T { fold2(zip_with2(a, b, Mul::mul), Add::add) }
pub fn dot3<T: Float>(a: Vector3<T>, b: Vector3<T>) -> T { fold3(zip_with3(a, b, Mul::mul), Add::add) }
pub fn dot4<T: Float>(a: Vector4<T>, b: Vector4<T>) -> T { fold4(zip_with4(a, b, Mul::mul), Add::add) }
pub fn const2<T: Copy>(x: T) -> Vector2<T> { [x, x] }
pub fn const3<T: Copy>(x: T) -> Vector3<T> { [x, x, x] }
pub fn const4<T: Copy>(x: T) -> Vector4<T> { [x, x, x, x] }
pub fn one2<T: Copy + NumCast>() -> Vector2<T> { cast2(const2(1)) }
pub fn one3<T: Copy + NumCast>() -> Vector3<T> { cast3(const3(1)) }
pub fn one4<T: Copy + NumCast>() -> Vector4<T> { cast4(const4(1)) }
pub fn cast2<T: NumCast + Copy, U: NumCast + Copy>(x: Point2<T>) -> Point2<U> { map2(x, cast) }
pub fn cast3<T: NumCast + Copy, U: NumCast + Copy>(x: Point3<T>) -> Point3<U> { map3(x, cast) }
pub fn cast4<T: NumCast + Copy, U: NumCast + Copy>(x: Point4<T>) -> Point4<U> { map4(x, cast) }