#z-order #fractal #curve #morton

no-std morton-encoding

A crate for encoding and decoding Morton ("Z-order") keys

4 stable releases

2.0.1 Mar 26, 2021
2.0.0 Mar 22, 2021
1.0.1 Dec 31, 2019
1.0.0 Nov 28, 2019

#692 in Algorithms

Download history 35/week @ 2023-06-07 114/week @ 2023-06-14 180/week @ 2023-06-21 129/week @ 2023-06-28 181/week @ 2023-07-05 97/week @ 2023-07-12 131/week @ 2023-07-19 133/week @ 2023-07-26 68/week @ 2023-08-02 132/week @ 2023-08-09 140/week @ 2023-08-16 112/week @ 2023-08-23 159/week @ 2023-08-30 164/week @ 2023-09-06 130/week @ 2023-09-13 101/week @ 2023-09-20

588 downloads per month
Used in 4 crates


730 lines

Morton encoding (Z-order encoding)


The morton-encoding crate offers convenience functions for transforming arrays of primitive unsigned integers to Morton keys and back, via the eponymous encoding process, which basically groups all same-order bits together. This helps linearise data points while preserving some measure of locality.

This crate was originally built with fractal analysis in mind. Nevertheless, Morton encoding can also be used for other use-cases, such as the efficient searching of data-bases.

The lindel crate is an extension of this one, also containing Hilbert functions.


The morton_encode and morton_decode functions ought to be sufficient for most use-cases. They are used as follows:

let input = 992;
let output: [u8; 5] = morton_decode(input);
assert_eq!(output, [2u8; 5]);
let input = [543u32, 23765];
let encoded_input: u64 = morton_encode(input);
let reassembled_input: [u32; 2] = morton_decode(encoded_input);
assert_eq!(input, reassembled_input);

For more detailed information, as well as information on other similar crates, please look at the documentation.


The Morton encoding can be computed very efficiently and branchlessly. For use-cases where one needs to keep splitting the available space recursively into halves, it's unmatched; quad-trees and oct-trees are a great example of that.


Morton encoding in general isn't very good at preserving locality, at least when compared to eg Hilbert encoding. Furthermore, the present crate only implements it for cases where each coordinate has the same amount of significant bits; for cases where that's not true, the user is urged to use lindel instead.