-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[examples] Added shapes_math_sine_cosine
(#5209)
#5237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
/******************************************************************************************* | ||
* | ||
* raylib [shapes] example - math sine cosine | ||
* | ||
* Port of the p5.js "sine and cosine" demo to raylib + raygui | ||
* Sources: https://p5js.org/examples/angles-and-motion-sine-cosine/ | ||
* | ||
* Demonstrates uniform circular motion and the correspondence between | ||
* the unit circle and sine / cosine graphs. Right panel contains a | ||
* play/pause toggle implemented with raygui. | ||
* | ||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev | ||
* | ||
* Copyright (c) 2025 Olivier (@oqu) | ||
* | ||
********************************************************************************************/ | ||
|
||
#include "raylib.h" | ||
|
||
// Required for GUI controls | ||
#define RAYGUI_IMPLEMENTATION | ||
#include "raygui.h" | ||
|
||
#include <math.h> | ||
|
||
int main(void) | ||
{ | ||
// Window initialization | ||
const int screenWidth = 800; | ||
const int screenHeight = 450; | ||
|
||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math sine cosine"); | ||
const char* playText = "Play"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please, review raylib code conventions: https://github.com/raysan5/raylib/blob/master/CONVENTIONS.md |
||
const char* pauseText = "Pause"; | ||
|
||
// Scene layout (mimic p5 example positioning) | ||
const float circleX = 200.0f; | ||
const float circleY = 150.0f; | ||
const float circleRadius = 75.0f; | ||
|
||
const float graphX = 50.0f; | ||
const float graphY = 300.0f; | ||
const float graphAmplitude = 50.0f; | ||
const float graphPeriod = 300.0f; // width of the graph in pixels | ||
|
||
// Animation / UI state | ||
bool playing = true; // play / pause toggle | ||
int frameCountLocal = 0; // local frame counter (used when playing) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please, review raylib code conventions: https://github.com/raysan5/raylib/blob/master/CONVENTIONS.md Comments should start with capital letter |
||
|
||
SetTargetFPS(60); | ||
|
||
// Main loop | ||
while (!WindowShouldClose()) | ||
{ | ||
// Handle GUI and input first | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please, note that Update and Draw should be in separate sections. |
||
BeginDrawing(); | ||
|
||
ClearBackground(BLACK); | ||
|
||
// Right control panel | ||
float panelX = (float)GetScreenWidth() - 270.0f; | ||
Rectangle panel = {panelX, 10, 260, (float)GetScreenHeight() - 20}; | ||
DrawRectangleRec(panel, Fade(LIGHTGRAY, 0.6f)); | ||
DrawRectangleLinesEx(panel, 1, GRAY); | ||
|
||
int y = 20; | ||
int px = (int)panelX + 10; | ||
DrawText("Sine / Cosine Demo", px, y, 20, DARKGRAY); | ||
y += 34; | ||
|
||
// Play / Pause toggle | ||
DrawText("Animation:", px, y, 14, DARKGRAY); | ||
y += 18; | ||
GuiToggle((Rectangle){(float)px, y, 220, 30}, playing ? pauseText : playText, &playing); | ||
y += 40; | ||
|
||
// Small description | ||
DrawText("Animated demonstration of a point moving", px, y, 10, DARKGRAY); | ||
y += 14; | ||
DrawText("around the unit circle and the corresponding", px, y, 10, DARKGRAY); | ||
y += 14; | ||
DrawText("sine (red) and cosine (orange) graphs.", px, y, 10, DARKGRAY); | ||
y += 30; | ||
|
||
DrawFPS(px, GetScreenHeight() - 30); | ||
|
||
// Update frameCount if playing | ||
if (playing) | ||
frameCountLocal++; | ||
|
||
// Angle in degrees (like the p5 example) | ||
int angleDeg = frameCountLocal % 360; | ||
|
||
// Draw angle label | ||
Color labelCol = WHITE; | ||
DrawText(TextFormat("angle: %d", angleDeg), 25, 25, 20, labelCol); | ||
|
||
// --- Draw circle and diameters --- | ||
// circle outer | ||
DrawCircleLines((int)circleX, (int)circleY, circleRadius, Fade(GRAY, 0.6f)); | ||
// diameters | ||
DrawLine((int)circleX, (int)(circleY - circleRadius), (int)circleX, (int)(circleY + circleRadius), Fade(GRAY, 0.6f)); | ||
DrawLine((int)(circleX - circleRadius), (int)circleY, (int)(circleX + circleRadius), (int)circleY, Fade(GRAY, 0.6f)); | ||
|
||
// Compute moving point on circle (cos for x, sin for y). Note: cos/sin in C expect radians | ||
float angRad = angleDeg * (PI / 180.0f); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please, review raylib code conventions: https://github.com/raysan5/raylib/blob/master/CONVENTIONS.md
|
||
float pointX = circleX + circleRadius * cosf(angRad); | ||
float pointY = circleY - circleRadius * sinf(angRad); // minus to match p5 y-axis direction | ||
|
||
// line from center to point | ||
DrawLine((int)circleX, (int)circleY, (int)pointX, (int)pointY, Fade(GRAY, 0.6f)); | ||
|
||
// moving points | ||
DrawCircleV((Vector2){pointX, pointY}, 6.0f, WHITE); | ||
DrawCircle((int)pointX, (int)circleY, 6.0f, ORANGE); | ||
DrawCircle((int)circleX, (int)pointY, 6.0f, RED); | ||
|
||
// --- Draw graph area axes --- | ||
// axes lines | ||
DrawLine((int)graphX, (int)graphY, (int)(graphX + graphPeriod), (int)graphY, Fade(GRAY, 0.6f)); | ||
DrawLine((int)graphX, (int)(graphY - graphAmplitude), (int)graphX, (int)(graphY + graphAmplitude), Fade(GRAY, 0.6f)); | ||
DrawLine((int)(graphX + graphPeriod), (int)(graphY - graphAmplitude), (int)(graphX + graphPeriod), (int)(graphY + graphAmplitude), Fade(GRAY, 0.6f)); | ||
|
||
// labels | ||
DrawText("0", (int)graphX - 6, (int)(graphY + graphAmplitude + 6), 14, Fade(GRAY, 0.9f)); | ||
DrawText("360", (int)(graphX + graphPeriod) - 12, (int)(graphY + graphAmplitude + 6), 14, Fade(GRAY, 0.9f)); | ||
DrawText("1", (int)(graphX / 2) - 6, (int)(graphY - graphAmplitude) - 6, 14, Fade(GRAY, 0.9f)); | ||
DrawText("0", (int)(graphX / 2) - 6, (int)(graphY)-6, 14, Fade(GRAY, 0.9f)); | ||
DrawText("-1", (int)(graphX / 2) - 10, (int)(graphY + graphAmplitude) - 6, 14, Fade(GRAY, 0.9f)); | ||
|
||
DrawText("cos", (int)(graphX + graphPeriod + graphX / 2) - 18, (int)(graphY - graphAmplitude) - 10, 20, ORANGE); | ||
DrawText("sin", (int)(graphX + graphPeriod + graphX / 2) - 18, (int)(graphY) - 10, 20, RED); | ||
|
||
// --- Draw cosine curve (orange) --- | ||
for (int t = 0; t <= 360; t++) | ||
{ | ||
float x = ((float)t / 360.0f) * graphPeriod + graphX; | ||
float y = graphY - graphAmplitude * cosf(t * (PI / 180.0f)); | ||
// draw small segments between consecutive points for smoother curve | ||
if (t > 0) | ||
{ | ||
int prevT = t - 1; | ||
float px = ((float)prevT / 360.0f) * graphPeriod + graphX; | ||
float py = graphY - graphAmplitude * cosf(prevT * (PI / 180.0f)); | ||
DrawLineEx((Vector2){px, py}, (Vector2){x, y}, 2.5f, ORANGE); | ||
} | ||
} | ||
|
||
// --- Draw sine curve (red) --- | ||
for (int t = 0; t <= 360; t++) | ||
{ | ||
float x = ((float)t / 360.0f) * graphPeriod + graphX; | ||
float y = graphY - graphAmplitude * sinf(t * (PI / 180.0f)); | ||
if (t > 0) | ||
{ | ||
int prevT = t - 1; | ||
float px = ((float)prevT / 360.0f) * graphPeriod + graphX; | ||
float py = graphY - graphAmplitude * sinf(prevT * (PI / 180.0f)); | ||
DrawLineEx((Vector2){px, py}, (Vector2){x, y}, 2.5f, RED); | ||
} | ||
} | ||
|
||
// --- Draw moving vertical line on the graph corresponding to the angle --- | ||
float lineX = ((float)angleDeg / 360.0f) * graphPeriod + graphX; | ||
DrawLine((int)lineX, (int)(graphY - graphAmplitude), (int)lineX, (int)(graphY + graphAmplitude), Fade(GRAY, 0.6f)); | ||
|
||
// moving points on graph | ||
float orangeY = graphY - graphAmplitude * cosf(angRad); | ||
float redY = graphY - graphAmplitude * sinf(angRad); | ||
|
||
DrawCircle((int)lineX, (int)orangeY, 6.0f, ORANGE); | ||
DrawCircle((int)lineX, (int)redY, 6.0f, RED); | ||
|
||
EndDrawing(); | ||
} | ||
|
||
CloseWindow(); | ||
|
||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that Init, Update, Draw sections should be defined by:
//--------------------------------------------------------------------------------------
following the template structure: https://github.com/raysan5/raylib/blob/master/examples/examples_template.c