66*
77* Example originally created with raylib 5.6, last time updated with raylib 5.6
88*
9- * Example contributed by Hamza RAHAL (@hmz-rhl)
9+ * Example contributed by Hamza RAHAL (@hmz-rhl) and reviewed by Ramon Santamaria (@raysan5)
1010*
1111* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
1212* BSD-like license that allows static linking with closed source software
1717
1818
1919#include "raylib.h"
20- #include "raymath.h"
21- #include <stdlib.h>
22- #include <stdio.h>
2320
24- const int screenWidth = 800 ;
21+ #define RAYGUI_IMPLEMENTATION
22+ #include "raygui.h"
2523
26- const int screenHeight = 450 ;
27-
28- int order = 2 ;
29-
30- int total ;
31-
32- int counter = 0 ;
33-
34- Vector2 * hilbertPath = 0 ;
35-
36- const Vector2 hilbertPoints [4 ] =
37- {
38- [0 ] = {
39- .x = 0 ,
40- .y = 0
41- },
42- [1 ] = {
43- .x = 0 ,
44- .y = 1
45- },
46- [2 ] = {
47- .x = 1 ,
48- .y = 1
49- },
50- [3 ] = {
51- .x = 1 ,
52- .y = 0
53- },
54- };
24+ #include <stdlib.h> // Required for: calloc(), free()
5525
5626//------------------------------------------------------------------------------------
5727// Module Functions Declaration
5828//------------------------------------------------------------------------------------
59- Vector2 Hilbert (int index );
60-
61- void InitHilbertPath ( void );
29+ static Vector2 * LoadHilbertPath (int order , float size , int * strokeCount );
30+ static void UnloadHilbertPath ( Vector2 * hilbertPath );
31+ static Vector2 ComputeHilbertStep ( int order , int index );
6232
6333//------------------------------------------------------------------------------------
6434// Program main entry point
@@ -67,13 +37,23 @@ int main(void)
6737{
6838 // Initialization
6939 //--------------------------------------------------------------------------------------
40+ const int screenWidth = 800 ;
41+ const int screenHeight = 450 ;
7042
71- InitWindow (screenWidth , screenHeight , "raylib [shapes] example - hilbert curve example" );
72-
73- SetTargetFPS (60 ); // Set our game to run at 60 frames-per-second
43+ InitWindow (screenWidth , screenHeight , "raylib [shapes] example - hilbert curve" );
7444
75- InitHilbertPath ();
45+ int order = 2 ;
46+ float size = GetScreenHeight ();
47+ int strokeCount = 0 ;
48+ Vector2 * hilbertPath = LoadHilbertPath (order , size , & strokeCount );
7649
50+ int prevOrder = order ;
51+ int prevSize = (int )size ; // NOTE: Size from slider is float but for comparison we use int
52+ int counter = 0 ;
53+ float thick = 2.0f ;
54+ bool animate = true;
55+
56+ SetTargetFPS (60 ); // Set our game to run at 60 frames-per-second
7757 //--------------------------------------------------------------------------------------
7858
7959 // Main game loop
@@ -82,106 +62,135 @@ int main(void)
8262 {
8363 // Update
8464 //----------------------------------------------------------------------------------
85- if ((IsKeyPressed (KEY_UP )) && (order < 8 ))
65+ // Check if order or size have changed to regenerate
66+ // NOTE: Size from slider is float but for comparison we use int
67+ if ((prevOrder != order ) || (prevSize != (int )size ))
8668 {
87- counter = 0 ;
88- ++ order ;
89- InitHilbertPath ();
90- }
91- else if ((IsKeyPressed (KEY_DOWN )) && (order > 1 ))
92- {
93- counter = 0 ;
94- -- order ;
95- InitHilbertPath ();
69+ UnloadHilbertPath (hilbertPath );
70+ hilbertPath = LoadHilbertPath (order , size , & strokeCount );
71+
72+ if (animate ) counter = 0 ;
73+ else counter = strokeCount ;
74+
75+ prevOrder = order ;
76+ prevSize = size ;
9677 }
9778 //----------------------------------------------------------------------------------
9879
9980 // Draw
10081 //--------------------------------------------------------------------------
10182 BeginDrawing ();
102- DrawText (TextFormat ("(press UP or DOWN to change)\norder : %d" , order ), screenWidth /2 + 70 , 25 , 20 , WHITE );
10383
104- if (counter < total )
105- {
106- ClearBackground (BLACK );
107- for (int i = 1 ; i <= counter ; i ++ )
84+ ClearBackground (RAYWHITE );
85+
86+ if (counter < strokeCount )
10887 {
109- DrawLineV (hilbertPath [i ], hilbertPath [i - 1 ], ColorFromHSV (((float )i / total ) * 360.0f , 1.0f , 1.0f ));
88+ // Draw Hilbert path animation, one stroke every frame
89+ for (int i = 1 ; i <= counter ; i ++ )
90+ {
91+ DrawLineEx (hilbertPath [i ], hilbertPath [i - 1 ], thick , ColorFromHSV (((float )i /strokeCount )* 360.0f , 1.0f , 1.0f ));
92+ }
93+
94+ counter += 1 ;
11095 }
111- counter += 1 ;
112- }
96+ else
97+ {
98+ // Draw full Hilbert path
99+ for (int i = 1 ; i < strokeCount ; i ++ )
100+ {
101+ DrawLineEx (hilbertPath [i ], hilbertPath [i - 1 ], thick , ColorFromHSV (((float )i /strokeCount )* 360.0f , 1.0f , 1.0f ));
102+ }
103+ }
104+
105+ // Draw UI using raygui
106+ GuiCheckBox ((Rectangle ){ 450 , 50 , 20 , 20 }, "ANIMATE GENERATION ON CHANGE" , & animate );
107+ GuiSpinner ((Rectangle ){ 585 , 100 , 180 , 30 }, "HILBERT CURVE ORDER: " , & order , 2 , 8 , false);
108+ GuiSlider ((Rectangle ){ 524 , 150 , 240 , 24 }, "THICKNESS: " , NULL , & thick , 1.0f , 10.0f );
109+ GuiSlider ((Rectangle ){ 524 , 190 , 240 , 24 }, "TOTAL SIZE: " , NULL , & size , 10.0f , GetScreenHeight ()* 1.5f );
110+
113111 EndDrawing ();
114112 //--------------------------------------------------------------------------
115113 }
116114 //--------------------------------------------------------------------------------------
117115
118116 // De-Initialization
119117 //--------------------------------------------------------------------------------------
118+ UnloadHilbertPath (hilbertPath );
119+
120120 CloseWindow (); // Close window and OpenGL context
121- MemFree (hilbertPath );
122121 //--------------------------------------------------------------------------------------
123122 return 0 ;
124123}
125124
126125//------------------------------------------------------------------------------------
127126// Module Functions Definition
128127//------------------------------------------------------------------------------------
128+ // Load the whole Hilbert Path (including each U and their link)
129+ static Vector2 * LoadHilbertPath (int order , float size , int * strokeCount )
130+ {
131+ int N = 1 << order ;
132+ float len = size /N ;
133+ * strokeCount = N * N ;
129134
130- // calculate U positions
131- Vector2 Hilbert (int index )
135+ Vector2 * hilbertPath = (Vector2 * )RL_CALLOC (* strokeCount , sizeof (Vector2 ));
136+
137+ for (int i = 0 ; i < * strokeCount ; i ++ )
138+ {
139+ hilbertPath [i ] = ComputeHilbertStep (order , i );
140+ hilbertPath [i ].x = hilbertPath [i ].x * len + len /2.0f ;
141+ hilbertPath [i ].y = hilbertPath [i ].y * len + len /2.0f ;
142+ }
143+
144+ return hilbertPath ;
145+ }
146+
147+ // Unload Hilbert path data
148+ static void UnloadHilbertPath (Vector2 * hilbertPath )
132149{
150+ RL_FREE (hilbertPath );
151+ }
133152
134- int hiblertIndex = index & 3 ;
135- Vector2 vect = hilbertPoints [hiblertIndex ];
136- float temp ;
137- int len ;
153+ // Compute Hilbert path U positions
154+ static Vector2 ComputeHilbertStep (int order , int index )
155+ {
156+ // Hilbert points base pattern
157+ static const Vector2 hilbertPoints [4 ] = {
158+ [0 ] = { .x = 0 , .y = 0 },
159+ [1 ] = { .x = 0 , .y = 1 },
160+ [2 ] = { .x = 1 , .y = 1 },
161+ [3 ] = { .x = 1 , .y = 0 },
162+ };
163+
164+ int hilbertIndex = index & 3 ;
165+ Vector2 vect = hilbertPoints [hilbertIndex ];
166+ float temp = 0.0f ;
167+ int len = 0 ;
138168
139169 for (int j = 1 ; j < order ; j ++ )
140170 {
141- index = index >>2 ;
142- hiblertIndex = index & 3 ;
143- len = 1 <<j ;
144- switch (hiblertIndex )
171+ index = index >> 2 ;
172+ hilbertIndex = index & 3 ;
173+ len = 1 << j ;
174+
175+ switch (hilbertIndex )
145176 {
146177 case 0 :
178+ {
147179 temp = vect .x ;
148180 vect .x = vect .y ;
149181 vect .y = temp ;
150- break ;
151- case 2 :
152- vect .x += len ;
153- case 1 :
154- vect .y += len ;
155- break ;
182+ } break ;
183+ case 2 : vect .x += len ;
184+ case 1 : vect .y += len ; break ;
156185 case 3 :
186+ {
157187 temp = len - 1 - vect .x ;
158188 vect .x = 2 * len - 1 - vect .y ;
159189 vect .y = temp ;
160- break ;
190+ } break ;
191+ default : break ;
161192 }
162193 }
194+
163195 return vect ;
164196}
165-
166- // Calculate the whole Hilbert Path (including each U and their link)
167- void InitHilbertPath (void )
168- {
169- int N ;
170- float len ;
171- N = 1 <<order ;
172- total = N * N ;
173- MemFree (hilbertPath );
174- hilbertPath = NULL ;
175- hilbertPath = (Vector2 * )MemAlloc (sizeof (Vector2 )* total );
176- if (hilbertPath == NULL )
177- {
178- printf ("%s: malloc failed\n" , __func__ );
179- }
180- len = (float )screenHeight /N ;
181- for (int i = 0 ; i < total ; i ++ )
182- {
183- hilbertPath [i ] = Hilbert (i );
184- hilbertPath [i ].x = hilbertPath [i ].x * len + len /2.0f ;
185- hilbertPath [i ].y = hilbertPath [i ].y * len + len /2.0f ;
186- }
187- }
0 commit comments