Math linmath.h

# linmath.h -- A small library for linear math as required for computer graphics

linmath.h provides the most used types required for programming computer graphics:

vec3 -- 3 element vector of floats vec4 -- 4 element vector of floats (4th component used for homogenous computations) mat4x4 -- 4 by 4 elements matrix, computations are done in column major order quat -- quaternion

The types are deliberately named like the types in GLSL. In fact they are meant to be used for the client side computations and passing to same typed GLSL uniforms.

• #### mat4x4_rotate_z, order of operation intended?

I tried this function with a translation Matrix as input for M. When I use the resulting matrix it first rotates around the origin and after that, it translates, but given the functions description, I would have thought that it would take the transformation and add the operation "rotate around the origin" afterwards. Is that behaviour intended?

``````static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
mat4x4 R = {
{   c,   s, 0.f, 0.f},
{  -s,   c, 0.f, 0.f},
{ 0.f, 0.f, 1.f, 0.f},
{ 0.f, 0.f, 0.f, 1.f}
};
mat4x4_mul(Q, M, R);
}
``````

To get this behaviour I expected I had to change : `mat4x4_mul(Q, M, R);` to `mat4x4_mul(Q, R, M);`

Edit: 21.04.21 fix code formatting

opened by userx14 4
• #### Issue with constructing vectors

Hiya, Loving this module so far, but I have an issue constructing a 3 dimension vector. I have a large array of floats that represent 3d vertices. I wish to loop over them on a per vertex basis so i constructed the following piece of code.

``````for(int i=0; i<n; i++) {
vec3 v = VEC3(array[i+0], array[i+1], array[i+2]);
}
``````

But this gives me the following compile error (using g++)

``````linmath.h:148:30: error: array must be initialized with a brace-enclosed initializer
#define VEC3(x,y,z)   (vec3){x,y,z}
^~~~~~~
vertexbuf.h:76:17: note: in expansion of macro ‘VEC3’
vec3 p1 = VEC3(grid[i+0], grid[i+1], grid[i+2]);
``````

Am I doing something wrong here?

opened by HugoPeters1024 3
• #### Fixed an MSVC Compiler Error.

Upon using this header in Visual Studio projects. The MSVC reports Compiler Error C3861.

Therefore, added a preprocessor directive to check if this header is being compiled with MSVC, if so, then include a prototype for `memcpy` function to fix this.

opened by harshrathod50 2
• #### Ability to set row major computations order.

This PR adds ability to set row major computations order for matrices by definition of `MAT4X4_ROW_MAJOR` before inclusion of the library. It also fixes some implicit typecasts (includes PRs #8 and #10 as well) and adds two functions: `mat4x4_set_row()` and `mat4x4_set_col()` that were necessary for row major support. See commits for details.

opened by BlackDoomer 2
• #### quat_mul_vec3 causes SIGSEGV (Address boundary error)

It seems that the `quat_mul_vec3` function takes in a `vec3` as a result parameter and then passes it on to several other functions expecting a `quat`, resulting in an Address boundary error.

opened by eivindlysne 2
• #### Added tests, fixed a bug, and more

• added first tests (partially addresses #4). I skipped some primitive functions, though, in best practice, every function should be tested - I hope others will contribute!

• added CircleCI suite for your repository that will be automatically run on each commit. All you need to do is

• create an account on circleci.com, if you don't have it yet;
• choose this project from a list of your projects
• choose "Use existing config"

• fixed a bug in `mat4x4o_mul_quat`: the last element in each row of the resulting matrix was not set. Previously, there was junk data.

• Reused `vec4` code for `quat`:

``````#define quat_add vec4_add
#define quat_sub vec4_sub
#define quat_norm vec4_norm
#define quat_scale vec4_scale
#define quat_mul_inner vec4_mul_inner
``````

Previously, only `#define quat_norm vec4_norm` was set.

• Normalize `axis` to a unit norm in `quat_rotate`. An alternative implementation, when the user has to deal with normalization manually, is

``````LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 const axis) {
float s = sinf(angle / 2);
float c = cosf(angle / 2);
vec3_scale(r, axis, s);
r[3] = c;
}
``````

The previous version was strange and not optimized. Let me know which one you prefer - force users to manually normalize `axis` (the snippet above, optimized) or take care of the normalization in the function body (current).

• added `vec##n##_dup` function (used it in `mat4x4_dup` and `mat4x4_scale_aniso` functions, and several times in linmath_test.h). Previously, there was only a `mat4x4_dup` function. Also, now we can get rid of unsafe memcpy, which is the only function that requires `<string.h>` to be imported. Let me know if it's better to reuse `vec##n##_dup` instead of `memcpy` (the fix if very easy to add).

• (minor) added const qualifiers to each function (hints). Previously, there were several functions with a const qualifier and most of them didn't have any. We should either put const every time when the argument is not modified or don't use const at all. On second thought, I'm not sure how much it makes sense - for me, the tradeoff of const versus not const has never been clear.

There is a bunch of things. Let me know if you want to include only a part of them.

Danylo

Update 1 I noticed that linmath.h sometimes is used as a submodule to build a C/C++ project. Adding linmath_test.c with a main() function will break such workflows. Does it make sense generating linmath_test.c on the fly at CircleCI runs?

Update 2 I noticed that `quat_inner_product` was used to compute the inner product of two quaternions. Now I redefined it as `#define quat_mul_inner vec4_mul_inner`. Doing so introduces a breaking change for other projects that use linmath. Let me know if I should rename it to `#define quat_inner_product vec4_mul_inner`.

opened by dizcza 1

"linmath.h provides the most used types required programming computer graphice:" maybe better: "linmath.h provides the most used types required for programming computer graphics:"

opened by leok7v 1
• #### warning: return type defaults to int

warning: return type defaults to ‘int’ [-Wimplicit-int] LINMATH_H_FUNC mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s)

in commit "transplanted arcball function"

static inline void mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s) was changed to: LINMATH_H_FUNC mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s)

missing void

LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s)

opened by RicardasSim 1
• #### Reusing variables in quat_mul_vec3 for vector operations produces bad results

The new implementation of `quat_mul_vec3` introduced in commit 06b68f6caa214d9f98ada28db837c21e08ed2927 incorrectly calculates 't' and 'u'. The problem's caused by the variables being used as both input and output to `vec3_mul_cross`, which causes the variables to be corrupted as the cross product is taken. Unlike with the simple vector operations, input variables to vec3_mul_cross must be distinct from the output variable.

I've suggested a fix for it in PR #22.

``````static inline void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b) {
r[0] = a[1]*b[2] - a[2]*b[1];
r[1] = a[2]*b[0] - a[0]*b[2];
r[2] = a[0]*b[1] - a[1]*b[0];
}
``````
opened by t-mw 1
• #### mat4x4_scale_aniso leaves target W vector uninitialized

The mat4x4_scale_aniso function should copy the W vector from the reference matrix to the target matrix. As it stands:

``````mat4x4 id;
mat4x4_identity(id);

mat4x4 scaled;
mat4x4_scale_aniso(scaled, id, 0.1, 0.4, 0.9); // scales x, y, z, doesn't copy w
``````

Found this while running some really basic tests on the library.

opened by cormac-obrien 1
• #### Usage of For Loops

Have you benchmarked these functions using the existing short-range For loops versus unrolling them out? From the vantage point of the compiled product, using Floops of only 3 and 4 increments seems woefully verbose.

opened by sc-harsha 1
• #### Usage double numbers instead of float

By default C compiler treats floating point numbers as double, so "1." is always converted to float, "1.f" should be used instead.

https://github.com/datenwolf/linmath.h/blob/05387571f57224f8cbc2b390b423dab6b9158988/linmath.h#L582

opened by mgorchak-blackberry 0
• #### acos() instead of acosf() was used

https://github.com/datenwolf/linmath.h/blob/05387571f57224f8cbc2b390b423dab6b9158988/linmath.h#L599

Usage of acos() function instead of acosf() makes compiler do a float-to-double conversion and back without needs.

opened by mgorchak-blackberry 0
• #### redundant #include

after commit 05387571f57224f8cbc2b390b423dab6b9158988

redundant #include <string.h>

#include <string.h> #include <math.h> #include <string.h>

opened by RicardasSim 0
• #### warning: pointers to arrays with different qualifiers are incompatible in ISO C

after commit 05387571f57224f8cbc2b390b423dab6b9158988

linmath.h: In function ‘mat4x4_mul’: linmath.h:174:16: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 174 | mat4x4_dup(M, temp); | ^~~~ linmath.h: In function ‘mat4x4_translate_in_place’: linmath.h:198:17: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 198 | mat4x4_row(r, M, i); | ^ linmath.h: In function ‘mat4x4_rotate’: linmath.h:225:19: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 225 | mat4x4_scale(S, S, s); | ^ linmath.h:229:17: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 229 | mat4x4_sub(C, C, T); | ^ linmath.h:229:20: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 229 | mat4x4_sub(C, C, T); | ^ linmath.h:231:19: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 231 | mat4x4_scale(C, C, c); | ^ linmath.h:233:17: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 233 | mat4x4_add(T, T, C); | ^ linmath.h:233:20: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 233 | mat4x4_add(T, T, C); | ^ linmath.h:234:17: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 234 | mat4x4_add(T, T, S); | ^ linmath.h:234:20: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 234 | mat4x4_add(T, T, S); | ^ linmath.h:237:20: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 237 | mat4x4_mul(R, M, T); | ^ linmath.h: In function ‘mat4x4_rotate_X’: linmath.h:252:19: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 252 | mat4x4_mul(Q, M, R); | ^ linmath.h: In function ‘mat4x4_rotate_Y’: linmath.h:264:19: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 264 | mat4x4_mul(Q, M, R); | ^ linmath.h: In function ‘mat4x4_rotate_Z’: linmath.h:276:19: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 276 | mat4x4_mul(Q, M, R);

opened by RicardasSim 1
• #### STOP. CONVERTING. DOUBLES. TO. FLOATS.

So uhh yeah, whenever I try to use linmath, I get 12 warnings all telling me that "Severity Code Description Project File Line Column Suppression State Warning C4244 'initializing': conversion from 'double' to 'float', possible loss of data". And guess where they are? LinMath! pls fix

opened by KSPAtlas 1
###### libmpc++ is a C++ header-only library to solve linear and non-linear MPC

libmpc++ libmpc++ is a C++ library to solve linear and non-linear MPC. The library is written in modern C++17 and it is tested to work on Linux, macOS

39 Jul 8, 2022
###### Kraken is an open-source modern math library that comes with a fast-fixed matrix class and math-related functions.

Kraken ?? Table of Contents Introduction Requirement Contents Installation Introduction Kraken is a modern math library written in a way that gives ac

24 Mar 28, 2022
###### Invk - Inverse Kinematics Library with Quaternions

InvK - Inverse Kinematics Library using Quaternions by Rama Hoetzlein (ramakarl.com) This is a simple library that demonsrates an efficient solution t

17 Jul 14, 2022
###### nml is a simple matrix and linear algebra library written in standard C.

nml is a simple matrix and linear algebra library written in standard C.

35 Jul 5, 2022
###### C++ library for solving large sparse linear systems with algebraic multigrid method

AMGCL AMGCL is a header-only C++ library for solving large sparse linear systems with algebraic multigrid (AMG) method. AMG is one of the most effecti

539 Aug 1, 2022
###### A large scale non-linear optimization library

Ceres Solver Ceres Solver is an open source C++ library for modeling and solving large, complicated optimization problems. It is a feature rich, matur

2.5k Aug 5, 2022
###### C++ Matrix -- High performance and accurate (e.g. edge cases) matrix math library with expression template arithmetic operators

Matrix This is a math and arithmetic matrix library. It has stood many years of performing in mission critical production for financial systems. It ha

68 Aug 6, 2022
###### linalg.h is a single header, public domain, short vector math library for C++

linalg.h linalg.h is a single header, public domain, short vector math library for C++. It is inspired by the syntax of popular shading and compute la

729 Aug 9, 2022
###### 📽 Highly optimized 2D|3D math library, also known as OpenGL Mathematics (glm) for `C

Highly optimized 2D|3D math library, also known as OpenGL Mathematics (glm) for `C`. cglm provides lot of utils to help math operations to be fast and quick to write. It is community friendly, feel free to bring any issues, bugs you faced.

1.4k Aug 16, 2022
###### C++ header-only fixed-point math library

fpm A C++ header-only fixed-point math library. "fpm" stands for "fixed-point math". It is designed to serve as a drop-in replacement for floating-poi

319 Aug 12, 2022
###### Simple long integer math library for C++

SLIMCPP Simple long integer math library for C++ SLIMCPP is C++ header-only library that implements long integers that exceed maximum size of native t

20 Aug 2, 2022
###### Math library using hlsl syntax with SSE/NEON support

HLSL++ Small header-only math library for C++ with the same syntax as the hlsl shading language. It supports any SSE (x86/x64 devices like PC, Mac, PS

299 Aug 12, 2022
###### Linear Algebra in C

Linear Algebra in C Quick Start Grab la.h and use it as an stb-style header-only library. For more info on such libraries see: https://github.com/noth

66 Jul 24, 2022
###### tiny recursive descent expression parser, compiler, and evaluation engine for math expressions

TinyExpr TinyExpr is a very small recursive descent parser and evaluation engine for math expressions. It's handy when you want to add the ability to

1.1k Aug 8, 2022
###### Fast math tool written on asm/c

math_tool fast math tool written on asm/c This project was created for easy use of mathematical / geometric rules and operations. This project contain

3 Mar 8, 2022
###### qpSWIFT is a light-weight sparse quadratic programming solver

qpSWIFT Light-weight sparse Quadratic Programming Solver Introduction qpSWIFT is light-weight sparse Quadratic Programming solver targetted for embedd

59 Jul 18, 2022
491 Aug 5, 2022
###### A C library for statistical and scientific computing

Apophenia is an open statistical library for working with data sets and statistical or simulation models. It provides functions on the same level as t

184 Jun 17, 2022
###### C++ Mathematical Expression Parsing And Evaluation Library

C++ Mathematical Expression Toolkit Library Documentation Section 00 - Introduction Section 01 - Capabilities Section 02 - Example Expressions

414 Aug 9, 2022