Skip to content

Commit 269fc68

Browse files
docs: update vectors readme
1 parent 6c3676e commit 269fc68

File tree

1 file changed

+135
-101
lines changed

1 file changed

+135
-101
lines changed

doc/vectors.md

Lines changed: 135 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ additional features are implemented (for boolean vectors obviously only a
1515
reduced subset makes sense).
1616

1717
The generated structs are all zero-size, i.e. they're merely namespaces exposing
18-
size & type-specific type aliases, constants and operations. The vectors
18+
size & type-specific type aliases, constants and functions. The vectors
1919
themselves are always pre-configured versions of Zig's built-in `@Vector` type,
2020
which depending on target platform is SIMD capable/optimized.
2121

@@ -26,115 +26,149 @@ which depending on target platform is SIMD capable/optimized.
2626
- `uvec2` / `uvec3` / `uvec4` - `u32` based
2727
- `bvec2` / `bvec3` / `bvec4` - `bool` vectors
2828

29-
### Vector operations
29+
### Vector creation
3030

31-
Type generics used:
31+
All vector type defined expose the following constants:
3232

3333
- `B`: Boolean vector type of size `N`
3434
- `N`: vector size
3535
- `T`: Vector component type (e.g. `f32`)
3636
- `V`: Vector type (e.g. `@Vector(N, T)`)
3737

38-
| Op | Sizes | Types |
39-
| ------------------------------------------------ | ----- | ----------- |
40-
| `abs(a: V) V` | all | float / int |
41-
| `acos(a: V) V` | all | float |
42-
| `allEqDelta(a: V, b: V, eps: T) bool` | all | float / int |
43-
| `angleBetween(a: V, b: V) T` | all | float |
44-
| `asin(a: V) V` | all | float |
45-
| `argmin(a: V) usize` | all | all |
46-
| `argmax(a: V) usize` | all | all |
47-
| `atan(a: V) V` | all | float |
48-
| `atan2(a: V, b: V) V` | all | float |
49-
| `ceil(a: V) V` | all | float |
50-
| `center(a: V) V` | all | float |
51-
| `centroid(a: []const V) V` | all | all |
52-
| `clamp(a: V, b: V, c: V) V` | all | all |
53-
| `clamp01(a: V) V` | all | float |
54-
| `cos(a: V) V` | all | float |
55-
| `cross(a: V, b: V) V` | 2, 3 | float |
56-
| `direction(a: V, b: V) T` | all | float |
57-
| `distSq(a: V, b: V) T` | all | all |
58-
| `dist(a: V, b: V) T` | all | float |
59-
| `divN(a: V, n: T) V` | all | all |
60-
| `dot(a: V, b: V) T` | all | all |
61-
| `eqDelta(a: V, b: V, eps: T) B` | all | float / int |
62-
| `equal(a: V, b: V) bool` | all | all |
63-
| `exp(a: V) V` | all | float |
64-
| `exp2(a: V) V` | all | float |
65-
| `fill(buf: []V, val: V) void` | all | all |
66-
| `fit(a: V, b: V, c: V, d: V, e: V) V` | all | float |
67-
| `fitN(a: V, b: T, c: T, d: T, e: T) V` | all | float |
68-
| `fitClamped(a: V, b: V, c: V, d: V, e: V) V` | all | float |
69-
| `fitNClamped(a: V, b: T, c: T, d: T, e: T) V` | all | float |
70-
| `fit01(a: V, b: V, c: V) V` | all | float |
71-
| `floor(a: V) V` | all | float |
72-
| `fract(a: V) V` | all | float |
73-
| `fromBVec(a: B) V` | all | all |
74-
| `fromVec(comptime S: type, a: @Vector(N, S)) V` | all | all |
75-
| `fromVec2(a: @Vector(2, T), z: T) V` | 3 | all |
76-
| `fromVec2(a: @Vector(2, T), b: @Vector(2, T)) V` | 4 | all |
77-
| `fromVec2N(a: @Vector(2, T), z: T, w: T) V` | 4 | all |
78-
| `fromVec3(a: @Vector(3, T), w: T) V` | 4 | all |
79-
| `isZero(a: V) bool` | all | all |
80-
| `heading(a: V) T` | 2 | float |
81-
| `invSqrt(a: V) V` | all | float |
82-
| `log(a: V) V` | all | float |
83-
| `log2(a: V) V` | all | float |
84-
| `log10(a: V) V` | all | float |
85-
| `maddN(a: V, n: T, b: V) V` | all | all |
86-
| `mag(a: V) T` | all | float |
87-
| `magSq(a: V) T` | all | all |
88-
| `mean(a: V) T` | all | float |
89-
| `min(a: V, b: V) V` | all | all |
90-
| `minComp(a: V) T` | all | all |
91-
| `mix(a: V, b: V, t: V) V` | all | float |
92-
| `mixN(a: V, b: V, n: T) V` | all | float |
93-
| `max(a: V, b: V) V` | all | all |
94-
| `maxComp(a: V) T` | all | all |
95-
| `mod(a: V, b: V) V` | all | float |
96-
| `modN(a: V, b: T) V` | all | float |
97-
| `mulN(a: V, n: T) V` | all | all |
98-
| `normalize(a: V) V` | all | float |
99-
| `normalizeTo(a: V, n: T) V` | all | float |
100-
| `of(n: T) V` | all | all |
101-
| `orthoNormal(a: V, b: V, c: V) V` | 3 | float |
102-
| `perpendicularCCW(a: V) V` | 2 | float / int |
103-
| `perpendicularCW(a: V) V` | 2 | float / int |
104-
| `pow(a: V, b: V) V` | all | float |
105-
| `powN(a: V, n: T) V` | all | float |
106-
| `product(a: V) T` | all | all |
107-
| `reflect(a: V, n: V) V` | all | float |
108-
| `refract(a: V, n: V, eta: T) V` | all | float |
109-
| `rotate(a: V, theta: T) V` | 2 | float |
110-
| `rotateX(a: V, theta: T) V` | 3 | float |
111-
| `rotateY(a: V, theta: T) V` | 3 | float |
112-
| `rotateZ(a: V, theta: T) V` | 3 | float |
113-
| `round(a: V) V` | all | float |
114-
| `sd(a: V) T` | all | float |
115-
| `sdError(a: V) T` | all | float |
116-
| `select(mask: B, a: V, b: V) V` | all | all |
117-
| `sin(a: V) V` | all | float |
118-
| `smoothStep(e0: V, e1: V, a: V) V` | all | float |
119-
| `sqrt(a: V) V` | all | float |
120-
| `standardize(a: V) V` | all | float |
121-
| `step(edge: V, a: V) V` | all | all |
122-
| `subN(a: V, n: Y) V` | all | all |
123-
| `sum(a: V) T` | all | all |
124-
| `tan(a: V) V` | all | float |
125-
| `trunc(a: V) V` | all | float |
126-
| `variance(a: V) T` | all | float |
127-
| `_not(a: V) V` | all | int / uint |
128-
| `_and(a: V, b: V) V` | all | int / uint |
129-
| `_or(a: V, b: V) V` | all | int / uint |
130-
| `_xor(a: V, b: V) V` | all | int / uint |
131-
| `pow(a: V, n: T) V` | all | all |
38+
```zig
39+
const vec2 = @import("thing").vectors.vec2;
40+
const vec3 = @import("thing").vectors.vec3;
41+
42+
const a: vec2.V = [_]f32{ 1, 2 }; // cast as @Vector(2, f32)
43+
44+
// vector from uniform scalar
45+
const b = vec3.of(1); // [3]f32{ 1, 1, 1 }
46+
47+
// extend vector with pad value
48+
const c = vec3.fromVec(a, 10); // [3]f32{ 1, 2, 10 }
49+
50+
// select sub-vector from larger vec
51+
const d = vec2.fromVec([_]f32{1, 2, 3, 4}, 0); // [2]f32{ 1, 2 }
52+
53+
// coerce to boolean vec
54+
const d = bvec2.fromVec([_]f32{ 1, 0}, false); // [2]bool{ true, false }
55+
56+
// coerce from boolean vec with pad value
57+
const d = vec3.fromVec([_]bool{ true, false }, 10); // [3]f32{ 1, 0, 10 }
58+
```
59+
60+
### Vector operations
61+
62+
| Op | Sizes | Types |
63+
| --------------------------------------------- | ----- | ------------------ |
64+
| `abs(a: V) V` | all | float / int |
65+
| `acos(a: V) V` | all | float |
66+
| `allEqDelta(a: V, b: V, eps: T) bool` | all | float / int / uint |
67+
| `angleBetween(a: V, b: V) T` | all | float |
68+
| `asin(a: V) V` | all | float |
69+
| `argmin(a: V) usize` | all | float / int / uint |
70+
| `argmax(a: V) usize` | all | float / int / uint |
71+
| `atan(a: V) V` | all | float |
72+
| `atan2(a: V, b: V) V` | all | float |
73+
| `ceil(a: V) V` | all | float |
74+
| `center(a: V) V` | all | float |
75+
| `centroid(a: []const V) V` | all | float / int / uint |
76+
| `clamp(a: V, b: V, c: V) V` | all | float / int / uint |
77+
| `clamp01(a: V) V` | all | float |
78+
| `cos(a: V) V` | all | float |
79+
| `cross(a: V, b: V) V` | 2, 3 | float |
80+
| `direction(a: V, b: V) T` | all | float |
81+
| `distSq(a: V, b: V) T` | all | float / int / uint |
82+
| `dist(a: V, b: V) T` | all | float |
83+
| `divN(a: V, n: T) V` | all | float / int / uint |
84+
| `dot(a: V, b: V) T` | all | float / int / uint |
85+
| `eqDelta(a: V, b: V, eps: T) B` | all | float / int |
86+
| `equal(a: V, b: V) bool` | all | all |
87+
| `exp(a: V) V` | all | float |
88+
| `exp2(a: V) V` | all | float |
89+
| `fill(buf: []V, val: V) void` | all | all |
90+
| `fit(a: V, b: V, c: V, d: V, e: V) V` | all | float |
91+
| `fitN(a: V, b: T, c: T, d: T, e: T) V` | all | float |
92+
| `fitClamped(a: V, b: V, c: V, d: V, e: V) V` | all | float |
93+
| `fitNClamped(a: V, b: T, c: T, d: T, e: T) V` | all | float |
94+
| `fit01(a: V, b: V, c: V) V` | all | float |
95+
| `floor(a: V) V` | all | float |
96+
| `fract(a: V) V` | all | float |
97+
| `fromVec(a: V, pad: T) V` | all | all |
98+
| `isZero(a: V) bool` | all | float / int / uint |
99+
| `heading(a: V) T` | 2 | float |
100+
| `invSqrt(a: V) V` | all | float |
101+
| `log(a: V) V` | all | float |
102+
| `log2(a: V) V` | all | float |
103+
| `log10(a: V) V` | all | float |
104+
| `maddN(a: V, n: T, b: V) V` | all | float / int / uint |
105+
| `mag(a: V) T` | all | float |
106+
| `magSq(a: V) T` | all | float / int / uint |
107+
| `mean(a: V) T` | all | float |
108+
| `min(a: V, b: V) V` | all | float / int / uint |
109+
| `minComp(a: V) T` | all | float / int / uint |
110+
| `mix(a: V, b: V, t: V) V` | all | float |
111+
| `mixN(a: V, b: V, n: T) V` | all | float |
112+
| `max(a: V, b: V) V` | all | float / int / uint |
113+
| `maxComp(a: V) T` | all | float / int / uint |
114+
| `mod(a: V, b: V) V` | all | float |
115+
| `modN(a: V, b: T) V` | all | float |
116+
| `mulN(a: V, n: T) V` | all | float / int / uint |
117+
| `normalize(a: V) V` | all | float |
118+
| `normalizeTo(a: V, n: T) V` | all | float |
119+
| `of(n: T) V` | all | float / int / uint |
120+
| `orthoNormal(a: V, b: V, c: V) V` | 3 | float |
121+
| `perpendicularCCW(a: V) V` | 2 | float / int |
122+
| `perpendicularCW(a: V) V` | 2 | float / int |
123+
| `pow(a: V, b: V) V` | all | float |
124+
| `powN(a: V, n: T) V` | all | float |
125+
| `product(a: V) T` | all | float / int / uint |
126+
| `reflect(a: V, n: V) V` | all | float |
127+
| `refract(a: V, n: V, eta: T) V` | all | float |
128+
| `rotate(a: V, theta: T) V` | 2 | float |
129+
| `rotateX(a: V, theta: T) V` | 3 | float |
130+
| `rotateY(a: V, theta: T) V` | 3 | float |
131+
| `rotateZ(a: V, theta: T) V` | 3 | float |
132+
| `round(a: V) V` | all | float |
133+
| `sd(a: V) T` | all | float |
134+
| `sdError(a: V) T` | all | float |
135+
| `select(mask: B, a: V, b: V) V` | all | all |
136+
| `sin(a: V) V` | all | float |
137+
| `smoothStep(e0: V, e1: V, a: V) V` | all | float |
138+
| `sqrt(a: V) V` | all | float |
139+
| `standardize(a: V) V` | all | float |
140+
| `step(edge: V, a: V) V` | all | float / int / uint |
141+
| `subN(a: V, n: Y) V` | all | float / int / uint |
142+
| `sum(a: V) T` | all | float / int / uint |
143+
| `tan(a: V) V` | all | float |
144+
| `trunc(a: V) V` | all | float |
145+
| `variance(a: V) T` | all | float |
146+
| `_not(a: V) V` | all | int / uint |
147+
| `_and(a: V, b: V) V` | all | int / uint |
148+
| `_or(a: V, b: V) V` | all | int / uint |
149+
| `_xor(a: V, b: V) V` | all | int / uint |
150+
| `pow(a: V, n: V) V` | all | float / int / uint |
151+
| `powN(a: V, n: T) V` | all | float / int / uint |
132152

133153
### Vector swizzling
134154

135-
[Named
136-
swizzles](https://github.com/thi-ng/zig-thing/blob/main/src/vectors/swizzle.zig)
137-
are implemented for 2D, 3D and 4D vectors, e.g. `vec3.zyx()`, `vec4.xxzz()` etc.
155+
Due to the loss of struct merging with the release of Zig 0.15.1, the implementation of
156+
named swizzle functions has become too much of a maintenance burden and swizzling is now
157+
handled via a single `swizzle()` function available for all vector types:
158+
159+
```zig
160+
const vec2 = @import("thing").vectors.vec2;
161+
162+
const a = [_]f32{1, 2};
163+
164+
vec2.swizzle(a, "x"); // [1]f32{1}
165+
vec2.swizzle(a, "xy"); // [2]f32{1, 2}
166+
vec2.swizzle(a, "xyx"); // [3]f32{1, 2, 1}
167+
vec2.swizzle(a, "xxyy"); // [4]f32{1, 1, 2, 2}
168+
```
169+
170+
Swizzle ID strings are `comptime`. The following component IDs are supported
171+
(depending on given input vector size): `x`, `y`, `z`, `w`.
138172

139173
### Boolean vector operations
140174

@@ -148,4 +182,4 @@ are implemented for 2D, 3D and 4D vectors, e.g. `vec3.zyx()`, `vec4.xxzz()` etc.
148182

149183
## License
150184

151-
© 2021 - 2022 Karsten Schmidt // Apache License 2.0
185+
© 2021 - 2025 Karsten Schmidt // Apache License 2.0

0 commit comments

Comments
 (0)