Browse Source

REVIEWED: example: `shapes_penrose_tile` formating

pull/5356/merge
Ray 1 day ago
parent
commit
d3addad9a7
1 changed files with 161 additions and 159 deletions
  1. +161
    -159
      examples/shapes/shapes_penrose_tile.c

+ 161
- 159
examples/shapes/shapes_penrose_tile.c View File

@ -16,14 +16,18 @@
*
********************************************************************************************/
#include "raylib.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "raylib.h"
#define STR_MAX_SIZE 10000
#define TURTLE_STACK_MAX_SIZE 50
#define STR_MAX_SIZE 10000
#define TURTLE_STACK_MAX_SIZE 50
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct TurtleState {
Vector2 origin;
double angle;
@ -40,32 +44,111 @@ typedef struct PenroseLSystem {
float theta;
} PenroseLSystem;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static TurtleState turtleStack[TURTLE_STACK_MAX_SIZE];
static int turtleTop = -1;
void PushTurtleState(TurtleState state)
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
static void PushTurtleState(TurtleState state);
static TurtleState PopTurtleState(void);
static PenroseLSystem CreatePenroseLSystem(float drawLength);
static void BuildProductionStep(PenroseLSystem *ls);
static void BuildPenroseLSystem(PenroseLSystem *ls, float drawLength, int generations);
static void DrawPenroseLSystem(PenroseLSystem *ls);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
if (turtleTop < TURTLE_STACK_MAX_SIZE - 1)
{
turtleStack[++turtleTop] = state;
}
else
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - penrose tile");
float drawLength = 460.0f;
int minGenerations = 0;
int maxGenerations = 4;
int generations = 0;
PenroseLSystem ls = {0};
BuildPenroseLSystem(&ls, drawLength*(generations/(float)maxGenerations), generations);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
TraceLog(LOG_WARNING, "TURTLE STACK OVERFLOW!");
// Update
//----------------------------------------------------------------------------------
bool rebuild = false;
if (IsKeyPressed(KEY_UP))
{
if (generations < maxGenerations)
{
generations++;
rebuild = true;
}
}
else if (IsKeyPressed(KEY_DOWN))
{
if (generations > minGenerations)
{
generations--;
if (generations > 0) rebuild = true;
}
}
if (rebuild) BuildPenroseLSystem(&ls, drawLength*(generations/(float)maxGenerations), generations);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground( RAYWHITE );
if (generations > 0) DrawPenroseLSystem(&ls);
DrawText("penrose l-system", 10, 10, 20, DARKGRAY);
DrawText("press up or down to change generations", 10, 30, 20, DARKGRAY);
DrawText(TextFormat("generations: %d", generations), 10, 50, 20, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
void PushTurtleState(TurtleState state)
{
if (turtleTop < (TURTLE_STACK_MAX_SIZE - 1)) turtleStack[++turtleTop] = state;
else TraceLog(LOG_WARNING, "TURTLE STACK OVERFLOW!");
}
TurtleState PopTurtleState(void)
{
if (turtleTop >= 0)
{
return turtleStack[turtleTop--];
}
else
{
TraceLog(LOG_WARNING, "TURTLE STACK UNDERFLOW!");
}
return (TurtleState) {0};
if (turtleTop >= 0) return turtleStack[turtleTop--];
else TraceLog(LOG_WARNING, "TURTLE STACK UNDERFLOW!");
return (TurtleState){ 0 };
}
PenroseLSystem CreatePenroseLSystem(float drawLength)
@ -77,86 +160,19 @@ PenroseLSystem CreatePenroseLSystem(float drawLength)
.ruleY = "-WF++XF[+++YF++ZF]-",
.ruleZ = "--YF++++WF[+ZF++++XF]--XF",
.drawLength = drawLength,
.theta = 36.0f // in degrees
.theta = 36.0f // Degrees
};
ls.production = (char*) malloc(sizeof(char) * STR_MAX_SIZE);
ls.production = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
ls.production[0] = '\0';
strncpy(ls.production, "[X]++[X]++[X]++[X]++[X]", STR_MAX_SIZE);
return ls;
}
void DrawPenroseLSystem(PenroseLSystem *ls)
{
Vector2 screenCenter = {GetScreenWidth()/2, GetScreenHeight()/2};
TurtleState turtle = {
.origin = {0},
.angle = -90.0f
};
int repeats = 1;
int productionLength = (int) strnlen(ls->production, STR_MAX_SIZE);
ls->steps += 12;
if (ls->steps > productionLength)
{
ls->steps = productionLength;
}
for (int i = 0; i < ls->steps; i++)
{
char step = ls->production[i];
if ( step == 'F' )
{
for ( int j = 0; j < repeats; j++ )
{
Vector2 startPosWorld = turtle.origin;
float radAngle = DEG2RAD * turtle.angle;
turtle.origin.x += ls->drawLength * cosf(radAngle);
turtle.origin.y += ls->drawLength * sinf(radAngle);
Vector2 startPosScreen = {startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y};
Vector2 endPosScreen = {turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y};
DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2));
}
repeats = 1;
}
else if ( step == '+' )
{
for ( int j = 0; j < repeats; j++ )
{
turtle.angle += ls->theta;
}
repeats = 1;
}
else if ( step == '-' )
{
for ( int j = 0; j < repeats; j++ )
{
turtle.angle += -ls->theta;
}
repeats = 1;
}
else if ( step == '[' )
{
PushTurtleState(turtle);
}
else if ( step == ']' )
{
turtle = PopTurtleState();
}
else if ( ( step >= 48 ) && ( step <= 57 ) )
{
repeats = (int) step - 48;
}
}
turtleTop = -1;
return ls;
}
void BuildProductionStep(PenroseLSystem *ls)
{
char *newProduction = (char*) malloc(sizeof(char) * STR_MAX_SIZE);
char *newProduction = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
newProduction[0] = '\0';
int productionLength = strnlen(ls->production, STR_MAX_SIZE);
@ -177,7 +193,7 @@ void BuildProductionStep(PenroseLSystem *ls)
{
int t = strnlen(newProduction, STR_MAX_SIZE);
newProduction[t] = step;
newProduction[t+1] = '\0';
newProduction[t + 1] = '\0';
}
} break;
}
@ -185,89 +201,75 @@ void BuildProductionStep(PenroseLSystem *ls)
ls->drawLength *= 0.5f;
strncpy(ls->production, newProduction, STR_MAX_SIZE);
free( newProduction );
RL_FREE(newProduction);
}
void BuildPenroseLSystem(PenroseLSystem *ls, float drawLength, int generations)
{
*ls = CreatePenroseLSystem(drawLength);
for (int i = 0; i < generations; i++)
{
BuildProductionStep(ls);
}
for (int i = 0; i < generations; i++) BuildProductionStep(ls);
}
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
void DrawPenroseLSystem(PenroseLSystem *ls)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
SetConfigFlags( FLAG_MSAA_4X_HINT );
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - penrose tile");
float drawLength = 460.0f;
int minGenerations = 0;
int maxGenerations = 4;
int generations = 0;
Vector2 screenCenter = { GetScreenWidth()/2, GetScreenHeight()/2 };
PenroseLSystem ls = {0};
BuildPenroseLSystem(&ls, drawLength * (generations / (float) maxGenerations), generations);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
TurtleState turtle = {
.origin = {0},
.angle = -90.0f
};
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
int repeats = 1;
int productionLength = (int)strnlen(ls->production, STR_MAX_SIZE);
ls->steps += 12;
if (ls->steps > productionLength) ls->steps = productionLength;
for (int i = 0; i < ls->steps; i++)
{
// Update
//----------------------------------------------------------------------------------
bool rebuild = false;
if (IsKeyPressed(KEY_UP))
char step = ls->production[i];
if (step == 'F')
{
if (generations < maxGenerations)
for (int j = 0; j < repeats; j++)
{
generations++;
rebuild = true;
Vector2 startPosWorld = turtle.origin;
float radAngle = DEG2RAD*turtle.angle;
turtle.origin.x += ls->drawLength*cosf(radAngle);
turtle.origin.y += ls->drawLength*sinf(radAngle);
Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y };
Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y };
DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2));
}
}
else if (IsKeyPressed(KEY_DOWN))
repeats = 1;
}
else if (step == '+')
{
if (generations > minGenerations)
{
generations--;
rebuild = generations > 0;
}
}
if (rebuild)
for (int j = 0; j < repeats; j++) turtle.angle += ls->theta;
repeats = 1;
}
else if (step == '-')
{
BuildPenroseLSystem(&ls, drawLength * (generations / (float) maxGenerations), generations);
}
//----------------------------------------------------------------------------------
for (int j = 0; j < repeats; j++) turtle.angle += -ls->theta;
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground( RAYWHITE );
if (generations > 0)
{
DrawPenroseLSystem(&ls);
}
DrawText("penrose l-system", 10, 10, 20, DARKGRAY);
DrawText("press up or down to change generations", 10, 30, 20, DARKGRAY);
DrawText(TextFormat("generations: %d", generations), 10, 50, 20, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
repeats = 1;
}
else if (step == '[')
{
PushTurtleState(turtle);
}
else if (step == ']')
{
turtle = PopTurtleState();
}
else if ((step >= 48) && (step <= 57))
{
repeats = (int) step - 48;
}
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
turtleTop = -1;
}

Loading…
Cancel
Save