Skip to content

ChrisG0x20/c-vector-rectangle-lib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

c-vector-rectangle-lib

Simple pure C language vector and rectangle library. The vector types and functions can be used for a variety of purposes, such as: 2D integer points for pixel coordinates and sizes; 2D floating point vectors for 2D game objects and texture coordinates; 3D floating point vectors for 3D graphics and RGB values; 4D floating point vectors for RGBA values; etc. The rectangle types can be either math-style or raster-style. The difference being: the direction of the Y-axis, and whether the width and height of the rectangle are treated as inclusive or exclusive.

Design

This library started as an experimental translation of a couple C++ template classes to pure C. The design goals behind the original C++ code were:

  1. Single header file for each class e.g., vector.h and rectangle.h.
  2. Templated vector and rectangle types that handled both integer and floating point scalars.
  3. Templated vector type that handled multiple dimensions; two, three or four dimensional vectors.
  4. The structure layout of the types would be equivalent to an array of scalars; for efficient casting and interoperation with other APIs.
  5. Straight forward code that doesn't depend on CPU intrinsics, but is written in a style that allows vectorizing compilers to recognize and take advantage of vector operations via SIMD CPU instructions.
  6. Specialized operations for specific vector dimensions and rectangle types. e.g., cross product only makes sense for 3D vectors.
  7. Templated rectangle type that handled both geometric and raster style rectangles.

Some of these goals translated to pure C better than others.

Specifically, it didn't seem reasonable to maintain a single header file layout for each "class". However, while the user must build some source files, only a single header file need be included. Next, the preprocessor was used (abused?) to emulate the template expansion of numerous types of vectors and rectangles based on both integer and floating point scalars. Because of the way the template expansion was translated to pure C, only a few common combinations of vector and rectangle types are generated by default. Many other types may be generated via simple modifications to the library. Also, it's worth pointing out that a little more preprocessor magic (I can quit at any time, I swear!) could be added to turn off code generation of undesired or unused types. In order to keep the header files readable they've been written clearly without macros.

Portability

The library was written to avoid platform specific code. However, the scope of testing has been limited. It's been tested with Microsoft Visual C v11.0 and Clang v3.2 (OS X).

Of note:

  • The library includes a typedef int bool; and the following macro definitions: #define true 1 and #define false 0. This is a hold over from the translation of this code from C++. There's probably a better way to do this in pure C that's less likely to cause name collisions with other peoples' code.

Using the Library

  • Build a library made up of the .c files in the src directory, or simply include them in your own project's build directly.
  • Include the header file cvr_vector.h in your source file to use the vector types and functions.
  • Or, include the header file cvr_rectangle.h in your source file for vector and rectangle types and functions.
  • If CVR_VECTOR_POLLUTION is defined, the cvr_vector.h header will typedef several more friendly names for vectors. This is intended to help client code's usage of vectors convey more context. Here's the list of the additional names:
typedef vec2f   pointf;
typedef vec2i   pointi;
typedef vec2ui  pointui;
typedef vec2f   sizef;
typedef vec2i   sizei;
typedef vec2ui  sizeui;
typedef vec2f   texcoord2f;

typedef vec3f   rgbf;
typedef vec3f   volumef;
typedef vec3f   texcoord3f;

typedef vec4f   rgbaf;
typedef vec4f   texcoord4f;

Instructions and Notes

Vectors

The vector types are implemented as a union of structs and a scalar array. The structs contain several conveniently named members to help client code imply context when using a vector. The structs include these names where appropriate:

  • Coordinates: x, y, z, w
  • Sizes: width, height, depth
  • Texture coordinates: t, s, p, q
  • Color channels: r, g, b, a

Additionally, a vector may be accessed as an array of its scalar type either by casting it, or using its elem member. For example: ((float*)&v)[1] or v.elem[1].

Vector functions take the form: vec[DIMENSION][SCALAR_TYPE]_func(), where DIMENSION is required and SCALAR_TYPE is optional, but defaults to double. For example, vec2i_zero() would operate on a 2D integer vector. Here's a list of the default vector types included with the library:

vec2    // 2D vector of double
vec2f   // 2D vector of float
vec2i   // 2D vector of int_fast32_t (at least 32-bit integer; maybe, but not likely, more bits)
vec2ui  // 2D vector of uint_fast32_t (at least 32-bit unsigned integer; maybe, but not likely, more bits)
vec3    // 3D vector of double
vec3f   // 3D vector of float
vec4    // 4D vector of double
vec4f   // 4D vector of float

Rectangles

The rectangle types are composed of two 2D vectors: a location and a size. Alternatively, the rectangles may be treated as a structure of four scalars: x, y, width and height. Finally, the rectangle's four scalars may be indexed as an array, either by casting or via the elem member of the rectangle structure.

Styles of rectangles supported.

Math-style rectangles might be used with vector graphics like OpenGL where the Y-axis increases from bottom to top and the dimensions of the rectangle are inclusive. If a math-style rect's left side is at location 1.0 and its right side is at 5.0, the width of the rectangle is 4.0 and any point up-to and including the point 5.0 is considered to be inside the rectangle.

The raster-style could be used for text or window pixel coordinates where the Y-axis increases from top to bottom and the value of the bottom and right sides are exclusive. That is, if the left side is equal to 1 and the right side is equal to 5, the wdith of the raster rectangle is 4 columns. Any column up-to but excluding column 5 would be considered inside the rectangle. Example: Win32 RECTs work like this.

Rectangle functions take the form: [raster_]rect[SCALAR_TYPE]func(), where the 'raster' prefix is used only when operating on raster-style rectangles and SCALAR_TYPE is used to indicate the type of scalars making up the rectangle. For example, recti_zero() would operate on a integer, math-style rectangle. Here's a list of the default rectangle types included with the library:

rectf           // math-style rectangle of float
recti           // math-style rectangle of int_fast32_t (at least 32-bit integer; maybe, but not likely, more bits)
raster_rectf    // raster-style rectangle of float
raster_recti    // raster-style rectangle of int_fast32_t (at least 32-bit integer; maybe, but not likely, more bits)
raster_rectui   // raster-style rectangle of uint_fast32_t (at least 32-bit unsigned integer; maybe, but not likely, more bits)

License

Boost Software License - Version 1.0

The Boost License Design Requirements:

  • Must be simple to read and understand.
  • Must grant permission without fee to copy, use and modify the software for any use (commercial and non-commercial).
  • Must require that the license appear with all copies [including redistributions] of the software source code.
  • Must not require that the license appear with executables or other binary uses of the library.
  • Must not require that the source code be available for execution or other binary uses of the library.

About

Simple pure C language vector and rectangle library.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages