← ziglang.inraylib-zigGitHub

math sine cosine

★★☆☆by Jopestpe (@jopestpe)

There is no browser build of this example yet.

Is it the same as C?

//! raylib [shapes] example - math sine cosine
//!
//! Zig-API translation of examples/shapes/shapes_math_sine_cosine.c (raylib 6.2).
//! Example contributed by Jopestpe (@jopestpe) and reviewed by Ramon Santamaria (@raysan5)
//! Example licensed under an unmodified zlib/libpng license.
//! Copyright (c) 2025 Jopestpe (@jopestpe)

const rl = @import("raylib");
const gui = @import("raygui");

// libm tanf(), as in the C example (keeps the tangent bit-identical)
extern "c" fn tanf(x: f32) f32;

// Wave points for sine/cosine visualization
const wave_points = 36;

pub fn main() void {
    // Initialization
    const screen_width = 800;
    const screen_height = 450;

    rl.setConfigFlags(.{ .msaa_4x_hint = true });
    rl.initWindow(screen_width, screen_height, "raylib [shapes] example - math sine cosine");
    defer rl.closeWindow(); // Close window and OpenGL context

    var sine_points: [wave_points]rl.Vector2 = undefined;
    var cos_points: [wave_points]rl.Vector2 = undefined;
    const center: rl.Vector2 = .{ .x = (screen_width / 2.0) - 30.0, .y = screen_height / 2.0 };
    const start: rl.Rectangle = .{ .x = 20.0, .y = screen_height - 120.0, .width = 200.0, .height = 100.0 };
    const radius: f32 = 130.0;
    var angle: f32 = 0.0;
    var pause = false;

    for (&sine_points, &cos_points, 0..) |*sine_point, *cos_point, i| {
        const t = @as(f32, @floatFromInt(i)) / (wave_points - 1);
        const current_angle = t * 360.0 * rl.deg2rad;
        sine_point.* = .{ .x = start.x + t * start.width, .y = start.y + start.height / 2.0 - @sin(current_angle) * (start.height / 2.0) };
        cos_point.* = .{ .x = start.x + t * start.width, .y = start.y + start.height / 2.0 - @cos(current_angle) * (start.height / 2.0) };
    }

    rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second

    // Main game loop
    while (!rl.windowShouldClose()) { // Detect window close button or ESC key
        // Update
        const angle_rad = angle * rl.deg2rad;
        const cos_rad = @cos(angle_rad);
        const sin_rad = @sin(angle_rad);

        const point: rl.Vector2 = .{ .x = center.x + cos_rad * radius, .y = center.y - sin_rad * radius };
        const limit_min: rl.Vector2 = .{ .x = center.x - radius, .y = center.y - radius };
        const limit_max: rl.Vector2 = .{ .x = center.x + radius, .y = center.y + radius };

        const complementary = 90.0 - angle;
        const supplementary = 180.0 - angle;
        const explementary = 360.0 - angle;

        const tangent = rl.math.clamp(tanf(angle_rad), -10.0, 10.0);
        const cotangent = if (@abs(tangent) > 0.001) rl.math.clamp(1.0 / tangent, -radius, radius) else 0.0;
        const tangent_point: rl.Vector2 = .{ .x = center.x + radius, .y = center.y - tangent * radius };
        const cotangent_point: rl.Vector2 = .{ .x = center.x + cotangent * radius, .y = center.y - radius };

        angle = rl.math.wrap(angle + @as(f32, if (!pause) 1.0 else 0.0), 0.0, 360.0);

        // Draw
        rl.beginDrawing();
        defer rl.endDrawing();

        rl.clearBackground(.ray_white);

        // Cotangent (orange)
        rl.drawLineEx(.{ .x = center.x, .y = limit_min.y }, .{ .x = cotangent_point.x, .y = limit_min.y }, 2.0, .orange);
        rl.drawLineDashed(center, cotangent_point, 10, 4, .orange);

        // Side background
        rl.drawLine(580, 0, 580, rl.getScreenHeight(), .{ .r = 218, .g = 218, .b = 218, .a = 255 });
        rl.drawRectangle(580, 0, rl.getScreenWidth(), rl.getScreenHeight(), .{ .r = 232, .g = 232, .b = 232, .a = 255 });

        // Base circle and axes
        rl.drawCircleLinesV(center, radius, .gray);
        rl.drawLineEx(.{ .x = center.x, .y = limit_min.y }, .{ .x = center.x, .y = limit_max.y }, 1.0, .gray);
        rl.drawLineEx(.{ .x = limit_min.x, .y = center.y }, .{ .x = limit_max.x, .y = center.y }, 1.0, .gray);

        // Wave graph axes
        rl.drawLineEx(.{ .x = start.x, .y = start.y }, .{ .x = start.x, .y = start.y + start.height }, 2.0, .gray);
        rl.drawLineEx(.{ .x = start.x + start.width, .y = start.y }, .{ .x = start.x + start.width, .y = start.y + start.height }, 2.0, .gray);
        rl.drawLineEx(.{ .x = start.x, .y = start.y + start.height / 2 }, .{ .x = start.x + start.width, .y = start.y + start.height / 2 }, 2.0, .gray);

        // Wave graph axis labels
        const start_x: i32 = @intFromFloat(start.x);
        const start_y: i32 = @intFromFloat(start.y);
        const start_width: i32 = @intFromFloat(start.width);
        const start_height: i32 = @intFromFloat(start.height);
        rl.drawText("1", start_x - 8, start_y, 6, .gray);
        rl.drawText("0", start_x - 8, start_y + @divTrunc(start_height, 2) - 6, 6, .gray);
        rl.drawText("-1", start_x - 12, start_y + start_height - 8, 6, .gray);
        rl.drawText("0", start_x - 2, start_y + start_height + 4, 6, .gray);
        rl.drawText("360", start_x + start_width - 8, start_y + start_height + 4, 6, .gray);

        // Sine (red - vertical)
        rl.drawLineEx(.{ .x = center.x, .y = center.y }, .{ .x = center.x, .y = point.y }, 2.0, .red);
        rl.drawLineDashed(.{ .x = point.x, .y = center.y }, .{ .x = point.x, .y = point.y }, 10, 4, .red);
        rl.drawText(rl.textFormat("Sine {d:.2}", .{sin_rad}), 640, 190, 6, .red);
        rl.drawCircleV(.{ .x = start.x + (angle / 360.0) * start.width, .y = start.y + ((-sin_rad + 1) * start.height / 2.0) }, 4.0, .red);
        rl.drawSplineLinear(&sine_points, 1.0, .red);

        // Cosine (blue - horizontal)
        rl.drawLineEx(.{ .x = center.x, .y = center.y }, .{ .x = point.x, .y = center.y }, 2.0, .blue);
        rl.drawLineDashed(.{ .x = center.x, .y = point.y }, .{ .x = point.x, .y = point.y }, 10, 4, .blue);
        rl.drawText(rl.textFormat("Cosine {d:.2}", .{cos_rad}), 640, 210, 6, .blue);
        rl.drawCircleV(.{ .x = start.x + (angle / 360.0) * start.width, .y = start.y + ((-cos_rad + 1) * start.height / 2.0) }, 4.0, .blue);
        rl.drawSplineLinear(&cos_points, 1.0, .blue);

        // Tangent (purple)
        rl.drawLineEx(.{ .x = limit_max.x, .y = center.y }, .{ .x = limit_max.x, .y = tangent_point.y }, 2.0, .purple);
        rl.drawLineDashed(center, tangent_point, 10, 4, .purple);
        rl.drawText(rl.textFormat("Tangent {d:.2}", .{tangent}), 640, 230, 6, .purple);

        // Cotangent (orange)
        rl.drawText(rl.textFormat("Cotangent {d:.2}", .{cotangent}), 640, 250, 6, .orange);

        // Complementary angle (beige)
        rl.drawCircleSectorLines(center, radius * 0.6, -angle, -90.0, 36, .beige);
        rl.drawText(rl.textFormat("Complementary  {d:.0}°", .{complementary}), 640, 150, 6, .beige);

        // Supplementary angle (darkblue)
        rl.drawCircleSectorLines(center, radius * 0.5, -angle, -180.0, 36, .dark_blue);
        rl.drawText(rl.textFormat("Supplementary  {d:.0}°", .{supplementary}), 640, 130, 6, .dark_blue);

        // Explementary angle (pink)
        rl.drawCircleSectorLines(center, radius * 0.4, -angle, -360.0, 36, .pink);
        rl.drawText(rl.textFormat("Explementary  {d:.0}°", .{explementary}), 640, 170, 6, .pink);

        // Current angle - arc (lime), radius (black), endpoint (black)
        rl.drawCircleSectorLines(center, radius * 0.7, -angle, 0.0, 36, .lime);
        rl.drawLineEx(.{ .x = center.x, .y = center.y }, point, 2.0, .black);
        rl.drawCircleV(point, 4.0, .black);

        // Draw GUI controls
        gui.setStyle(.label, gui.ControlProperty.text_color_normal, rl.colorToInt(.gray));
        _ = gui.toggle(.{ .x = 640, .y = 70, .width = 120, .height = 20 }, "Pause", &pause);
        gui.setStyle(.label, gui.ControlProperty.text_color_normal, rl.colorToInt(.lime));
        _ = gui.sliderBar(.{ .x = 640, .y = 40, .width = 120, .height = 20 }, "Angle", rl.textFormat("{d:.0}°", .{angle}), &angle, 0.0, 360.0);

        // Angle values panel
        _ = gui.groupBox(.{ .x = 620, .y = 110, .width = 140, .height = 170 }, "Angle Values");

        rl.drawFPS(10, 10);
    }
}
/*******************************************************************************************
*
*   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)
*
********************************************************************************************/

#include "raylib.h"
#include <math.h>
#include "raymath.h"

#define RAYGUI_IMPLEMENTATION
#include "raygui.h"                 // Required for GUI controls

// Wave points for sine/cosine visualization
#define WAVE_POINTS 36

//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
    // Initialization
    //--------------------------------------------------------------------------------------
    const int screenWidth = 800;
    const int screenHeight = 450;

    SetConfigFlags(FLAG_MSAA_4X_HINT);
    InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math sine cosine");

    Vector2 sinePoints[WAVE_POINTS];
    Vector2 cosPoints[WAVE_POINTS];
    Vector2 center = { (screenWidth/2.0f) - 30.0f, screenHeight/2.0f };
    Rectangle start = { 20.0f, screenHeight - 120.f , 200.0f, 100.0f};
    float radius = 130.0f;
    float angle = 0.0f;
    bool 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] = (Vector2){ start.x + t*start.width, start.y + start.height/2.0f - sinf(currentAngle)*(start.height/2.0f) };
        cosPoints[i] = (Vector2){ start.x + t*start.width, start.y + start.height/2.0f - cosf(currentAngle)*(start.height/2.0f) };
    }

    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 angleRad = angle*DEG2RAD;
        float cosRad = cosf(angleRad);
        float sinRad = sinf(angleRad);

        Vector2 point = { center.x + cosRad*radius, center.y - sinRad*radius };
        Vector2 limitMin = { center.x - radius, center.y - radius };
        Vector2 limitMax = { center.x + radius, center.y + radius };

        float complementary = 90.0f - angle;
        float supplementary = 180.0f - angle;
        float explementary = 360.0f - angle;

        float tangent = Clamp(tanf(angleRad), -10.0f, 10.0f);
        float cotangent = (fabsf(tangent) > 0.001f) ? Clamp(1.0f/tangent, -radius, radius) : 0.0f;
        Vector2 tangentPoint = { center.x + radius, center.y - tangent*radius };
        Vector2 cotangentPoint = { center.x + cotangent*radius, center.y - radius };

        angle = Wrap(angle + (!pause ? 1.0f : 0.0f), 0.0f, 360.0f);
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();
            ClearBackground(RAYWHITE);

            // Cotangent (orange)
            DrawLineEx((Vector2){ center.x , limitMin.y }, (Vector2){ cotangentPoint.x, limitMin.y }, 2.0f, ORANGE);
            DrawLineDashed(center, cotangentPoint, 10, 4, ORANGE);

            // Side background
            DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
            DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 });

            // Base circle and axes
            DrawCircleLinesV(center, radius, GRAY);
            DrawLineEx((Vector2){ center.x, limitMin.y }, (Vector2){ center.x, limitMax.y }, 1.0f, GRAY);
            DrawLineEx((Vector2){ limitMin.x, center.y }, (Vector2){ limitMax.x, center.y }, 1.0f, GRAY);

            // Wave graph axes
            DrawLineEx((Vector2){ start.x , start.y }, (Vector2){ start.x , start.y + start.height }, 2.0f, GRAY);
            DrawLineEx((Vector2){ start.x + start.width, start.y }, (Vector2){ start.x + start.width, start.y + start.height }, 2.0f, GRAY);
            DrawLineEx((Vector2){ start.x, start.y + start.height/2 }, (Vector2){ start.x + start.width, start.y + start.height/2 }, 2.0f, GRAY);

            // Wave graph axis labels
            DrawText("1", (int)start.x - 8, (int)start.y, 6, GRAY);
            DrawText("0", (int)start.x - 8, (int)start.y + (int)start.height/2 - 6, 6, GRAY);
            DrawText("-1", (int)start.x - 12, (int)start.y + (int)start.height - 8, 6, GRAY);
            DrawText("0", (int)start.x - 2, (int)start.y + (int)start.height + 4, 6, GRAY);
            DrawText("360", (int)start.x + (int)start.width - 8, (int)start.y + (int)start.height + 4, 6, GRAY);

            // Sine (red - vertical)
            DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ center.x, point.y }, 2.0f, RED);
            DrawLineDashed((Vector2){ point.x, center.y }, (Vector2){ point.x, point.y }, 10, 4, RED);
            DrawText(TextFormat("Sine %.2f", sinRad), 640, 190, 6, RED);
            DrawCircleV((Vector2){ start.x + (angle/360.0f)*start.width, start.y + ((-sinRad + 1)*start.height/2.0f) }, 4.0f, RED);
            DrawSplineLinear(sinePoints, WAVE_POINTS, 1.0f, RED);

            // Cosine (blue - horizontal)
            DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ point.x, center.y }, 2.0f, BLUE);
            DrawLineDashed((Vector2){ center.x , point.y }, (Vector2){ point.x, point.y }, 10, 4, BLUE);
            DrawText(TextFormat("Cosine %.2f", cosRad), 640, 210, 6, BLUE);
            DrawCircleV((Vector2){ start.x + (angle/360.0f)*start.width, start.y + ((-cosRad + 1)*start.height/2.0f) }, 4.0f, BLUE);
            DrawSplineLinear(cosPoints, WAVE_POINTS, 1.0f, BLUE);

            // Tangent (purple)
            DrawLineEx((Vector2){ limitMax.x , center.y }, (Vector2){ limitMax.x, tangentPoint.y }, 2.0f, PURPLE);
            DrawLineDashed(center, tangentPoint, 10, 4, PURPLE);
            DrawText(TextFormat("Tangent %.2f", tangent), 640, 230, 6, PURPLE);

            // Cotangent (orange)
            DrawText(TextFormat("Cotangent %.2f", cotangent), 640, 250, 6, ORANGE);

            // Complementary angle (beige)
            DrawCircleSectorLines(center, radius*0.6f , -angle, -90.0f , 36, BEIGE);
            DrawText(TextFormat("Complementary  %0.f°",complementary), 640, 150, 6, BEIGE);

            // Supplementary angle (darkblue)
            DrawCircleSectorLines(center, radius*0.5f , -angle, -180.0f , 36, DARKBLUE);
            DrawText(TextFormat("Supplementary  %0.f°",supplementary), 640, 130, 6, DARKBLUE);

            // Explementary angle (pink)
            DrawCircleSectorLines(center, radius*0.4f , -angle, -360.0f , 36, PINK);
            DrawText(TextFormat("Explementary  %0.f°",explementary), 640, 170, 6, PINK);

            // Current angle - arc (lime), radius (black), endpoint (black)
            DrawCircleSectorLines(center, radius*0.7f , -angle, 0.0f, 36, LIME);
            DrawLineEx((Vector2){ center.x , center.y }, point, 2.0f, BLACK);
            DrawCircleV(point, 4.0f, BLACK);

            // Draw GUI controls
            //------------------------------------------------------------------------------
            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();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    CloseWindow();        // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}

From raylib 6.2. The original on GitHub.