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+ // Auto mode
99+ // float angleInDegrees = (int)(GetTime()*TARGET_FPS) % 360;
100+ float angleInDegrees = 0.0f ;
101+ float angle = 0 ;
102+
103+ if (mousePosition .x <= windowSplitX ) // Calculate angle relative to the circle
104+ {
105+ angle = Vector2Angle (Vector2Subtract (mousePosition , circlePosition ), (Vector2 ) { 1 , 0 });
106+ if (angle < 0.0f )
107+ {
108+ angle += 2 * PI ;
109+ }
110+ }
111+ else // Calculate angle relative to the graph
112+ {
113+ angle = Clamp ((mousePosition .x - graphLeft )* 2 * PI /graphWidth , 0.0f , 2 * PI );
114+ }
115+
116+ angleInDegrees = angle * RAD2DEG ;
117+
118+ float cosine = cosf (angle );
119+ float sine = sinf (angle );
120+ int pointX = circleX + circleRadius * cosine ;
121+ int pointY = circleY - circleRadius * sine ;
122+
123+ // Draw
124+ //----------------------------------------------------------------------------------
125+ BeginDrawing ();
126+
127+ ClearBackground (RAYWHITE );
128+
129+ // Draw top angle label
130+ DrawText (TextFormat ("Angle:%.1f" , angleInDegrees ), 20 , 20 , 30 , GRAY );
131+
132+ // Trigonometry circle
133+ // --------------------
134+ 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
135+ DrawLineEx ((Vector2 ) { circleLeft , circleY }, (Vector2 ) { circleRight , circleY }, lineThickness , GRAY );
136+ DrawLineEx ((Vector2 ) { circleX , circleTop }, (Vector2 ) { circleX , circleBottom }, lineThickness , GRAY );
137+
138+ DrawCircleSectorLines (circlePosition , circleRadius /3 , 0 , - angleInDegrees , 0 , BLUE );
139+
140+ // Draw line to point
141+ DrawLine (circleX , circleY , pointX , pointY , GRAY );
142+
143+ // Draw cosine point
144+ DrawLineEx ((Vector2 ) { circleX , circleY }, (Vector2 ) { pointX , circleY }, lineThickness , cosineColor );
145+ DrawText (TextFormat ("%.3f" , cosine ), ((pointX + circleX )/2 ) - circleTextMaxLength /2 , circleY + 2 , circleTextFontSize , cosineColor );
146+ // Draw sine point
147+ DrawLineEx ((Vector2 ) { pointX , circleY }, (Vector2 ) { pointX , pointY }, lineThickness , sineColor );
148+ DrawText (TextFormat ("%.3f" , sine ), pointX + 5 , (pointY + circleY )/2 - circleTextFontSize /2 , circleTextFontSize , sineColor );
149+
150+ // Draw point
151+ DrawCircle (pointX , pointY , pointsSize , BLACK );
152+ // --------------------
153+
154+ // Window split
155+ DrawLine (windowSplitX , 0 , windowSplitX , screenHeight - 1 , GRAY );
156+
157+ // Graph
158+ // --------------------
159+ // Draw graph borders
160+ DrawLineEx ((Vector2 ) { graphLeft , graphTop }, (Vector2 ) { graphLeft , graphBottom }, 2 , GRAY );
161+ DrawLineEx ((Vector2 ) { graphRight , graphTop }, (Vector2 ) { graphRight , graphBottom }, 2 , GRAY );
162+ DrawLineEx ((Vector2 ) { graphLeft , graphYMiddle }, (Vector2 ) { graphRight , graphYMiddle }, 2 , GRAY );
163+
164+ // Draw graph outer texts
165+ DrawText ("1" , graphLeft - graphTextPadding - MeasureText ("1" , graphTextFontSize ), graphTop - graphTextFontSize /2 , graphTextFontSize , GRAY );
166+ DrawText ("0" , graphLeft - graphTextPadding - MeasureText ("0" , graphTextFontSize ), graphYMiddle - graphTextFontSize /2 , graphTextFontSize , GRAY );
167+ DrawText ("-1" , graphLeft - graphTextPadding - MeasureText ("-1" , graphTextFontSize ), graphBottom - graphTextFontSize /2 , graphTextFontSize , GRAY );
168+ DrawText ("0" , graphLeft - MeasureText ("0" , graphTextFontSize )/2 , graphBottom + graphTextPadding /2 , graphTextFontSize , GRAY );
169+ DrawText ("360" , graphRight - MeasureText ("360" , graphTextFontSize )/2 , graphBottom + graphTextPadding /2 , graphTextFontSize , GRAY );
170+
171+ // Draw cosine curve
172+ DrawSplineLinear (cosineCurvePoints , graphWidth , 2 , cosineColor );
173+ DrawText ("cos" , graphRight + graphTextPadding , cosineCurvePoints [graphWidth - 1 ].y - graphTextFontSize /2 , graphTextFontSize , cosineColor );
174+
175+ // Draw sine curve
176+ DrawSplineLinear (sineCurvePoints , graphWidth , 2 , sineColor );
177+ DrawText ("sin" , graphRight + graphTextPadding , sineCurvePoints [graphWidth - 1 ].y - graphTextFontSize /2 , graphTextFontSize , sineColor );
178+
179+ // Draw graph progress line
180+ int x = graphLeft + graphWidth * angleInDegrees /360.0f ;
181+ DrawLine (x , graphBottom , x , graphTop , BLUE );
182+
183+ // Draw cosine and sine points on graph
184+ int cosineY = graphYMiddle - cosine * graphHalfHeight ;
185+ int sineY = graphYMiddle - sine * graphHalfHeight ;
186+ DrawCircle (x , cosineY , pointsSize , cosineColor );
187+ DrawText (TextFormat ("%.3f" , cosine ), x - circleTextMaxLength /2 , cosineY - circleTextFontSize - 5 , circleTextFontSize , cosineColor );
188+ DrawCircle (x , sineY , pointsSize , sineColor );
189+ DrawText (TextFormat ("%.3f" , sine ), x - circleTextMaxLength /2 , sineY + 8 , circleTextFontSize , sineColor );
190+ // --------------------
191+
192+ EndDrawing ();
193+ //----------------------------------------------------------------------------------
194+ }
195+
196+ // De-Initialization
197+ //--------------------------------------------------------------------------------------
198+
199+ free (cosineCurvePoints );
200+ free (sineCurvePoints );
201+
202+ CloseWindow (); // Close window and OpenGL context
203+ //--------------------------------------------------------------------------------------
204+
205+ return 0 ;
206+ }
0 commit comments