Watch
2
0
Fork
You've already forked raylib-cs
0

chore: clean recommit

This commit is contained in:
tiger tiger tiger 2026-07-07 23:47:38 +02:00
commit 60ad2e7fb1
122 changed files with 23950 additions and 323 deletions

View file

@ -0,0 +1,205 @@
/*******************************************************************************************
*
* raylib [shapes] example - double pendulum
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.5
*
* Example contributed by JoeCheong (@Joecheong2006) 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 JoeCheong (@Joecheong2006)
*
********************************************************************************************/
using System;
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Shapes;
public partial class DoublePendulum : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
// Constant for Simulation
private const int SIMULATION_STEPS = 30;
private const float G = 9.81f;
public string Name => "Shapes / Double Pendulum";
public string Title => "raylib [shapes] example - double pendulum";
public ConfigFlags ConfigFlags => ConfigFlags.HighDpiWindow;
// Simulation Parameters
private float l1, m1, theta1, w1;
private float l2, m2, theta2, w2;
private float lengthScaler;
private float totalM;
private Vector2 previousPosition;
// Scale length
private float L1;
private float L2;
// Draw parameters
private float lineThick, trailThick;
private float fateAlpha;
// Create framebuffer
private RenderTexture2D target;
// Calculate pendulum end point
private static Vector2 CalculatePendulumEndPoint(float l, float theta)
{
return new(10 * l * MathF.Sin(theta), 10 * l * MathF.Cos(theta));
}
// Calculate double pendulum end point
private static Vector2 CalculateDoublePendulumEndPoint(float l1, float theta1, float l2, float theta2)
{
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
Vector2 endpoint2 = CalculatePendulumEndPoint(l2, theta2);
return new(endpoint1.X + endpoint2.X, endpoint1.Y + endpoint2.Y);
}
public void Init()
{
// Simulation Parameters
l1 = 15.0f; m1 = 0.2f; theta1 = DEG2RAD * 170; w1 = 0;
l2 = 15.0f; m2 = 0.1f; theta2 = DEG2RAD * 0; w2 = 0;
lengthScaler = 0.1f;
totalM = m1 + m2;
previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
previousPosition.X += ((float)screenWidth / 2);
previousPosition.Y += ((float)screenHeight / 2 - 100);
// Scale length
L1 = l1 * lengthScaler;
L2 = l2 * lengthScaler;
// Draw parameters
lineThick = 20; trailThick = 2;
fateAlpha = 0.01f;
// Create framebuffer
target = LoadRenderTexture(screenWidth, screenHeight);
SetTextureFilter(target.Texture, TextureFilter.Bilinear);
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
float dt = GetFrameTime();
float step = dt / SIMULATION_STEPS, step2 = step * step;
// Update Physics - larger steps = better approximation
for (int i = 0; i < SIMULATION_STEPS; i++)
{
float delta = theta1 - theta2;
float sinD = MathF.Sin(delta), cosD = MathF.Cos(delta), cos2D = MathF.Cos(2 * delta);
float ww1 = w1 * w1, ww2 = w2 * w2;
// Calculate a1
float a1 = (-G * (2 * m1 + m2) * MathF.Sin(theta1)
- m2 * G * MathF.Sin(theta1 - 2 * theta2)
- 2 * sinD * m2 * (ww2 * L2 + ww1 * L1 * cosD))
/ (L1 * (2 * m1 + m2 - m2 * cos2D));
// Calculate a2
float a2 = (2 * sinD * (ww1 * L1 * totalM
+ G * totalM * MathF.Cos(theta1)
+ ww2 * L2 * m2 * cosD))
/ (L2 * (2 * m1 + m2 - m2 * cos2D));
// Update thetas
theta1 += w1 * step + 0.5f * a1 * step2;
theta2 += w2 * step + 0.5f * a2 * step2;
// Update omegas
w1 += a1 * step;
w2 += a2 * step;
}
// Calculate position
Vector2 currentPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
currentPosition.X += (float)screenWidth / 2;
currentPosition.Y += (float)screenHeight / 2 - 100;
// Draw to render texture
BeginTextureMode(target);
// Draw a transparent rectangle - smaller alpha = longer trails
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(Color.Black, fateAlpha));
// Draw trail
DrawCircleV(previousPosition, trailThick, Color.Red);
DrawLineEx(previousPosition, currentPosition, trailThick * 2, Color.Red);
EndTextureMode();
// Update previous position
previousPosition = currentPosition;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.Black);
// Draw trails texture
DrawTextureRec(target.Texture, new Rectangle(0, 0, (float)target.Texture.Width, (float)-target.Texture.Height), new Vector2(0, 0), Color.White);
// Draw double pendulum
DrawRectanglePro(new Rectangle(screenWidth / 2.0f, screenHeight / 2.0f - 100, 10 * l1, lineThick),
new Vector2(0, lineThick * 0.5f), 90 - RAD2DEG * theta1, Color.RayWhite);
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
DrawRectanglePro(new Rectangle(screenWidth / 2.0f + endpoint1.X, screenHeight / 2.0f - 100 + endpoint1.Y, 10 * l2, lineThick),
new Vector2(0, lineThick * 0.5f), 90 - RAD2DEG * theta2, Color.RayWhite);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadRenderTexture(target);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
SetConfigFlags(ConfigFlags.HighDpiWindow);
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - double pendulum");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new DoublePendulum();
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;
}
}