Skip to content

Commit fb2d695

Browse files
committed
Added shapes_collision_ellipses example
1 parent 6ff51d3 commit fb2d695

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*******************************************************************************************
2+
*
3+
* raylib [shapes] example - collision ellipses
4+
*
5+
* Example complexity rating: [★★☆☆] 2/4
6+
*
7+
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
8+
* BSD-like license that allows static linking with closed source software
9+
*
10+
********************************************************************************************/
11+
12+
#include "raylib.h"
13+
#include <math.h>
14+
15+
// Check if point is inside ellipse
16+
static bool CheckCollisionPointEllipse(Vector2 point, Vector2 center, float rx, float ry)
17+
{
18+
float dx = (point.x - center.x) / rx;
19+
float dy = (point.y - center.y) / ry;
20+
return (dx*dx + dy*dy) <= 1.0f;
21+
}
22+
23+
// Check if two ellipses collide
24+
// Uses radial boundary distance in the direction between centers — scales correctly with radii
25+
static bool CheckCollisionEllipses(Vector2 c1, float rx1, float ry1, Vector2 c2, float rx2, float ry2)
26+
{
27+
float dx = c2.x - c1.x;
28+
float dy = c2.y - c1.y;
29+
float dist = sqrtf(dx*dx + dy*dy);
30+
31+
// Ellipses are on top of each other
32+
if (dist == 0.0f) return true;
33+
34+
float theta = atan2f(dy, dx);
35+
float cosT = cosf(theta);
36+
float sinT = sinf(theta);
37+
38+
// Radial distance from center to ellipse boundary in direction theta
39+
// r(theta) = (rx * ry) / sqrt((ry*cos)^2 + (rx*sin)^2)
40+
float r1 = (rx1 * ry1) / sqrtf((ry1*cosT)*(ry1*cosT) + (rx1*sinT)*(rx1*sinT));
41+
float r2 = (rx2 * ry2) / sqrtf((ry2*cosT)*(ry2*cosT) + (rx2*sinT)*(rx2*sinT));
42+
43+
return dist <= (r1 + r2);
44+
}
45+
46+
//------------------------------------------------------------------------------------
47+
// Program main entry point
48+
//------------------------------------------------------------------------------------
49+
int main(void)
50+
{
51+
// Initialization
52+
//--------------------------------------------------------------------------------------
53+
const int screenWidth = 1200;
54+
const int screenHeight = 840;
55+
56+
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - collision ellipses");
57+
SetTargetFPS(60);
58+
59+
Vector2 ellipseACenter = { (float)screenWidth/4, (float)screenHeight/2 };
60+
float ellipseARx = 120.0f;
61+
float ellipseARy = 70.0f;
62+
63+
Vector2 ellipseBCenter = { (float)screenWidth*3/4, (float)screenHeight/2 };
64+
float ellipseBRx = 90.0f;
65+
float ellipseBRy = 140.0f;
66+
67+
// 0 = controlling A, 1 = controlling B
68+
int controlled = 0;
69+
70+
Color bgColor = { 16, 12, 21, 255 };
71+
//--------------------------------------------------------------------------------------
72+
73+
// Main game loop
74+
while (!WindowShouldClose())
75+
{
76+
// Update
77+
//----------------------------------------------------------------------------------
78+
if (IsKeyPressed(KEY_A)) controlled = 0;
79+
if (IsKeyPressed(KEY_B)) controlled = 1;
80+
81+
if (controlled == 0) ellipseACenter = GetMousePosition();
82+
else ellipseBCenter = GetMousePosition();
83+
84+
bool ellipsesCollide = CheckCollisionEllipses(
85+
ellipseACenter, ellipseARx, ellipseARy,
86+
ellipseBCenter, ellipseBRx, ellipseBRy
87+
);
88+
89+
bool mouseInA = CheckCollisionPointEllipse(GetMousePosition(), ellipseACenter, ellipseARx, ellipseARy);
90+
bool mouseInB = CheckCollisionPointEllipse(GetMousePosition(), ellipseBCenter, ellipseBRx, ellipseBRy);
91+
//----------------------------------------------------------------------------------
92+
93+
// Draw
94+
//----------------------------------------------------------------------------------
95+
BeginDrawing();
96+
97+
ClearBackground(bgColor);
98+
99+
DrawEllipse((int)ellipseACenter.x, (int)ellipseACenter.y,
100+
ellipseARx, ellipseARy,
101+
ellipsesCollide ? RED : BLUE);
102+
103+
DrawEllipse((int)ellipseBCenter.x, (int)ellipseBCenter.y,
104+
ellipseBRx, ellipseBRy,
105+
ellipsesCollide ? RED : GREEN);
106+
107+
DrawEllipseLines((int)ellipseACenter.x, (int)ellipseACenter.y,
108+
ellipseARx, ellipseARy, WHITE);
109+
110+
DrawEllipseLines((int)ellipseBCenter.x, (int)ellipseBCenter.y,
111+
ellipseBRx, ellipseBRy, WHITE);
112+
113+
DrawCircleV(ellipseACenter, 4, WHITE);
114+
DrawCircleV(ellipseBCenter, 4, WHITE);
115+
116+
if (ellipsesCollide) DrawText("ELLIPSES COLLIDE", screenWidth/2 - 120, 40, 28, RED);
117+
else DrawText("NO COLLISION", screenWidth/2 - 80, 40, 28, DARKGRAY);
118+
119+
// Controlled ellipse indicator
120+
DrawText(controlled == 0 ? "Controlling: A" : "Controlling: B",
121+
20, screenHeight - 40, 20, YELLOW);
122+
123+
if (mouseInA && controlled != 0) DrawText("Mouse inside ellipse A", 20, screenHeight - 70, 20, BLUE);
124+
if (mouseInB && controlled != 1) DrawText("Mouse inside ellipse B", 20, screenHeight - 70, 20, GREEN);
125+
126+
DrawText("Press [A] or [B] to switch control", 20, 20, 20, GRAY);
127+
128+
EndDrawing();
129+
//----------------------------------------------------------------------------------
130+
}
131+
132+
// De-Initialization
133+
//--------------------------------------------------------------------------------------
134+
CloseWindow();
135+
//--------------------------------------------------------------------------------------
136+
137+
return 0;
138+
}
28.5 KB
Loading

0 commit comments

Comments
 (0)