Pure C math library for 2D and 3D programming

Overview

MATHC

MATHC is a simple math library for 2D and 3D programming.

Features

  • Vectors (2D, 3D and 4D) (integer type and floating-point type)
  • Quaternions
  • Matrices (2×2, 3×3, and 4×4)
  • Easing functions

Contributions and Development

You can help with the development of MATHC testing the library, sending in-scope math functions, reporting errors and giving feedback.

I work little on the library nowadays, but I am always open to suggestions and contributions.

Versioning

Starting on version 2, the development of MATHC uses calendar versioning, with a tag YYYY.MM.DD.MICRO for each stable release. If a release breaks backward compatibility, then it is mentioned in the release notes.

Configuring

MATHC can be configured using these preprocessors:

  • MATHC_NO_INT: disable implementations using mint_t.
  • MATHC_USE_INT8: define mint_t as int8_t.
  • MATHC_USE_INT16: define mint_t as int16_t.
  • MATHC_USE_INT32: define mint_t as int32_t. This is the default.
  • MATHC_USE_INT64: define mint_t as int64_t.
  • MATHC_INT_TYPE: set a custom type for mint_t.
  • MATHC_NO_FLOATING_POINT: disable implementations using mfloat_t.
  • MATHC_USE_SINGLE_FLOATING_POINT: define mfloat_t as float. This is the default.
  • MATHC_USE_DOUBLE_FLOATING_POINT: define mfloat_t as double.
  • MATHC_FLOATING_POINT_TYPE: set a custom type for mfloat_t.
  • MATHC_USE_UNIONS: define anonymous unions inside structures.
  • MATHC_NO_POINTER_STRUCT_FUNCTIONS: don't define the functions that take pointer to structures.
  • MATHC_NO_STRUCT_FUNCTIONS: don't define the functions that take structures as value.
  • MATHC_NO_EASING_FUNCTIONS: don't define the easing functions.

You can define these preprocessors using the compiler's option -D or using the compiler's option -include to include a configuration header with the configuration preprocessors inside it.

Example of a configuration header that makes mint_t a int16_t, mfloat_t a GLfloat and uses the standard math functions with double floating-point precision:

#include <gl.h>

#define MATHC_USE_INT16
#define MATHC_FLOATING_POINT_TYPE GLfloat
#define MATHC_USE_DOUBLE_FLOATING_POINT

Types

By default, vectors, quaternions and matrices can be declared as arrays of mint_t, arrays of mfloat_t, or structures.

Functions

By default, MATHC has functions that take as argument arrays of mint_t, arrays of mfloat_t, structures as value, or pointer to structures. Functions that take structure as value have a prefix s. Functions that take structure pointer have a prefix ps.

Easing Functions

The easing functions are an implementation of the functions presented in easings.net, useful particularly for animations.

Easing functions take a value inside the range 0.0-1.0 and usually will return a value inside that same range.

Usage

Creating a "look at" view matrix, useful for 3D programming:

mfloat_t position[VEC3_SIZE];
mfloat_t target[VEC3_SIZE];
mfloat_t up[VEC3_SIZE];
mfloat_t view[MAT4_SIZE];

mat4_look_at(view,
	vec3(position, 0.0, 0.0, 10.0),
	vec3(target, 0.0, 0.0, 0.0),
	vec3(up, 0.0, 1.0, 0.0));

Creating a perspective projection matrix:

mfloat_t perspective[MAT4_SIZE];

mat4_perspective(perspective, to_radians(60.0), 1.0, 0.1, 100.0);

Creating a model matrix:

mfloat_t position[VEC3_SIZE];
mfloat_t scaling[VEC3_SIZE];
struct {
	mfloat_t position[MAT4_SIZE];
	mfloat_t rotation[MAT4_SIZE];
	mfloat_t scaling[MAT4_SIZE];
	mfloat_t model[MAT4_SIZE];
} matrices;

/* Position */
mat4_identity(matrices.position);
mat4_translation(matrices.position,
	vec3(position, 0.0, 0.0, 0.0));

/* Rotation */
mat4_identity(matrices.rotation);
mat4_rotation_x(matrices.rotation, to_radians(30.0));

/* Scaling */
mat4_identity(matrices.scaling);
mat4_translation(matrices.scaling,
	vec3(scaling, 1.0, 1.0, 1.0));

/* Model matrix */
mat4_multiply(matrices.model, matrices.scaling, matrices.rotation);
mat4_multiply(matrices.model, matrices.position, matrices.model);

License

Copyright © 2018 Felipe Ferreira da Silva

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
Issues
  • Assert Test Results

    Assert Test Results

    tests should assert the returned value is equal to the expected value, and fail if otherwise. the test can be run as is or using a unit testing framework, which ever option is found to be the best fit. Any input?

    opened by barrotsteindev 5
  • Add vectors with integer fields

    Add vectors with integer fields

    Vectors with integer fields are less used, but are still usable. They won't have as many functions as the vectors with float fields, but they will have minimally the basic math operation functions.

    opened by felselva 5
  • Function to apply translation to existing mat4?

    Function to apply translation to existing mat4?

    When building a camera transform matrix, I have a quaternion for the heading and a vec3 for the camera position. I can use smat_rotation_quat() to build the rotation matrix from the quaternion, but then I need to insert the position as well. I don't see any functions for this, all mat4 translate functions appear to build a new mat4 from scratch.

    For reference, I'm converting from linmath.h which had mat4x4_translate_in_place().

    enhancement version 2 
    opened by Nairou 4
  • Use macros to define similar functions

    Use macros to define similar functions

    The functions for different vector sizes are very similar, but they are repeated in the code. This means mistakes are easy to make. I suggest using macros to define these functions, so you write the code once and use macros to define the other vector versions.

    Here's some sample code for doing this kind of thing:

    #include <stdio.h>
    
    #define CAT(x, y) x##y
    #define MAKE_FUNC(_num) \
    void CAT(foo, _num)(void) { printf("func %d\n", _num); }
    
    MAKE_FUNC(2)
    MAKE_FUNC(3)
    
    int main(void) {
    	foo2();
    	foo3();
    	return 0;
    }
    
    opened by cxong 4
  • add CI tests

    add CI tests

    proposal to add CI/CD tests, for example using travis ci to compile the code and run the test file. I have no problem to start working on this if it is found to be needed.

    opened by barrotsteindev 4
  • Compiler warnings for missing field initializers

    Compiler warnings for missing field initializers

    This code produces a warning when gcc/clang have warnings turned to full, or if -Wmissing-field-initializers is defined:

    struct vec b_minus_a = {0};
    

    Although this is valid C99 initialisation, should mathc aim to produce no compiler warnings? If so this needs to be replaced with say

    struct vec a = {0, 0, 0, 0};
    // or
    struct vec a = vector2_zero();
    
    opened by cxong 3
  • Suggestion: add quat_to_axis_angle

    Suggestion: add quat_to_axis_angle

    I looked for this but couldn't find a quat_to_axis_angle. While I assume this can be obtained by applying the quaternion on a forward pointing vector and getting the angle manually, this is more cumbersome than a single call. Also, this might be me just misunderstanding things, but to me it's not obvious what sort of vector would align with the axis of a non-rotating quaternion in mathc's coordinate system since this is not specified. (Is it 0,0,-1? Or 1,0,0? ...) I might be wrong, but I think this knowledge is required to implement this manually in a way such that the quat_from_axis_angle reverses back to the same quaternion.

    opened by ghost 2
  • How stable is MathC version 2?

    How stable is MathC version 2?

    From what I can tell, v2 looks a lot friendlier than v1. v1 has been around a while, but v2 is listed as in development. Is it still recommended to use v1? Or is v2 ready for use in projects?

    opened by Nairou 2
  • Should 2D vectors be removed and keep only 3D vectors?

    Should 2D vectors be removed and keep only 3D vectors?

    2D vectors can be simply represented as 3D vectors with z = 0.0f. However, matrices only works with 3D vectors, and it's inconvenient to convert from 2D to 3D just to use with matrices, as in this case:

    cvector2 position = to_vector2(0.0f, 0.0f);
    m = matrix_translation(to_vector3(position.x, position.y, 0.0f));
    

    Working only with 3D vectors would make things simpler:

    cvector3 position = to_vector3(0.0f, 0.0f, 0.0f);
    m = matrix_translation(position);
    

    The z component of 3D vectors are also useful in 2D games for z-ordering.

    Functions like vector2_dot and vector2_angle will still exist, but they will only operate on the x and y components of a 3D vector:

    float vector2_dot(cvector3 v);
    float vector2_angle(cvector3 v);
    

    To remove 2D vectors, react with :+1:.

    To keep 2D vectors, react with :-1:.

    opened by felselva 2
  • Add version of functions that take pointers

    Add version of functions that take pointers

    For the sake of performance, it should be added version of functions that take the structures as pointers. The functions that take the structures as values will still exist, and the functions that take the structures as pointers will have a p prefix.

    As example:

    cvector2 pvector2_add(const cvector2 *a, const cvector2 *b)
    {
    	cvector2 result;
    	result.x = a->x + b->x;
    	result.y = a->y + b->y;
    	return result;
    }
    
    inline cvector2 vector2_add(const cvector2 a, const cvector2 b)
    {
    	return pvector2_add(&a, &b);
    }
    
    opened by felselva 2
  • Remove memory functions dependencies, and fix for mat4 and quaternion to mat4.

    Remove memory functions dependencies, and fix for mat4 and quaternion to mat4.

    Hi,

    I made 2 little changes to the library.

    1. Using memcpy and malloc functions seemed a bit overkilling for a simple math library like this, especially when memory size and layout is known beforehand.

    2. I have fixed two bugs for mat4_rotation_axis and mat4_rotation_quat implementation.

    If you think these are reasonable, here it is my pull request.

    opened by fabiopolimeni 1
  • Array overflow

    Array overflow

    https://github.com/felselva/mathc/blob/d672725203fc80f6f79fba64533b87d51c32d714/mathc.c#L2556

    Hey is this not an array overflow taking element 8 in a quartenion?

    opened by johandc 0
  • smat4_rotation_* looks wrong. Shouldn't they be initialised with identity matrix?

    smat4_rotation_* looks wrong. Shouldn't they be initialised with identity matrix?

    On https://github.com/felselva/mathc/blob/master/mathc.c#L5169 mat4 result is defined which is passed to mat4_rotation_x. Inside mat4_rotation_x only values at index 5,6,9, and 10 are updated. Also as per the example, in README, identity matrix was generated before passing it to mat4_rotation_x.

    So shouldn't smat_rotation_* methods also set identity matrix before calling mat4_rotation_x?

    E.g.

    struct mat4 smat4_rotation_x(mfloat_t f)
    {
    	struct mat4 result = smat4_identity();
    	mat4_rotation_x((mfloat_t *)&result, f);
    	return result;
    }
    
    opened by suyashmohan 0
  • add function sncs1cs to get accurate 1-cosine

    add function sncs1cs to get accurate 1-cosine

    Currently in three places in the code there is an expression like: 1-cosine(subexpr). The problem with that is that it sacrifices quite a bit of precision the floating point type in use could provide. Because of the subtraction, and the fact that floating point is MUCH denser near zero than near one, 1-cosine(x) values that should be close to zero will just be truncated to exactly zero.

    The added function sncs1cs is not exported.

    The changes apply only if the user has not specified a custom mfloat_t.

    This improves mat3_rotation_axis, mat4_rotation_axis and sine_ease_in_out. A side improvement in the former two is that the computation of sine, cosine and 1-cosine should be cheaper when computing them all at the same time than when calling a separate function for each of the three (because the majority of the code is shared between the three).

    I checked that the improvements do materialize and, more importantly, at the same time searched for big regressions:

    https://github.com/nsajko/numericcompfricas (see the README.md)

    Basically, the results are that there are no significant differences for sin and cos (I think the accuracy only varies by one bit), but there are big improvements for 1-cos (AKA omc AKA 1cs). The repository contains the results of the check against glibc and against musl.

    FriCAS (for the check) can be found here: https://github.com/fricas/fricas

    opened by nsajko 0
  • Looking for new maintainer

    Looking for new maintainer

    Working on this library was very nice, and it seems it helped a lot of people, but also seems like I can't give it enough dedication anymore.

    With that, I am looking for a new maintainer. I am looking for a maintainer that is experienced in C and is dedicated in the open-source community.

    Thank you all for the support all this time!

    opened by felselva 3
  • quat_look_at

    quat_look_at

    I tried to find this function or an equivalent, but it seems to be missing: quat_look_at

    I see matrix equivalents, but it would be really useful to be able to do this one with quaternions. From the internet it looks like this is commonly available in other quaternion libraries (e.g. Ogre3D's quaternions offer this) so it doesn't seem like a super arcane function either. Would be really cool if it could be added some day!

    opened by ghost 4
Owner
Felipe da Silva
C programmer (16 years) and Biologist at Federal University of Minas Gerais (UFMG). Migrating account…
Felipe da Silva
📽 Highly Optimized Graphics Math (glm) for C

?? OpenGL Mathematics (glm) for C Documentation Almost all functions (inline versions) and parameters are documented inside the corresponding headers.

Recep Aslantas 1.4k Aug 12, 2022
Bash math utilities

Bashmash Bash math utilities What is Bashmash? Bashmash is a set of math utilities for the Bash language. It simplifies common mathematical operations

Hubert Pastyrzak 11 Mar 11, 2021
Phyxed is a 2D physics engine with support for fixed point math.

Phyxed is a 2D physics engine with support for fixed point math.

Anders Elfgren 23 Jul 10, 2022
Pure C Game Engine

Corange game engine Version 0.8.0 Written in Pure C, SDL and OpenGL. Running Corange is a library, but to take a quick look at some of the things it d

Daniel Holden 1.5k Aug 11, 2022
FDF is a 42 Project to learn about 3d programming. The program takes a map as parameter and creates its 3d representation.

FDF Project Overview FDF is a 42 Project to learn about 3d programming. The program takes a map as parameter and creates its 3d representation. Render

Mmoumni08 6 Jul 30, 2022
ANSI C library for NURBS, B-Splines, and Bézier curves with interfaces for C++, C#, D, Go, Java, Lua, Octave, PHP, Python, R, and Ruby.

TinySpline TinySpline is a small, yet powerful library for interpolating, transforming, and querying arbitrary NURBS, B-Splines, and Bézier curves. Th

Marcel Steinbeck 810 Aug 7, 2022
StereoKit is an easy-to-use open source mixed reality library for building HoloLens and VR applications with C# and OpenXR!

StereoKit is an easy-to-use open source mixed reality library for building HoloLens and VR applications with C# and OpenXR! Inspired by libraries like XNA and Processing, StereoKit is meant to be fun to use and easy to develop with, yet still quite capable of creating professional and business ready software.

Nick Klingensmith 668 Aug 8, 2022
Draco is a library for compressing and decompressing 3D geometric meshes and point clouds.

Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.

Google 5.1k Aug 12, 2022
A multi core friendly rigid body physics and collision detection library suitable for games and VR applications.

A multi core friendly rigid body physics and collision detection library suitable for games and VR applications.

null 2k Aug 7, 2022
DirectX 11 and 12 library that provides a scalable and GCN-optimized solution for deferred shadow filtering

AMD ShadowFX The ShadowFX library provides a scalable and GCN-optimized solution for deferred shadow filtering. Currently the library supports uniform

GPUOpen Effects 165 Jul 13, 2022
The official Open-Asset-Importer-Library Repository. Loads 40+ 3D-file-formats into one unified and clean data structure.

Open Asset Import Library (assimp) A library to import and export various 3d-model-formats including scene-post-processing to generate missing render

Open Asset Import Library 8.1k Aug 7, 2022
A modern cross-platform low-level graphics library and rendering framework

Diligent Engine A Modern Cross-Platform Low-Level 3D Graphics Library Diligent Engine is a lightweight cross-platform graphics API abstraction library

Diligent Graphics 2.4k Aug 12, 2022
A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input

GLFW Introduction GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platf

GLFW 9.4k Aug 6, 2022
Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal

Low Level Graphics Library (LLGL) Documentation NOTE: This repository receives bug fixes only, but no major updates. Pull requests may still be accept

Lukas Hermanns 1.4k Aug 13, 2022
Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.

This project is not actively maintained. NanoVG NanoVG is small antialiased vector graphics rendering library for OpenGL. It has lean API modeled afte

Mikko Mononen 4.4k Aug 11, 2022
Freecell Solver - a C library for automatically solving Freecell and some other variants of card Solitaire

The Freecell Solver Repository Root README Freecell Solver is an open source (distributed under the MIT/Expat licence) library, written in C, for atte

Shlomi Fish 49 Jun 24, 2022
A terminal-based graphics library for both 2D and 3D graphics.

TermGL A terminal-based graphics library for both 2D and 3D graphics. Written in C, created for terminals supporting ANSI escape codes. Table of Conte

null 205 Aug 10, 2022
A minimalist library with basic facilities for developing interactive real-time 3D applications, with a strong emphasis on simplicity and ease of use.

SlimEngine A minimalist and platform-agnostic base project for interactive graphical applications (2D/3D) with a strong emphasis on simplicity, ease o

Arnon Marcus 67 Jul 27, 2022