GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
gp_hilbert_curve.h
1// SPDX-License-Identifier: LGPL-2.1-or-later
2/*
3 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz>
4 */
5
6/*
7
8 Hilbert curve implementation.
9
10 */
11
12#ifndef FILTERS_GP_HILBERT_CURVE_H
13#define FILTERS_GP_HILBERT_CURVE_H
14
15typedef struct gp_curve_state {
16 /* half of the number of bits of curve size */
17 unsigned int n;
18 /* coordinates */
19 unsigned int x, y;
20 /* current curve lenght */
21 unsigned int s;
22} gp_curve_state;
23
24/*
25 * Resets curve to initial state i.e. x = 0, y = 0, (length) s = 0.
26 */
27static inline void gp_hilbert_curve_init(gp_curve_state *state, int n)
28{
29 state->n = n;
30 state->s = 0;
31 state->x = 0;
32 state->y = 0;
33}
34
35/*
36 * Variant of Lam and Shapiro
37 */
38static inline void gp_hilbert_curve_getxy(gp_curve_state *state)
39{
40 int sa, sb;
41 /*
42 * Older gcc thinks that x and y are used uninitialized that is not
43 * true so we silence the warning by initializing them.
44 */
45 unsigned int i, temp, x = 0, y = 0;
46
47 for (i = 0; i < 2 * state->n; i += 2) {
48 sa = (state->s >> (i+1)) & 0x01;
49 sb = (state->s >> i) & 0x01;
50
51 if ((sa ^ sb) == 0) {
52 temp = x;
53 x = y ^ (-sa);
54 y = temp ^ (-sa);
55 }
56
57 x = (x >> 1) | (sa << 31);
58 y = (y >> 1) | ((sa ^ sb) << 31);
59 }
60
61 state->x = x >> (32 - state->n);
62 state->y = y >> (32 - state->n);
63}
64
65
66/*
67 * Finds next X and Y
68 */
69static inline void gp_hilbert_curve_next(gp_curve_state *state)
70{
71
72 /* increment length */
73 state->s++;
74 /* get X and Y */
75 gp_hilbert_curve_getxy(state);
76}
77
78/*
79 * Returns true if we are not at curve endpoint
80 */
81static inline int gp_hilbert_curve_continues(gp_curve_state *state)
82{
83 return state->s < (1U<<(2*state->n));
84}
85
86#endif /* FILTERS_GP_HILBERT_CURVE_H */