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.
Comments
  • 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.5k Nov 20, 2022
DOSBox Pure is a new fork of DOSBox built for RetroArch/Libretro aiming for simplicity and ease of use.

DOSBox Pure is a fork of DOSBox, an emulator for DOS games, built for RetroArch/Libretro aiming for simplicity and ease of use.

Bernhard Schelling 549 Nov 28, 2022
Pure C Arcade game. Cross between pong and breakout, made it by accident

LameBall I accidentally made this game while testing some code. It's kind of a cross between Pong and Breakout, mixed with Squash/Racquetball. >> DOWN

Phil Bagshaw 2 Sep 17, 2021
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.6k Nov 25, 2022
A simple and easy-to-use library to enjoy videogames programming

raylib is a simple and easy-to-use library to enjoy videogames programming. raylib is highly inspired by Borland BGI graphics lib and by XNA framework

Ray 11.1k Nov 23, 2022
dos-like is a programming library/framework, kind of like a tiny game engin

dos-like is a programming library/framework, kind of like a tiny game engine, for writing games and programs with a similar feel to MS-DOS productions from the early 90s. But rather than writing code that would run on a real DOS machine, dos-like is about making programs which runs on modern platforms like Windows, Mac and Linux, but which attempts to recreate the look, feel, and sound of old DOS programs.

Mattias Gustavsson 804 Nov 23, 2022
Project 1945 is a top down scroller game made with SDL2, CMake and programmed in C as a project of study for the Italian Videogames Academy for the 3rd year course of Videogames programming.

Project 1945 is a top down scroller game made with SDL2, CMake and programmed in C as a project of study for the Italian Videogames Academy for the 3rd year course of Videogames programming. The game is based on the old videogame 1945: The Final Front of the 2002.

null 18 Jul 27, 2022
A set of libraries and tools to make MSX games using the C programming language.

ubox MSX lib This is a set of libraries and tools to make MSX games using the C programming language. There are three main components: ubox: thin wrap

Juan J. Martínez 42 May 30, 2022
A clone of the classic QBasic Gorillas written in the Zig programming language

⚡ Zig Gorillas ?? A clone of the classic QBasic Gorillas written in the Zig programming language. Take turns in throwing an exploding banana at each o

Fabio Arnold 44 Jun 18, 2022
An OpenGL Engine Written In C Using A Very OOP-Like Way Of Programming

A Simple Engine in its very first stages of becoming a, Game Engine or just a framework for making games using OpenGL. Here are the features of the Op

DevHedron 26 Jul 9, 2022
A programming game, in which your goal is to help a group of dwarves establish a small outpost in the middle of a dangerous forest.

"Since they were to come in the days of the power of Melkor, Aulë made the dwarves strong to endure. Therefore they are stone-hard, stubborn, fast in

Alexey Nikolaev 6 Sep 29, 2022
Recreation of the MineStorm game for a student programming project.

MineStorm General information This project is a student project done for ISART Digital by Rémi SERRA and Alexandre PERCHÉ. The goal was to recreate th

Rémi Serra 2 Nov 14, 2021
Engine being created for homeworks in UPC Master's Degree in Advanced Programming for AAA Video Games.

Strawhat Engine Strawhat Engine is a game engine under construction that has model loading and camera movement features along with an editor. Reposito

I. Baran Surucu 12 May 18, 2022
A minecraft clone built in c++ opengl for the purpose of prefecting graphics programming skills.

LearnOpenGL - CLion This is a project template for OpenGL development with JetBrains CLion IDE. It was created mainly for LearnOpenGL tutorials. Inclu

Jeremy Dellock 1 Dec 28, 2021
This is the source repo for the book Game Programming Patterns

Note: Now that the book is done, I'm not actively working on it. There are only so many hours in the day, and I have other projects that need my love,

Bob Nystrom 3.4k Nov 18, 2022
Tic Tac Toe implementation using c programming language with minimax algorithm.

Tic Tac Toe implementation using c programming language with minimax algorithm.

Sehan Weerasekara 1 Feb 19, 2022
A multi core friendly rigid body physics and collision detection library suitable for games and VR applications.

Jolt Physics Library A multi core friendly rigid body physics and collision detection library suitable for games and VR applications. A YouTube video

null 2.4k Nov 27, 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 52 Nov 17, 2022
SubLink is a C++ library used for constructing and analyzing merger trees in numerical simulations of galaxy formation

README SubLink is a C++ library used for constructing and analyzing merger trees in numerical simulations of galaxy formation. Brief description SubLi

nelson-group 1 Jan 20, 2022