Enable zooming by drawing a rectangle with the mouse.

This commit is contained in:
felixm 2024-06-17 20:00:44 -04:00
parent 2efd9cfa32
commit 4357caf830
2 changed files with 88 additions and 19 deletions

View File

@ -1,2 +1,2 @@
main: main.c
gcc main.c -o main -I./raylib/include -L./raylib/lib -lraylib -lm
gcc -Wall -Wpedantic main.c -o main -I./raylib/include -L./raylib/lib -lraylib -lm

105
main.c
View File

@ -1,20 +1,33 @@
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "raylib.h"
#define WIDTH 800
#define HEIGHT 600
#define MAX_ITER 50
#define MAX_ITER 50
#define SELECTED CLITERAL(Color){ 112, 31, 126, 100 } // Dark Purple
int mandelbrot(double x, double y) {
typedef struct RectangleD {
double x; // Rectangle top-left corner position x
double y; // Rectangle top-left corner position y
double width; // Rectangle width
double height; // Rectangle height
} RectangleD;
float min(float x, float y) {
return (x < y) ? x : y;
}
int mandelbrot(double x, double y, int max_iter) {
int k;
double u = 0.0;
double v = 0.0;
double u2 = 0.0;
double v2 = 0.0;
for (k = 1; k < MAX_ITER && (u2 + v2 < 4.0); k++) {
for (k = 1; k < max_iter && (u2 + v2 < 4.0); k++) {
v = 2 * u * v + y;
u = u2 - v2 + x;
u2 = u * u;
@ -25,22 +38,29 @@ int mandelbrot(double x, double y) {
}
int main() {
InitWindow(WIDTH, HEIGHT, "Hello, raylib!");
double re_start = -2.0;
double re_end = 1.0;
double im_start = -1.0;
double im_end = 1.0;
void measure_time() {
// struct timespec start, end;
// double time_spent;
// clock_gettime(CLOCK_MONOTONIC, &start);
// clock_gettime(CLOCK_MONOTONIC, &end);
// time_spent = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
// printf("Execution time: %.9f seconds\n", time_spent);
}
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(RAYWHITE);
for (int x = 0; x < WIDTH; ++x) {
for (int y = 0; y < HEIGHT; ++y) {
double zreal = re_start + (x / (float) WIDTH) * (re_end - re_start);
double zimag = im_start + (y / (float) HEIGHT) * (im_end - im_start);
int m = mandelbrot(zreal, zimag);
void render_mandelbrot(RenderTexture2D *target, RectangleD *area) {
double re_start = area->x;
double re_end = area->x + area->width;
double im_start = area->y;
double im_end = area->y + area->height;
int width = GetScreenWidth();
int height = GetScreenHeight();
BeginTextureMode(*target);
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
double zreal = re_start + (x / (double) width) * (re_end - re_start);
double zimag = im_start + (y / (double) height) * (im_end - im_start);
int m = mandelbrot(zreal, zimag, MAX_ITER);
assert(m >= 0 && m <= MAX_ITER);
unsigned char c = 255 - ((m * 255) / MAX_ITER);
@ -48,6 +68,55 @@ int main() {
DrawPixel(x, y, color);
}
}
EndTextureMode();
}
int main() {
bool mouse_pressed = false;
Vector2 selection_start = { 0 };
RectangleD rect_mandelbrot = { -2.0, -1.0, 3.0, 2.0 };
Rectangle rect_selected = { 0 };
InitWindow(WIDTH, HEIGHT, "Mandelbrot Viewer");
RenderTexture2D target = LoadRenderTexture(800, 600);
render_mandelbrot(&target, &rect_mandelbrot);
while (!WindowShouldClose()) {
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
selection_start = GetMousePosition();
}
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
mouse_pressed = true;
rect_selected.x = min(selection_start.x, GetMouseX());
rect_selected.y = min(selection_start.y, GetMouseY());
rect_selected.width = abs(selection_start.x - GetMouseX());
rect_selected.height = rect_selected.width * (HEIGHT / (float) WIDTH);
}
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) {
rect_mandelbrot.x += (rect_mandelbrot.width * (double) (rect_selected.x / GetScreenWidth()));
rect_mandelbrot.y += (rect_mandelbrot.height * (double) (rect_selected.y / GetScreenHeight()));
rect_mandelbrot.width *= ((double) rect_selected.width / GetScreenWidth());
rect_mandelbrot.height *= ((double) rect_selected.height / GetScreenHeight());
render_mandelbrot(&target, &rect_mandelbrot);
}
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2) { 0, 0 }, WHITE);
if (mouse_pressed) {
DrawRectangleRec(rect_selected, SELECTED);
mouse_pressed = false;
}
EndDrawing();
}