A linear algebra and mathematics library for computer graphics.

Overview

cgmath-rs

Build Status Documentation Version License Downloads Gitter

A linear algebra and mathematics library for computer graphics.

The library provides:

  • vectors: Vector2, Vector3, Vector4
  • square matrices: Matrix2, Matrix3, Matrix4
  • a quaternion type: Quaternion
  • rotation matrices: Basis2, Basis3
  • angle units: Rad, Deg
  • points: Point2, Point3
  • perspective projections: Perspective, PerspectiveFov, Ortho
  • spatial transformations: AffineMatrix3, Transform3

Not all of the functionality has been implemented yet, and the existing code is not fully covered by the testsuite. If you encounter any mistakes or omissions please let me know by posting an issue, or even better: send me a pull request with a fix.

Conventions

cgmath interprets its vectors as column matrices (also known as "column vectors"), meaning when transforming a vector with a matrix, the matrix goes on the left. This is reflected in the fact that cgmath implements the multiplication operator for Matrix * Vector, but not Vector * Matrix.

Features

Swizzling

This library offers an optional feature called "swizzling" widely familiar to GPU programmers. To enable swizzle operators, pass the --features="swizzle" option to cargo. Enabling this feature will increase the size of the cgmath library by approximately 0.6MB. This isn't an issue if the library is linked in the "normal" way by adding cgmath as a dependency in Cargo.toml, which will link cgmath statically so all unused swizzle operators will be optimized away by the compiler in release mode.

Example

If we have

let v = Vector3::new(1.0, 2.0, 3.0);

then v.xyxz() produces a

Vector4 { x: 1.0, y: 2.0, z: 1.0, w: 3.0 }

and v.zy() produces a

Vector2 { x: 3.0, y: 2.0 }

SIMD optimizations

The current SIMD support depends on the deprecated "simd" package as well as the unstable "specialization" feature. To build this code, a pre-1.33 nightly build of Rust is required, e.g. 2019-01-01-nightly. Though the code is not useful in its present form, it has some worth preserving as starting point for a future migration (see https://github.com/rustgd/cgmath/issues/490).

Limitations

cgmath is not an n-dimensional library and is aimed at computer graphics applications rather than general linear algebra. It only offers the 2, 3, and 4 dimensional structures that are more than enough for most computer graphics applications. This design decision was made in order to simplify the implementation (Rust cannot parameterize over constants at compile time), and to make dimension-specific optimisations easier in the future.

Contributing

Pull requests are most welcome, especially in the realm of performance enhancements and fixing any mistakes I may have made along the way. Unit tests and benchmarks are also required, so help on that front would be most appreciated.

Comments
  • Matrix4::invert breaks because of low precision in approx_eq

    Matrix4::invert breaks because of low precision in approx_eq

    When inverting a matrix, we check that the determinant is non-zero using approx_eq. If the determinant is approximately zero, the inversion fails.

    But approx_eq only goes to a precision of 10^-5.

    That's problematic, because projection matrices often have very small determinants. This is especially true when the camera is zoomed out very far. In that case, we're transforming a large volume of world space to the clip space volume. Which means that the determinant tends to be very small. (This is because the determinant is the ratio of the two volumes.)

    opened by jarrett 27
  • Release 0.18?

    Release 0.18?

    Would it be possible to see a new release sometime soon? I'm trying to trim down dependencies and the rand crate was made optional about a year ago. It would be nice to exclude that when it's not needed.

    question 
    opened by aloucks 26
  • Use top corner instead of center for position in the axis-aligned box struct

    Use top corner instead of center for position in the axis-aligned box struct

    I'd like to use Aabb2 as a rectangle type in my code, and want the basic representation to match the range of points inside the box instead of the center: struct Aabb2 { top: Point2, size: Vec2 }. Rectangle code is mostly concerned with the edges instead of the center, so accessing those with simple arithmetic that doesn't involve dividing size components by two would be quite nice.

    Code that needs the box center can use a method which derives the center point from the top and size data.

    opened by rsaarelm 23
  • Mint flavour integration

    Mint flavour integration

    Includes #417 r? @brendanzab

    Notice how matrix and Euler conversions have stronger types (to ColumnMatrix*<> and EulerAngles<, IntraXYZ> respectively).

    opened by kvark 21
  • The future of cgmath

    The future of cgmath

    I currently am stretching myself quite thin when it comes to projects, and I feel like I am no longer able to adequately steer the development of cgmath going forwards. I am also considering moving to @sebcrozet's nalgebra library for my future projects. I can continue to merge PRs, but I can't see myself contributing much heading into the future. If somebody has the passion or energy to spare to keep things going, I am also happy to transfer ownership of the repository.

    wontfix 
    opened by brendanzab 21
  • Looking for new maintainers

    Looking for new maintainers

    Hello all!

    I'm incredibly sorry with my lack of involvement in cgmath as of late. I currently have a bunch of notifications in my Github inbox that I have been avoiding clicking on, which is never a good sign! A big problem is that I'm not currently working on any game projects myself which makes it incredibly hard to empathise with current pain-points with the library as it currently stands.

    I was wondering if anyone, or a group of people would be willing to take up the reigns of cgmath, seeing as it is obvious that I can no longer invest time in the project? If not I might be able to put up a notice that redirects people to more actively developed libraries like nalgebra or euler.

    cc. #419

    opened by brendanzab 15
  • Add Transform::{look_at_rh, look_at_lh} and deprecate look_at

    Add Transform::{look_at_rh, look_at_lh} and deprecate look_at

    The corresponding functions have been added to Matrix4 and Decomposed and are now consistent.

    Matrix3, Matrix2, and the Rotation trait are only partially updated. The look_at methods on these should probably be renamed to look_to_[lh|rh] as they take a direction vector, not a focus point. Does handedness even make sense for Matrix2?

    The older functions have all been left in-tact and marked deprecated. I don't think the old functionality should be removed in the near or medium term.

    opened by aloucks 13
  • implement Transform for Matrix3 and Matrix4

    implement Transform for Matrix3 and Matrix4

    Pursuant to conversations in #337, #302, and #324, I've implemented Transform for these two matrices. This makes working with the matrices as fully-fledged transformations much easier.

    Along the lines of https://github.com/bjz/cgmath/pull/302#issuecomment-211168768, I've also implemented Transform2 and Transform3 for Matrix3, to reflect its potential use as both a 3D rotation matrix and a 2D affine transform.

    Transform3 is implemented for Matrix4 as well, and I moved the From impls down with the rest of the From impls, in an unrelated edit which I think nonetheless improves readability of what is now a rather large file.

    I'm not positive I've gotten the Transform2 implementation for Matrix3 correct, would appreciate a sanity check :D

    opened by mhintz 13
  • Overload basic operators

    Overload basic operators

    Vector +- Vector Point +- Vector Matrix * Vector Quat * Vector ... probably a lot more, but we need to keep the behavior strictly obvious (i.e. not overloading Vector*Vector as a dot product)

    enhancement 
    opened by kvark 13
  • Make `rand` dependency optional

    Make `rand` dependency optional

    Closes #481

    This PR leaves the feature enabled by default so that this can be released as a minor version soon. (I would suggest to disable it by default in future versions, but that's another discussion.)

    The changes are pretty straight forward with one catch: I changed some use statements to nested imports (otherwise, there would be even more #[cfg(feature = "rand")] lines). Nested imports were stabilized in 1.25 (see the edition guide on this feature). I'm not sure how cgmaths policy on minimum compiler version is. Maybe cgmath already requires a >= 1.25 compiler for other reasons. If my change is a problem, just tell me and I will change the imports back.

    opened by LukasKalbertodt 11
  • Remove Rotation and Transform traits

    Remove Rotation and Transform traits

    Closes #143, #194

    Given the interactions on IRC, they cause more confusion than perhaps they are worth. Perhaps we can re-add them in the future with a better API, but for now I would like to focus more on simplicity.

    The following traits and types have been removed:

    • Rotation types and structs: Rotation, Rotation2, Rotation3, Basis3, Basis3
    • Transform types and structs: Transform, Transform2, Transform3, Decomposed, AffineMatrix3
    opened by brendanzab 11
  • Added checked_normalize

    Added checked_normalize

    Hello, I noticed that there was no method to normalize a vector where the zero vector maps to itself. I looked at the issues and found https://github.com/rustgd/cgmath/issues/450. I thought I might as well implement it.

    Thanks for looking at this,

    • Ruairidh
    opened by RuairidhWilliamson 0
  • Special method for combined invert + transpose for matrices

    Special method for combined invert + transpose for matrices

    Sometimes it's necessary to calculate inverse + transpose matrix, to calculate proper normals matrix, for example. There are (of course) methods to do this. But (i presume) it is not an optimal solution, because invert methods already contain transpose operation. I suggest to add methods like invert_and_transpose, equivalent to invert but without transpose in last step.

    opened by Panzerschrek 0
  • Support infinite far planes

    Support infinite far planes

    Infinite far planes is a standard trick that actually improves the precision of the Z buffer.

    See for instance https://thxforthefish.com/posts/reverse_z/ and https://developer.nvidia.com/content/depth-precision-visualized

    opened by emilk 0
  • Matrix3 multiplication is 4x slower in 0.18

    Matrix3 multiplication is 4x slower in 0.18

    AMD Ryzen 7 3700X Windows 10 19044.1566 rustc 1.60.0-nightly (1e12aef3f 2022-02-13)

    The other day I was testing sprite performance in my engine and noticed it was a lot lower than usual. Investigated the cause and found it was when I updated cgmath from 0.17 to 0.18.

    With 0.17, my benchmark that does 100k translations, rotations, and scales on a Matrix3:

    test bench_transform_matrix ... bench: 670,110 ns/iter (+/- 13,076)

    With 0.18:

    test bench_transform_matrix ... bench: 2,755,590 ns/iter (+/- 10,904)

    The bench itself Code for the transform wrapper

    Since the transform happens for each sprite, the performance difference adds up quickly.

    Using default features with -O2/-O3. Compiler target is x86_64-pc-windows-msvc.

    bug 
    opened by cosmicchipsocket 1
  • Unspecified behavior in `impl_tuple_conversions`

    Unspecified behavior in `impl_tuple_conversions`

    The conversion between a vector and a tuple is defined as follows:

    https://docs.rs/cgmath/0.18.0/src/cgmath/macros.rs.html#226-238

    impl<$S> AsRef<$Tuple> for $ArrayN<$S> {
        #[inline]
        fn as_ref(&self) -> &$Tuple {
            unsafe { mem::transmute(self) }
        }
    }
    
    impl<$S> AsMut<$Tuple> for $ArrayN<$S> {
        #[inline]
        fn as_mut(&mut self) -> &mut $Tuple {
            unsafe { mem::transmute(self) }
        }
    }
    

    which is effectively a cast between &[T; 2] and &(T, T) and contains unspecified behavior since the layout of tuples (exept the unit ()) is not defined.

    https://doc.rust-lang.org/reference/type-layout.html#tuple-layout

    Tuples do not have any guarantees about their layout.

    bug 
    opened by Mokuzzai 2
Owner
rustgd
Rust libraries focused on game development
rustgd
Artsy pixel image to vector graphics converter

inkdrop inkdrop is an artsy bitmap to vector converter. Command line interface The CLI binary is called inkdrop-cli and reads almost any image bitmap

Matthias Vogelgesang 62 Dec 26, 2022
😱 Dead fast thumbnail library for browser and NodeJs! Built with Rust 🦀 and WebAssembly 🕸

thumbo-core ?? Dead fast thumbnail library for browser and NodeJs Built with Rust ?? & WebAssembly ?? ?? About thumbo-core is a thubnail library for b

Victor Aremu 12 Dec 2, 2022
PNG decoding and encoding library in pure Rust

PNG Decoder/Encoder PNG decoder/encoder in pure Rust. It contains all features required to handle the entirety of the PngSuite by Willem van Schack. p

image-rs 247 Dec 25, 2022
Rust library to get image size and format without loading/decoding

imageinfo-rs Rust library to get image size and format without loading/decoding. The imageinfo don't get image format by file ext name, but infer by f

xiaozhuai, Weihang Ding 47 Dec 30, 2022
A Rust library for calculating perceptual hash values of images

img_hash Now builds on stable Rust! (But needs nightly to bench.) A library for getting perceptual hash values of images. Thanks to Dr. Neal Krawetz f

Austin Bonander 264 Dec 9, 2022
A simple steganography library written in rust

steganography A stable steganography library written in rust Crates.io Usage Add the following to the Cargo.toml in your project: [dependencies] stega

Teodor Voinea 79 Dec 9, 2022
Face detection library for the Rust programming language

Rustface SeetaFace detection library for the Rust programming language Example of demo program output SEETAFACE C++ – Github repository for the origin

Andrei Tomashpolskiy 323 Dec 27, 2022
2D polyline/shape library for offsetting, combining, etc.

This project is a continuation of the C++ CavalierContours library rewritten in Rust with the goal of building out more functionality, better

Jedidiah Buck McCready 59 Jan 6, 2023
resvg is an SVG rendering library.

resvg can be used as a Rust library, a C library and as a CLI application to render SVG files based on a static SVG Full 1.1 subset.

Evgeniy Reizner 1.8k Dec 30, 2022
A Simple-to-use, cross-platform Rust Webcam Capture Library

Cross Platform Rust Library for powerful Webcam Capture and Virtual Webcams

null 246 Jan 8, 2023
Rust library for fast image resizing with using of SIMD instructions.

fast_image_resize Rust library for fast image resizing with using of SIMD instructions. CHANGELOG Supported pixel formats and available optimisations:

Kirill Kuzminykh 115 Jan 5, 2023
An advanced image processing library for Rust.

ImageProc Maintainers: @chyh1990 Note: this project is under active depvelopment, API may change! imageproc is a advanced image proccessing library fo

Chen Yuheng 97 Oct 18, 2022
Image operation rust library

Image operation rust library

LongYinan 166 Dec 20, 2022
ePaperify: Framebuffer/image pre-processing library for e-Paper displays

ePaperify: Framebuffer/image pre-processing library for e-Paper displays

Jackson Ming Hu 5 Mar 15, 2022
Antialiased 2D vector drawing library in Rust for Android, Web, Desktop

nonaquad Vector anti-aliased graphics renderer for Android, WASM, Desktop in Rust, using miniquad. This library started as a port of NanoVG for miniqu

Nokola 33 Nov 14, 2022
Antialiased 2D vector drawing library written in Rust

femtovg Join the femtovg Discord channel Work in progress! Antialiased 2D vector drawing library written in Rust.

Tomasz Sterna 0 Aug 24, 2021
Screen-capturer: A cross-platform screenshots library for MacOS、Windows、Linux(X11).

Screen-capturer: A cross-platform screenshots library for MacOS、Windows、Linux(X11).

nashaofu 49 Dec 12, 2022
Takes a folder of images (as a palette), and an image, and figures out how to tile the palette to resemble the image!

Takes a folder of images (as a palette), and an image, and figures out how to tile the palette to resemble the image!

Jacob 258 Dec 30, 2022
Encoding and decoding images in Rust

Image Maintainers: @HeroicKatora, @fintelia How to contribute An Image Processing Library This crate provides basic image processing functions and met

image-rs 3.5k Jan 9, 2023