Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: PROJ |
4 | | * Purpose: 3D vector operations for polyhedral projections. |
5 | | * Author: Felix Palmer |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Derived from gl-matrix (MIT License). |
9 | | * |
10 | | * gl-matrix: Copyright (c) 2015-2021, Brandon Jones, Colin MacKenzie IV. |
11 | | * https://github.com/toji/gl-matrix |
12 | | * |
13 | | * Permission is hereby granted, free of charge, to any person obtaining a |
14 | | * copy of this software and associated documentation files (the "Software"), |
15 | | * to deal in the Software without restriction, including without limitation |
16 | | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
17 | | * and/or sell copies of the Software, and to permit persons to whom the |
18 | | * Software is furnished to do so, subject to the following conditions: |
19 | | * |
20 | | * The above copyright notice and this permission notice shall be included |
21 | | * in all copies or substantial portions of the Software. |
22 | | * |
23 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
24 | | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
25 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
26 | | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
27 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
28 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
29 | | * DEALINGS IN THE SOFTWARE. |
30 | | ****************************************************************************/ |
31 | | |
32 | | #ifndef VEC3_H |
33 | | #define VEC3_H |
34 | | |
35 | | #include <cmath> |
36 | | |
37 | | struct Vec3 { |
38 | | double x = 0.0, y = 0.0, z = 0.0; |
39 | | }; |
40 | | |
41 | 389k | inline double vec3_dot(const Vec3 &a, const Vec3 &b) { |
42 | 389k | return a.x * b.x + a.y * b.y + a.z * b.z; |
43 | 389k | } |
44 | | |
45 | 260k | inline Vec3 vec3_cross(const Vec3 &a, const Vec3 &b) { |
46 | 260k | return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, |
47 | 260k | a.x * b.y - a.y * b.x}; |
48 | 260k | } |
49 | | |
50 | 110k | inline double vec3_length(const Vec3 &v) { return std::hypot(v.x, v.y, v.z); } |
51 | | |
52 | 98.0k | inline Vec3 vec3_normalize(const Vec3 &v) { |
53 | 98.0k | double len = vec3_length(v); |
54 | 98.0k | if (len == 0.0) |
55 | 0 | return v; |
56 | 98.0k | return {v.x / len, v.y / len, v.z / len}; |
57 | 98.0k | } |
58 | | |
59 | 49.9k | inline Vec3 vec3_subtract(const Vec3 &a, const Vec3 &b) { |
60 | 49.9k | return {a.x - b.x, a.y - b.y, a.z - b.z}; |
61 | 49.9k | } |
62 | | |
63 | 99.9k | inline Vec3 vec3_add(const Vec3 &a, const Vec3 &b) { |
64 | 99.9k | return {a.x + b.x, a.y + b.y, a.z + b.z}; |
65 | 99.9k | } |
66 | | |
67 | 72.2k | inline Vec3 vec3_scale(const Vec3 &v, double s) { |
68 | 72.2k | return {v.x * s, v.y * s, v.z * s}; |
69 | 72.2k | } |
70 | | |
71 | 55.3k | inline Vec3 vec3_lerp(const Vec3 &a, const Vec3 &b, double t) { |
72 | 55.3k | return {a.x + t * (b.x - a.x), a.y + t * (b.y - a.y), |
73 | 55.3k | a.z + t * (b.z - a.z)}; |
74 | 55.3k | } |
75 | | |
76 | 0 | inline double vec3_angle(const Vec3 &a, const Vec3 &b) { |
77 | 0 | Vec3 A = vec3_scale(a, vec3_length(b)); |
78 | 0 | Vec3 B = vec3_scale(b, vec3_length(a)); |
79 | 0 | return 2.0 * std::atan2(vec3_length(vec3_subtract(A, B)), |
80 | 0 | vec3_length(vec3_add(A, B))); |
81 | 0 | } |
82 | | |
83 | | struct Mat4 { |
84 | | double m[4][4] = {{1.0, 0.0, 0.0, 0.0}, |
85 | | {0.0, 1.0, 0.0, 0.0}, |
86 | | {0.0, 0.0, 1.0, 0.0}, |
87 | | {0.0, 0.0, 0.0, 1.0}}; |
88 | | }; |
89 | | |
90 | | // Apply an affine 4x4 to a 3D point (treated as (v.x, v.y, v.z, 1)). Assumes |
91 | | // the bottom row is [0, 0, 0, 1] (true affine, no perspective divide). |
92 | 10.1k | inline Vec3 vec3_apply_mat4(const Mat4 &m, const Vec3 &v) { |
93 | 10.1k | return { |
94 | 10.1k | m.m[0][0] * v.x + m.m[0][1] * v.y + m.m[0][2] * v.z + m.m[0][3], |
95 | 10.1k | m.m[1][0] * v.x + m.m[1][1] * v.y + m.m[1][2] * v.z + m.m[1][3], |
96 | 10.1k | m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z + m.m[2][3], |
97 | 10.1k | }; |
98 | 10.1k | } |
99 | | |
100 | | #endif // VEC3_H |