From b99a6cc6bd93f1355317a1ac49d889b35498158a Mon Sep 17 00:00:00 2001
From: Jopestpe <47086979+Jopestpe@users.noreply.github.com>
Date: Mon, 6 Oct 2025 17:35:18 -0300
Subject: [PATCH] [examples] Added `shapes_recursive_tree` (#5229)
* ADDED: example: shapes_recursive_tree
* [examples] Added shapes_recursive_tree
* [examples] shapes_recursive_tree: adjustments
* Reduced tree depth from 12 to 10
* new shapes_recursive_tree.png
* follow the conventions
* follow the conventions 2
---
examples/Makefile | 1 +
examples/Makefile.Web | 4 +
examples/README.md | 5 +-
examples/examples_list.txt | 1 +
examples/shapes/shapes_recursive_tree.c | 141 ++++++++++++++++++++++
examples/shapes/shapes_recursive_tree.png | Bin 0 -> 18375 bytes
6 files changed, 150 insertions(+), 2 deletions(-)
create mode 100644 examples/shapes/shapes_recursive_tree.c
create mode 100644 examples/shapes/shapes_recursive_tree.png
diff --git a/examples/Makefile b/examples/Makefile
index fb33b4894..a36b9e447 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -559,6 +559,7 @@ SHAPES = \
shapes/shapes_logo_raylib_anim \
shapes/shapes_rectangle_advanced \
shapes/shapes_rectangle_scaling \
+ shapes/shapes_recursive_tree \
shapes/shapes_ring_drawing \
shapes/shapes_rounded_rectangle_drawing \
shapes/shapes_splines_drawing \
diff --git a/examples/Makefile.Web b/examples/Makefile.Web
index 0dbefadf2..2d3018abf 100644
--- a/examples/Makefile.Web
+++ b/examples/Makefile.Web
@@ -559,6 +559,7 @@ SHAPES = \
shapes/shapes_logo_raylib_anim \
shapes/shapes_rectangle_advanced \
shapes/shapes_rectangle_scaling \
+ shapes/shapes_recursive_tree \
shapes/shapes_ring_drawing \
shapes/shapes_rounded_rectangle_drawing \
shapes/shapes_splines_drawing \
@@ -868,6 +869,9 @@ shapes/shapes_rectangle_advanced: shapes/shapes_rectangle_advanced.c
shapes/shapes_rectangle_scaling: shapes/shapes_rectangle_scaling.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_recursive_tree: shapes/shapes_recursive_tree.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
diff --git a/examples/README.md b/examples/README.md
index 70e07df2b..d852e7105 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -17,7 +17,7 @@ You may find it easier to use than other toolchains, especially when it comes to
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
-## EXAMPLES COLLECTION [TOTAL: 172]
+## EXAMPLES COLLECTION [TOTAL: 173]
### category: core [40]
@@ -66,7 +66,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
| [core_undo_redo](core/core_undo_redo.c) |
| ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_input_actions](core/core_input_actions.c) |
| ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) |
-### category: shapes [23]
+### category: shapes [24]
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
@@ -84,6 +84,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| [shapes_following_eyes](shapes/shapes_following_eyes.c) |
| ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [shapes_easings_ball](shapes/shapes_easings_ball.c) |
| ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [shapes_easings_box](shapes/shapes_easings_box.c) |
| ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
+| [shapes_recursive_tree](shapes/shapes_recursive_tree.c) |
| ⭐⭐⭐☆ | 5.6-dev | 5.6-dev| [Jopestpe](https://github.com/jopestpe) |
| [shapes_easings_rectangles](shapes/shapes_easings_rectangles.c) |
| ⭐⭐⭐☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [shapes_ring_drawing](shapes/shapes_ring_drawing.c) |
| ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| [shapes_circle_sector_drawing](shapes/shapes_circle_sector_drawing.c) |
| ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
diff --git a/examples/examples_list.txt b/examples/examples_list.txt
index 50643bf2b..5a0c679a4 100644
--- a/examples/examples_list.txt
+++ b/examples/examples_list.txt
@@ -60,6 +60,7 @@ shapes;shapes_following_eyes;★★☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@
shapes;shapes_easings_ball;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_easings_box;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_easings_rectangles;★★★☆;2.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
+shapes;shapes_recursive_tree;★★★☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
shapes;shapes_ring_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
shapes;shapes_circle_sector_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
shapes;shapes_rounded_rectangle_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
diff --git a/examples/shapes/shapes_recursive_tree.c b/examples/shapes/shapes_recursive_tree.c
new file mode 100644
index 000000000..3ec46de4b
--- /dev/null
+++ b/examples/shapes/shapes_recursive_tree.c
@@ -0,0 +1,141 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - shapes recursive tree
+*
+* Example complexity rating: [★★★☆] 3/4
+*
+* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
+*
+* Example contributed by Jopestpe (@jopestpe)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2018-2025 Jopestpe (@jopestpe)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include
+
+#define RAYGUI_IMPLEMENTATION
+#include "raygui.h" // Required for GUI controls
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+typedef struct {
+ Vector2 start;
+ Vector2 end;
+ float angle;
+ float length;
+} Branch;
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+static Vector2 CalculateBranchEnd(Vector2 start, float angle, float length);
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - shapes recursive tree");
+
+ Vector2 start = { (screenWidth/2.0f) - 125.0f, screenHeight };
+ float angle = 40.0f;
+ float thick = 1.0f;
+ float treeDepth = 10.0f;
+ float branchDecay = 0.66f;
+ float length = 120.0f;
+ bool bezier = false;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+
+ float theta = angle*DEG2RAD;
+ int maxBranches = (int)(powf(2, (int)(treeDepth)));
+ Branch branches[1024] = { 0 };
+ int count = 0;
+
+ Vector2 initialEnd = CalculateBranchEnd(start, 0.0f, length);
+ branches[count++] = (Branch){start, initialEnd, 0.0f, length};
+
+ for (int i = 0; i < count; i++)
+ {
+ Branch branch = branches[i];
+ if (branch.length < 2) continue;
+
+ float nextLength = branch.length*branchDecay;
+
+ if (count < maxBranches && nextLength >= 2)
+ {
+ Vector2 branchStart = branch.end;
+
+ Vector2 branchEnd1 = CalculateBranchEnd(branchStart, branch.angle + theta, nextLength);
+ Vector2 branchEnd2 = CalculateBranchEnd(branchStart, branch.angle - theta, nextLength);
+
+ branches[count++] = (Branch){branchStart, branchEnd1, branch.angle + theta, nextLength};
+ branches[count++] = (Branch){branchStart, branchEnd2, branch.angle - theta, nextLength};
+ }
+ }
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ for (int i = 0; i < count; i++)
+ {
+ Branch branch = branches[i];
+ if (branch.length >= 2)
+ {
+ if (!bezier) DrawLineEx(branch.start, branch.end, thick, RED);
+ else DrawLineBezier(branch.start, branch.end, thick, RED);
+ }
+ }
+
+ DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
+ DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 });
+
+ // Draw GUI controls
+ //------------------------------------------------------------------------------
+ GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f", angle), &angle, 0, 180);
+ GuiSliderBar((Rectangle){ 640, 70, 120, 20 }, "Length", TextFormat("%.0f", length), &length, 12.0f, 240.0f);
+ GuiSliderBar((Rectangle){ 640, 100, 120, 20}, "Decay", TextFormat("%.2f", branchDecay), &branchDecay, 0.1f, 0.78f);
+ GuiSliderBar((Rectangle){ 640, 130, 120, 20 }, "Depth", TextFormat("%.0f", treeDepth), &treeDepth, 1.0f, 10.f);
+ GuiSliderBar((Rectangle){ 640, 160, 120, 20}, "Thick", TextFormat("%.0f", thick), &thick, 1, 8);
+ GuiCheckBox((Rectangle){ 640, 190, 20, 20 }, "Bezier", &bezier);
+ //------------------------------------------------------------------------------
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+static Vector2 CalculateBranchEnd(Vector2 start, float angle, float length)
+{
+ return (Vector2){ start.x + length*sinf(angle), start.y - length*cosf(angle) };
+}
\ No newline at end of file
diff --git a/examples/shapes/shapes_recursive_tree.png b/examples/shapes/shapes_recursive_tree.png
new file mode 100644
index 0000000000000000000000000000000000000000..88932c204bcd24be38c10978b75cda9b002234d8
GIT binary patch
literal 18375
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
VwaZoF7#J8BJYD@<);T3K0RTk?UoZdw
literal 0
HcmV?d00001