-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathraytracing.cpp
More file actions
139 lines (110 loc) · 3.9 KB
/
Copy pathraytracing.cpp
File metadata and controls
139 lines (110 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <iostream>
#include <SDL3/SDL.h>
#define _USE_MATH_DEFINES
#include <math.h>
#define WIDTH 1300
#define HEIGHT 600
#define RAYS_N 1000
#define RAY_THICKNESS 2
#define COLOR_WHITE 0xffffffff
#define COLOR_BLACK 0x00000000
#define COLOR_YELLOW 0xFFC014
#define COLOR_ORANGE 0xffd43b
struct Circle{
double x;
double y;
double r;
};
struct Ray{
double x_0, y_0;
double x_e, y_e;
double angle;
};
void fillCircle(SDL_Surface* surface, struct Circle circle, Uint32 color){
double radius_squared = pow(circle.r, 2);
for(double x = circle.x - circle.r; x <= circle.x + circle.r; ++x){
for(double y = circle.y - circle.r; y < circle.y + circle.r; ++y){
double distance_squared = pow(x - circle.x, 2) + pow(y - circle.y, 2);
if(distance_squared < radius_squared){
SDL_Rect pixel = (SDL_Rect){static_cast<int>(x), static_cast<int>(y), 1, 1};
SDL_FillSurfaceRect(surface, &pixel, color);
}
}
}
return;
}
void generateRays(struct Circle circle, struct Ray rays[RAYS_N]){
for(int i = 0; i < RAYS_N; ++i){
double angle = (static_cast<double>(i) / RAYS_N) * 2.0 * M_PI;
struct Ray ray = {circle.x, circle.y, angle, 0, 0};
rays[i].angle = angle;
rays[i].x_0 = circle.x;
rays[i].y_0 = circle.y;
}
return;
}
void fillRays(SDL_Surface* surface, struct Ray rays[RAYS_N], Uint32 color, struct Circle obstacle){
double radius_squared = pow(obstacle.r, 2);
for(int i = 0; i < RAYS_N; ++i){
struct Ray ray = rays[i];
int end_of_screen = 0;
int obstacle_hit = 0;
double step = 1;
double x_draw = ray.x_0;
double y_draw = ray.y_0;
while(!end_of_screen && !obstacle_hit){
x_draw += step * cos(ray.angle);
y_draw += step * sin(ray.angle);
SDL_Rect pixel = (SDL_Rect){static_cast<int>(x_draw), static_cast<int>(y_draw), RAY_THICKNESS, RAY_THICKNESS};
SDL_FillSurfaceRect(surface, &pixel, color);
if(x_draw < 0 || x_draw > WIDTH) end_of_screen = 1;
if(y_draw < 0 || y_draw > HEIGHT) end_of_screen = 1;
double distance_squared = pow(x_draw - obstacle.x, 2) + pow(y_draw - obstacle.y, 2);
if(distance_squared < radius_squared){
break;
}
}
}
return;
}
void moveObstacle(struct Circle* obstacle, double& speed){
obstacle->y += speed;
if (obstacle->y - obstacle->r <= 0 || obstacle->y + obstacle->r >= HEIGHT) {
speed = -speed;
}
return;
}
int main(){
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("Raytracing", WIDTH, HEIGHT, 0);
SDL_Surface* surface = SDL_GetWindowSurface(window);
SDL_Rect rect = (SDL_Rect) {200,200,200,200};
struct Circle circle = {200.0, 200.0, 40.0};
struct Circle obstacle = {900.0, 250.0, 120.0};
SDL_Rect erase_rect = (SDL_Rect){0, 0, WIDTH, HEIGHT};
struct Ray rays[RAYS_N];
generateRays(circle, rays);
int simulation_running = 1;
SDL_Event event;
double obstacleSpeed = 5;
while(simulation_running){
while(SDL_PollEvent(&event)){
if(event.type == SDL_EVENT_QUIT){
simulation_running = 0;
}
if(event.type == SDL_EVENT_MOUSE_MOTION && (event.motion.state & SDL_BUTTON_LMASK)){
circle.x = event.motion.x;
circle.y = event.motion.y;
generateRays(circle, rays);
}
}
SDL_FillSurfaceRect(surface, &erase_rect, COLOR_BLACK);
fillRays(surface, rays, COLOR_ORANGE, obstacle);
fillCircle(surface, circle, COLOR_WHITE);
fillCircle(surface, obstacle, COLOR_WHITE);
SDL_UpdateWindowSurface(window);
SDL_Delay(20);
moveObstacle(&obstacle, obstacleSpeed);
}
return 0;
}