1+ /*******************************************************************************************
2+ *
3+ * raylib [shapes] example - math sine cosine
4+ *
5+ * Example complexity rating: [★☆☆☆] 1/4
6+ *
7+ * Example originally created with raylib 5.6, last time updated with raylib 5.6
8+ *
9+ * Example contributed by Midiphony (@midiphony) and reviewed by Ramon Santamaria (@raysan5)
10+ *
11+ * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
12+ * BSD-like license that allows static linking with closed source software
13+ *
14+ * Copyright (c) 2025-2025 Zero (@zerohorsepower)
15+ *
16+ ********************************************************************************************/
17+
18+ #include "raylib.h"
19+ #include "raymath.h" // Required for: Vector2 operations and Clamp()
20+ #include <stdlib.h> // Required for: malloc(), free()
21+ #include <math.h> // Required for: cosf(), sinf()
22+
23+ //------------------------------------------------------------------------------------
24+ // Program main entry point
25+ //------------------------------------------------------------------------------------
26+ int main (void )
27+ {
28+ // Initialization
29+ //--------------------------------------------------------------------------------------
30+ const Color cosineColor = RED ;
31+ const Color sineColor = ORANGE ;
32+ const int pointsSize = 6 ;
33+ const int lineThickness = 2 ;
34+
35+ const int screenWidth = 800 ;
36+ const int screenHeight = 450 ;
37+
38+ // Circle
39+ const int circleX = screenWidth /4 - 20 ;
40+ const int circleY = screenHeight /2 ;
41+ const Vector2 circlePosition = { circleX , circleY };
42+ const int circleRadius = 140 ;
43+ const int circleLeft = circleX - circleRadius ;
44+ const int circleRight = circleX + circleRadius ;
45+ const int circleTop = circleY - circleRadius ;
46+ const int circleBottom = circleY + circleRadius ;
47+
48+ const int circleTextFontSize = 20 ;
49+
50+ // Graph
51+ const int graphLeft = screenWidth /2 ;
52+ const int graphRight = 750 ;
53+ const int graphHeight = 200 ;
54+ const int graphHalfHeight = graphHeight /2 ;
55+ const int graphYMiddle = screenHeight /2 ;
56+ const int graphTop = graphYMiddle - graphHalfHeight ;
57+ const int graphBottom = graphYMiddle + graphHalfHeight ;
58+ const int graphWidth = graphRight - graphLeft ;
59+
60+ const int graphTextFontSize = 20 ;
61+ const int graphTextPadding = 10 ;
62+
63+ Vector2 * cosineCurvePoints = (Vector2 * )malloc (graphWidth * sizeof (Vector2 )); // Points array
64+ Vector2 * sineCurvePoints = (Vector2 * )malloc (graphWidth * sizeof (Vector2 )); // Points array
65+
66+ // Initialize cosine curve
67+ for (int x = 0 ; x < graphWidth ; x ++ )
68+ {
69+ float y = - cosf (((float )x /graphWidth )* 2.0 * PI );
70+ int yCoord = graphYMiddle + y * graphHalfHeight ;
71+ cosineCurvePoints [x ] = (Vector2 ){ graphLeft + x , yCoord };
72+ }
73+
74+ // Initialize sine curve
75+ for (int x = 0 ; x < graphWidth ; x ++ )
76+ {
77+ float y = sinf (((float )x /graphWidth )* 2.0 * PI );
78+ int yCoord = graphYMiddle - y * graphHalfHeight ;
79+ sineCurvePoints [x ] = (Vector2 ){ graphLeft + x , yCoord };
80+ }
81+
82+ const int windowSplitX = ((circleX + circleRadius ) + graphLeft )/2 ;
83+
84+ InitWindow (screenWidth , screenHeight , "raylib [shapes] example - math sine cosine" );
85+
86+ const int circleTextMaxLength = MeasureText ("-1.000" , circleTextFontSize );
87+ const int graphTextMaxLength = MeasureText ("-1.000" , graphTextFontSize );
88+
89+ SetTargetFPS (60 );
90+ //--------------------------------------------------------------------------------------
91+
92+ // Main game loop
93+ while (!WindowShouldClose ()) // Detect window close button or ESC key
94+ {
95+ // Update
96+ //----------------------------------------------------------------------------------
97+ Vector2 mousePosition = GetMousePosition ();
98+ float angleInDegrees = 0.0f ;
99+ float angle = 0 ;
100+
101+ if (mousePosition .x <= windowSplitX ) // Calculate angle relative to the circle
102+ {
103+ angle = Vector2Angle (Vector2Subtract (mousePosition , circlePosition ), (Vector2 ) { 1 , 0 });
104+ if (angle < 0.0f )
105+ {
106+ angle += 2 * PI ;
107+ }
108+ }
109+ else // Calculate angle relative to the graph
110+ {
111+ angle = Clamp ((mousePosition .x - graphLeft )* 2 * PI /graphWidth , 0.0f , 2 * PI );
112+ }
113+
114+ angleInDegrees = angle * RAD2DEG ;
115+
116+ float cosine = cosf (angle );
117+ float sine = sinf (angle );
118+ int pointX = circleX + circleRadius * cosine ;
119+ int pointY = circleY - circleRadius * sine ;
120+
121+ // Draw
122+ //----------------------------------------------------------------------------------
123+ BeginDrawing ();
124+
125+ ClearBackground (RAYWHITE );
126+
127+ // Draw top angle label
128+ DrawText (TextFormat ("Angle:%.1f" , angleInDegrees ), 20 , 20 , 30 , GRAY );
129+
130+ // Trigonometry circle
131+ // --------------------
132+ DrawRing (circlePosition , circleRadius - lineThickness /2 , circleRadius + lineThickness /2 , 0 , 360 , 0 , GRAY ); // 0 ring segment to let DrawRing choose a number of segments giving a smooth circle
133+ DrawLineEx ((Vector2 ) { circleLeft , circleY }, (Vector2 ) { circleRight , circleY }, lineThickness , GRAY );
134+ DrawLineEx ((Vector2 ) { circleX , circleTop }, (Vector2 ) { circleX , circleBottom }, lineThickness , GRAY );
135+
136+ DrawCircleSectorLines (circlePosition , circleRadius /3 , 0 , - angleInDegrees , 0 , BLUE );
137+
138+ // Draw line to point
139+ DrawLine (circleX , circleY , pointX , pointY , GRAY );
140+
141+ // Draw cosine point
142+ DrawLineEx ((Vector2 ) { circleX , circleY }, (Vector2 ) { pointX , circleY }, lineThickness , cosineColor );
143+ DrawText (TextFormat ("%.3f" , cosine ), ((pointX + circleX )/2 ) - circleTextMaxLength /2 , circleY + 2 , circleTextFontSize , cosineColor );
144+ // Draw sine point
145+ DrawLineEx ((Vector2 ) { pointX , circleY }, (Vector2 ) { pointX , pointY }, lineThickness , sineColor );
146+ DrawText (TextFormat ("%.3f" , sine ), pointX + 5 , (pointY + circleY )/2 - circleTextFontSize /2 , circleTextFontSize , sineColor );
147+
148+ // Draw point
149+ DrawCircle (pointX , pointY , pointsSize , BLACK );
150+ // --------------------
151+
152+ // Window split
153+ DrawLine (windowSplitX , 0 , windowSplitX , screenHeight - 1 , GRAY );
154+
155+ // Graph
156+ // --------------------
157+ // Draw graph borders
158+ DrawLineEx ((Vector2 ) { graphLeft , graphTop }, (Vector2 ) { graphLeft , graphBottom }, 2 , GRAY );
159+ DrawLineEx ((Vector2 ) { graphRight , graphTop }, (Vector2 ) { graphRight , graphBottom }, 2 , GRAY );
160+ DrawLineEx ((Vector2 ) { graphLeft , graphYMiddle }, (Vector2 ) { graphRight , graphYMiddle }, 2 , GRAY );
161+
162+ // Draw graph outer texts
163+ DrawText ("1" , graphLeft - graphTextPadding - MeasureText ("1" , graphTextFontSize ), graphTop - graphTextFontSize /2 , graphTextFontSize , GRAY );
164+ DrawText ("0" , graphLeft - graphTextPadding - MeasureText ("0" , graphTextFontSize ), graphYMiddle - graphTextFontSize /2 , graphTextFontSize , GRAY );
165+ DrawText ("-1" , graphLeft - graphTextPadding - MeasureText ("-1" , graphTextFontSize ), graphBottom - graphTextFontSize /2 , graphTextFontSize , GRAY );
166+ DrawText ("0" , graphLeft - MeasureText ("0" , graphTextFontSize )/2 , graphBottom + graphTextPadding /2 , graphTextFontSize , GRAY );
167+ DrawText ("360" , graphRight - MeasureText ("360" , graphTextFontSize )/2 , graphBottom + graphTextPadding /2 , graphTextFontSize , GRAY );
168+
169+ // Draw cosine curve
170+ DrawSplineLinear (cosineCurvePoints , graphWidth , 2 , cosineColor );
171+ DrawText ("cos" , graphRight + graphTextPadding , cosineCurvePoints [graphWidth - 1 ].y - graphTextFontSize /2 , graphTextFontSize , cosineColor );
172+
173+ // Draw sine curve
174+ DrawSplineLinear (sineCurvePoints , graphWidth , 2 , sineColor );
175+ DrawText ("sin" , graphRight + graphTextPadding , sineCurvePoints [graphWidth - 1 ].y - graphTextFontSize /2 , graphTextFontSize , sineColor );
176+
177+ // Draw graph progress line
178+ int x = graphLeft + graphWidth * angleInDegrees /360.0f ;
179+ DrawLine (x , graphBottom , x , graphTop , BLUE );
180+
181+ // Draw cosine and sine points on graph
182+ int cosineY = graphYMiddle - cosine * graphHalfHeight ;
183+ int sineY = graphYMiddle - sine * graphHalfHeight ;
184+ DrawCircle (x , cosineY , pointsSize , cosineColor );
185+ DrawText (TextFormat ("%.3f" , cosine ), x - circleTextMaxLength /2 , cosineY - circleTextFontSize - 5 , circleTextFontSize , cosineColor );
186+ DrawCircle (x , sineY , pointsSize , sineColor );
187+ DrawText (TextFormat ("%.3f" , sine ), x - circleTextMaxLength /2 , sineY + 8 , circleTextFontSize , sineColor );
188+ // --------------------
189+
190+ EndDrawing ();
191+ //----------------------------------------------------------------------------------
192+ }
193+
194+ // De-Initialization
195+ //--------------------------------------------------------------------------------------
196+
197+ free (cosineCurvePoints );
198+ free (sineCurvePoints );
199+
200+ CloseWindow (); // Close window and OpenGL context
201+ //--------------------------------------------------------------------------------------
202+
203+ return 0 ;
204+ }
0 commit comments