Skip to content

Commit 19df227

Browse files
committed
xmandlebrot now allows zooming in and out of the image by clicking.
1 parent 053f975 commit 19df227

File tree

1 file changed

+49
-9
lines changed

1 file changed

+49
-9
lines changed

unix/xmandelbrot.c

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ struct color colors_2bit[4];
2626
struct color colors_4bit[16];
2727
struct color colors_8bit[256];
2828

29+
#define DEFAULT_X_SHIFT 2.5
30+
#define DEFAULT_Y_SHIFT 1.0
31+
#define DEFAULT_X_SCALE 3.5
32+
#define DEFAULT_Y_SCALE 2.1
33+
34+
struct viewport {
35+
double x_shift, y_shift;
36+
double x_scale, y_scale;
37+
};
38+
2939
void get_window_size(display, window, height, width)
3040
Display *display;
3141
Window window;
@@ -65,12 +75,13 @@ double time_in_seconds()
6575
return t / 60.0;
6676
}
6777

68-
void calculate(display, window, gc, palette, palette_size)
78+
void calculate(display, window, gc, palette, palette_size, viewport)
6979
Display *display;
7080
Window window;
7181
GC gc;
7282
unsigned long int *palette;
7383
size_t palette_size;
84+
struct viewport viewport;
7485
{
7586
unsigned int i, col, row, iteration;
7687
double width, height, x0, y0, x, y, xtemp;
@@ -89,10 +100,10 @@ void calculate(display, window, gc, palette, palette_size)
89100
for (row = 0; row < lines; row++)
90101
{
91102
// printf("Row: %u\n", row);q
92-
y0 = (row * 2.1 / height) - 1;
103+
y0 = (row * viewport.y_scale / height) - viewport.y_shift;
93104
for (col = 0; col < cols; col++)
94105
{
95-
x0 = (col * 3.5 / width) - 2.5;
106+
x0 = (col * viewport.x_scale / width) - viewport.x_shift;
96107
x = 0.0;
97108
y = 0.0;
98109
iteration = 0;
@@ -113,7 +124,7 @@ void calculate(display, window, gc, palette, palette_size)
113124
}
114125

115126
finish = time_in_seconds();
116-
printf("Height: %u, Width: %u, Time: %0.3f Seconds\n", lines, cols, (finish-start));
127+
printf("Height: %u, Width: %u, Time: %0.3f Seconds (Viewport: {x - %0.3f, y - %0.3f, x * %0.3f, y * %0.3f})\n", lines, cols, (finish-start), viewport.x_shift, viewport.y_shift, viewport.x_scale, viewport.y_scale);
117128

118129
}
119130

@@ -215,8 +226,6 @@ void initialize_colors()
215226
}
216227
}
217228

218-
printf("Initialized %u colors.\n", idx);
219-
220229
}
221230

222231
void create_palette(display, colormap, palette, colors, size)
@@ -258,10 +267,17 @@ int main(argc,argv)
258267
unsigned int width, height, lastWidth, lastHeight;
259268
struct color *colors = colors_8bit;
260269
Colormap colormap;
261-
270+
struct viewport viewport;
271+
int max_iterations = 256;
262272
unsigned long palette[256];
273+
int x_center, y_center;
274+
double click_x, click_y;
263275

264-
int max_iterations = 256;
276+
viewport.x_shift = DEFAULT_X_SHIFT;
277+
viewport.y_shift = DEFAULT_Y_SHIFT;
278+
viewport.x_scale = DEFAULT_X_SCALE;
279+
viewport.y_scale = DEFAULT_Y_SCALE;
280+
265281
if (argc > 1)
266282
{
267283
max_iterations = atoi(argv[1]);
@@ -271,6 +287,7 @@ int main(argc,argv)
271287
exit(1);
272288
}
273289
}
290+
274291
initialize_colors();
275292

276293
/* setup display/screen */
@@ -347,7 +364,7 @@ int main(argc,argv)
347364
get_window_size(display, window, &height, &width);
348365
if (width != lastWidth || height != lastHeight)
349366
{
350-
calculate(display, window, gc, palette, max_iterations);
367+
calculate(display, window, gc, palette, max_iterations, viewport);
351368
}
352369
lastWidth = width;
353370
lastHeight = height;
@@ -359,6 +376,29 @@ int main(argc,argv)
359376
break;
360377
case ButtonPress:
361378
/* Mouse button was pressed. */
379+
/* Calculate the world coordinates of the clicked point */
380+
click_x = (event.xbutton.x * viewport.x_scale / width) - viewport.x_shift;
381+
click_y = (event.xbutton.y * viewport.y_scale / height) - viewport.y_shift;
382+
383+
/* increase or decrease the scale of the viewport depending on the button pressed */
384+
if (event.xbutton.button == 1)
385+
{
386+
viewport.x_scale *= 0.75;
387+
viewport.y_scale *= 0.75;
388+
}
389+
else if (event.xbutton.button == 3)
390+
{
391+
viewport.x_scale *= 1.25;
392+
viewport.y_scale *= 1.25;
393+
}
394+
395+
/* Adjust the viewport to center on the clicked point */
396+
x_center = width / 2;
397+
y_center = height / 2;
398+
viewport.x_shift = (x_center * viewport.x_scale / width) - click_x;
399+
viewport.y_shift = (y_center * viewport.y_scale / height) - click_y;
400+
401+
calculate(display, window, gc, palette, max_iterations, viewport);
362402
break;
363403
case KeyPress:
364404
/* Key input. */

0 commit comments

Comments
 (0)