Watch
2
0
Fork
You've already forked raylib-cs
0
raylib-cs/Examples/Shapes/MathSineCosine.cs
2026-07-17 07:52:43 +02:00

212 lines
9.4 KiB
C#

/*******************************************************************************************
*
* raylib [shapes] example - math sine cosine
*
* Example complexity rating: [★★☆☆] 2/4
*
* Example originally created with raylib 6.0, last time updated with raylib 6.0
*
* Example contributed by Jopestpe (@jopestpe) and reviewed by Ramon Santamaria (@raysan5)
*
* 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) 2025 Jopestpe (@jopestpe)
*
********************************************************************************************/
using System;
using System.Numerics;
using static Raylib_cs.Raylib;
using static Raylib_cs.Raymath;
namespace Examples.Shapes;
public partial class MathSineCosine : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
// Wave points for sine/cosine visualization
private const int WAVE_POINTS = 36;
public string Name => "Shapes / Math Sine Cosine";
public string Title => "raylib [shapes] example - math sine cosine";
public ConfigFlags ConfigFlags => ConfigFlags.Msaa4xHint;
private Vector2[] sinePoints;
private Vector2[] cosPoints;
private Vector2 center;
private Rectangle start;
private float radius;
private float angle;
private bool pause;
public void Init()
{
sinePoints = new Vector2[WAVE_POINTS];
cosPoints = new Vector2[WAVE_POINTS];
center = new((screenWidth / 2.0f) - 30.0f, screenHeight / 2.0f);
start = new(20.0f, screenHeight - 120.0f, 200.0f, 100.0f);
radius = 130.0f;
angle = 0.0f;
pause = false;
for (int i = 0; i < WAVE_POINTS; i++)
{
float t = i / (float)(WAVE_POINTS - 1);
float currentAngle = t * 360.0f * DEG2RAD;
sinePoints[i] = new(start.X + t * start.Width, start.Y + start.Height / 2.0f - MathF.Sin(currentAngle) * (start.Height / 2.0f));
cosPoints[i] = new(start.X + t * start.Width, start.Y + start.Height / 2.0f - MathF.Cos(currentAngle) * (start.Height / 2.0f));
}
}
public unsafe void Update()
{
// Update
//----------------------------------------------------------------------------------
float angleRad = angle * DEG2RAD;
float cosRad = MathF.Cos(angleRad);
float sinRad = MathF.Sin(angleRad);
Vector2 point = new(center.X + cosRad * radius, center.Y - sinRad * radius);
Vector2 limitMin = new(center.X - radius, center.Y - radius);
Vector2 limitMax = new(center.X + radius, center.Y + radius);
float complementary = 90.0f - angle;
float supplementary = 180.0f - angle;
float explementary = 360.0f - angle;
float tangent = Clamp(MathF.Tan(angleRad), -10.0f, 10.0f);
float cotangent = (MathF.Abs(tangent) > 0.001f) ? Clamp(1.0f / tangent, -radius, radius) : 0.0f;
Vector2 tangentPoint = new(center.X + radius, center.Y - tangent * radius);
Vector2 cotangentPoint = new(center.X + cotangent * radius, center.Y - radius);
angle = Wrap(angle + (!pause ? 1.0f : 0.0f), 0.0f, 360.0f);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Cotangent (orange)
DrawLineEx(new Vector2(center.X, limitMin.Y), new Vector2(cotangentPoint.X, limitMin.Y), 2.0f, Color.Orange);
DrawLineDashed(center, cotangentPoint, 10, 4, Color.Orange);
// Side background
DrawLine(580, 0, 580, GetScreenHeight(), new Color(218, 218, 218, 255));
DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), new Color(232, 232, 232, 255));
// Base circle and axes
DrawCircleLinesV(center, radius, Color.Gray);
DrawLineEx(new Vector2(center.X, limitMin.Y), new Vector2(center.X, limitMax.Y), 1.0f, Color.Gray);
DrawLineEx(new Vector2(limitMin.X, center.Y), new Vector2(limitMax.X, center.Y), 1.0f, Color.Gray);
// Wave graph axes
DrawLineEx(new Vector2(start.X, start.Y), new Vector2(start.X, start.Y + start.Height), 2.0f, Color.Gray);
DrawLineEx(new Vector2(start.X + start.Width, start.Y), new Vector2(start.X + start.Width, start.Y + start.Height), 2.0f, Color.Gray);
DrawLineEx(new Vector2(start.X, start.Y + start.Height / 2), new Vector2(start.X + start.Width, start.Y + start.Height / 2), 2.0f, Color.Gray);
// Wave graph axis labels
DrawText("1", (int)start.X - 8, (int)start.Y, 6, Color.Gray);
DrawText("0", (int)start.X - 8, (int)start.Y + (int)start.Height / 2 - 6, 6, Color.Gray);
DrawText("-1", (int)start.X - 12, (int)start.Y + (int)start.Height - 8, 6, Color.Gray);
DrawText("0", (int)start.X - 2, (int)start.Y + (int)start.Height + 4, 6, Color.Gray);
DrawText("360", (int)start.X + (int)start.Width - 8, (int)start.Y + (int)start.Height + 4, 6, Color.Gray);
// Sine (red - vertical)
DrawLineEx(new Vector2(center.X, center.Y), new Vector2(center.X, point.Y), 2.0f, Color.Red);
DrawLineDashed(new Vector2(point.X, center.Y), new Vector2(point.X, point.Y), 10, 4, Color.Red);
DrawText($"Sine {sinRad:0.00}", 640, 190, 6, Color.Red);
DrawCircleV(new Vector2(start.X + (angle / 360.0f) * start.Width, start.Y + ((-sinRad + 1) * start.Height / 2.0f)), 4.0f, Color.Red);
fixed (Vector2* p = sinePoints) DrawSplineLinear(p, WAVE_POINTS, 1.0f, Color.Red);
// Cosine (blue - horizontal)
DrawLineEx(new Vector2(center.X, center.Y), new Vector2(point.X, center.Y), 2.0f, Color.Blue);
DrawLineDashed(new Vector2(center.X, point.Y), new Vector2(point.X, point.Y), 10, 4, Color.Blue);
DrawText($"Cosine {cosRad:0.00}", 640, 210, 6, Color.Blue);
DrawCircleV(new Vector2(start.X + (angle / 360.0f) * start.Width, start.Y + ((-cosRad + 1) * start.Height / 2.0f)), 4.0f, Color.Blue);
fixed (Vector2* p = cosPoints) DrawSplineLinear(p, WAVE_POINTS, 1.0f, Color.Blue);
// Tangent (purple)
DrawLineEx(new Vector2(limitMax.X, center.Y), new Vector2(limitMax.X, tangentPoint.Y), 2.0f, Color.Purple);
DrawLineDashed(center, tangentPoint, 10, 4, Color.Purple);
DrawText($"Tangent {tangent:0.00}", 640, 230, 6, Color.Purple);
// Cotangent (orange)
DrawText($"Cotangent {cotangent:0.00}", 640, 250, 6, Color.Orange);
// Complementary angle (beige)
DrawCircleSectorLines(center, radius * 0.6f, -angle, -90.0f, 36, Color.Beige);
DrawText($"Complementary {complementary:0}°", 640, 150, 6, Color.Beige);
// Supplementary angle (darkblue)
DrawCircleSectorLines(center, radius * 0.5f, -angle, -180.0f, 36, Color.DarkBlue);
DrawText($"Supplementary {supplementary:0}°", 640, 130, 6, Color.DarkBlue);
// Explementary angle (pink)
DrawCircleSectorLines(center, radius * 0.4f, -angle, -360.0f, 36, Color.Pink);
DrawText($"Explementary {explementary:0}°", 640, 170, 6, Color.Pink);
// Current angle - arc (lime), radius (black), endpoint (black)
DrawCircleSectorLines(center, radius * 0.7f, -angle, 0.0f, 36, Color.Lime);
DrawLineEx(new Vector2(center.X, center.Y), point, 2.0f, Color.Black);
DrawCircleV(point, 4.0f, Color.Black);
// Draw GUI controls
// NOTE: raygui is not bound in raylib-cs, so the Pause toggle and Angle slider
// are unavailable; the angle animates continuously.
//------------------------------------------------------------------------------
/*
GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(GRAY));
GuiToggle((Rectangle){ 640, 70, 120, 20}, TextFormat("Pause"), &pause);
GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(LIME));
GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f°", angle), &angle, 0.0f, 360.0f);
// Angle values panel
GuiGroupBox((Rectangle){ 620, 110, 140, 170}, "Angle Values");
*/
//------------------------------------------------------------------------------
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
SetConfigFlags(ConfigFlags.Msaa4xHint);
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math sine cosine");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
var game = new MathSineCosine();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}