1
+ /*******************************************************************************************
2
+ *
3
+ * raylib [shapes] example - shapes recursive tree
4
+ *
5
+ * Example complexity rating: [★★★☆] 3/4
6
+ *
7
+ * Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
8
+ *
9
+ * Example contributed by Jopestpe (@jopestpe)
10
+ *
11
+ * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
12
+ * BSD-like license that allows static linking with closed source software
13
+ *
14
+ * Copyright (c) 2018-2025 Jopestpe (@jopestpe)
15
+ *
16
+ ********************************************************************************************/
17
+
18
+ #include "raylib.h"
19
+ #include <math.h>
20
+
21
+ #define RAYGUI_IMPLEMENTATION
22
+ #include "raygui.h" // Required for GUI controls
23
+
24
+ //----------------------------------------------------------------------------------
25
+ // Types and Structures Definition
26
+ //----------------------------------------------------------------------------------
27
+ typedef struct {
28
+ Vector2 start ;
29
+ Vector2 end ;
30
+ float angle ;
31
+ float length ;
32
+ } Branch ;
33
+
34
+ //----------------------------------------------------------------------------------
35
+ // Module Functions Declaration
36
+ //----------------------------------------------------------------------------------
37
+ static Vector2 CalculateBranchEnd (Vector2 start , float angle , float length );
38
+
39
+ //------------------------------------------------------------------------------------
40
+ // Program main entry point
41
+ //------------------------------------------------------------------------------------
42
+ int main (void )
43
+ {
44
+ // Initialization
45
+ //--------------------------------------------------------------------------------------
46
+ const int screenWidth = 800 ;
47
+ const int screenHeight = 450 ;
48
+
49
+ InitWindow (screenWidth , screenHeight , "raylib [shapes] example - shapes recursive tree" );
50
+
51
+ Vector2 start = { (screenWidth /2.0f ) - 125.0f , screenHeight };
52
+ float angle = 40.0f ;
53
+ float thick = 1.0f ;
54
+ float treeDepth = 10.0f ;
55
+ float branchDecay = 0.66f ;
56
+ float length = 120.0f ;
57
+ bool bezier = false;
58
+
59
+ SetTargetFPS (60 ); // Set our game to run at 60 frames-per-second
60
+ //--------------------------------------------------------------------------------------
61
+
62
+ // Main game loop
63
+ while (!WindowShouldClose ()) // Detect window close button or ESC key
64
+ {
65
+ // Update
66
+ //----------------------------------------------------------------------------------
67
+
68
+ float theta = angle * DEG2RAD ;
69
+ int maxBranches = (int )(powf (2 , (int )(treeDepth )));
70
+ Branch branches [1024 ] = { 0 };
71
+ int count = 0 ;
72
+
73
+ Vector2 initialEnd = CalculateBranchEnd (start , 0.0f , length );
74
+ branches [count ++ ] = (Branch ){start , initialEnd , 0.0f , length };
75
+
76
+ for (int i = 0 ; i < count ; i ++ )
77
+ {
78
+ Branch branch = branches [i ];
79
+ if (branch .length < 2 ) continue ;
80
+
81
+ float nextLength = branch .length * branchDecay ;
82
+
83
+ if (count < maxBranches && nextLength >= 2 )
84
+ {
85
+ Vector2 branchStart = branch .end ;
86
+
87
+ Vector2 branchEnd1 = CalculateBranchEnd (branchStart , branch .angle + theta , nextLength );
88
+ Vector2 branchEnd2 = CalculateBranchEnd (branchStart , branch .angle - theta , nextLength );
89
+
90
+ branches [count ++ ] = (Branch ){branchStart , branchEnd1 , branch .angle + theta , nextLength };
91
+ branches [count ++ ] = (Branch ){branchStart , branchEnd2 , branch .angle - theta , nextLength };
92
+ }
93
+ }
94
+
95
+ // Draw
96
+ //----------------------------------------------------------------------------------
97
+ BeginDrawing ();
98
+
99
+ ClearBackground (RAYWHITE );
100
+
101
+ for (int i = 0 ; i < count ; i ++ )
102
+ {
103
+ Branch branch = branches [i ];
104
+ if (branch .length >= 2 )
105
+ {
106
+ if (!bezier ) DrawLineEx (branch .start , branch .end , thick , RED );
107
+ else DrawLineBezier (branch .start , branch .end , thick , RED );
108
+ }
109
+ }
110
+
111
+ DrawLine (580 , 0 , 580 , GetScreenHeight (), (Color ){ 218 , 218 , 218 , 255 });
112
+ DrawRectangle (580 , 0 , GetScreenWidth (), GetScreenHeight (), (Color ){ 232 , 232 , 232 , 255 });
113
+
114
+ // Draw GUI controls
115
+ //------------------------------------------------------------------------------
116
+ GuiSliderBar ((Rectangle ){ 640 , 40 , 120 , 20 }, "Angle" , TextFormat ("%.0f" , angle ), & angle , 0 , 180 );
117
+ GuiSliderBar ((Rectangle ){ 640 , 70 , 120 , 20 }, "Length" , TextFormat ("%.0f" , length ), & length , 12.0f , 240.0f );
118
+ GuiSliderBar ((Rectangle ){ 640 , 100 , 120 , 20 }, "Decay" , TextFormat ("%.2f" , branchDecay ), & branchDecay , 0.1f , 0.78f );
119
+ GuiSliderBar ((Rectangle ){ 640 , 130 , 120 , 20 }, "Depth" , TextFormat ("%.0f" , treeDepth ), & treeDepth , 1.0f , 10.f );
120
+ GuiSliderBar ((Rectangle ){ 640 , 160 , 120 , 20 }, "Thick" , TextFormat ("%.0f" , thick ), & thick , 1 , 8 );
121
+ GuiCheckBox ((Rectangle ){ 640 , 190 , 20 , 20 }, "Bezier" , & bezier );
122
+ //------------------------------------------------------------------------------
123
+
124
+ DrawFPS (10 , 10 );
125
+
126
+ EndDrawing ();
127
+ //----------------------------------------------------------------------------------
128
+ }
129
+
130
+ // De-Initialization
131
+ //--------------------------------------------------------------------------------------
132
+ CloseWindow (); // Close window and OpenGL context
133
+ //--------------------------------------------------------------------------------------
134
+
135
+ return 0 ;
136
+ }
137
+
138
+ static Vector2 CalculateBranchEnd (Vector2 start , float angle , float length )
139
+ {
140
+ return (Vector2 ){ start .x + length * sinf (angle ), start .y - length * cosf (angle ) };
141
+ }
0 commit comments