mightymandel v16

GPU-based Mandelbrot set explorer

interact.c
Go to the documentation of this file.
1 // mightymandel -- GPU-based Mandelbrot Set explorer
2 // Copyright (C) 2012,2013,2014,2015 Claude Heiland-Allen
3 // License GPL3+ http://www.gnu.org/licenses/gpl.html
4 
5 #include <math.h>
6 #include <string.h>
7 
8 #include "logging.h"
9 #include "interact.h"
10 #include "utility.h"
11 
12 void interact_begin(int w, int h, const mpfr_t cx, const mpfr_t cy, const mpfr_t r, double weight, bool show_glitches) {
13  memset(&interact, 0, sizeof(struct interact));
14  interact.width = w;
15  interact.height = h;
16  interact.weight = weight;
17  interact.show_glitches = show_glitches;
18  mpfr_init2(interact.centerx, mpfr_get_prec(cx));
19  mpfr_init2(interact.centery, mpfr_get_prec(cy));
20  mpfr_init2(interact.radius, mpfr_get_prec(r));
21  mpfr_set(interact.centerx, cx, MPFR_RNDN);
22  mpfr_set(interact.centery, cy, MPFR_RNDN);
23  mpfr_set(interact.radius, r, MPFR_RNDN);
24 }
25 
26 void interact_end(void) {
27  mpfr_clear(interact.centerx);
28  mpfr_clear(interact.centery);
29  mpfr_clear(interact.radius);
30 }
31 
32 void interact_reset(void) {
33  interact.quit = false;
34  interact.save_screenshot = false;
35  interact.updated = false;
36 }
37 
38 static void interact_coord(mpfr_t x, mpfr_t y, double px, double py) {
40 }
41 
42 static void interact_center(const mpfr_t x, const mpfr_t y) {
43  mpfr_prec_t bits = fmax(53, pxbits(interact.radius, interact.height));
44  mpfr_set_prec(interact.centerx, bits);
45  mpfr_set(interact.centerx, x, MPFR_RNDN);
46  mpfr_set_prec(interact.centery, bits);
47  mpfr_set(interact.centery, y, MPFR_RNDN);
48  interact.updated = true;
49 }
50 
51 static void interact_translate(double dx, double dy) {
52  double px = interact.width / 2.0 + dx;
53  double py = interact.height / 2.0 + dy;
54  mpfr_t x, y;
55  mpfr_init2(x, 53);
56  mpfr_init2(y, 53);
58  interact_center(x, y);
59  mpfr_clear(x);
60  mpfr_clear(y);
61 }
62 
63 static void interact_zoom_about(const mpfr_t x, const mpfr_t y, double factor) {
64  double g = pow(sqrt(0.5), factor);
65  mpfr_mul_d(interact.radius, interact.radius, g, MPFR_RNDN);
66  mpfr_prec_t p = fmax(53, pxbits(interact.radius, interact.height));
67  mpfr_prec_round(interact.centerx, p, MPFR_RNDN);
68  mpfr_prec_round(interact.centery, p, MPFR_RNDN);
69  mpfr_t t;
70  mpfr_init2(t, p);
71  mpfr_mul_d(t, x, (1 - g), MPFR_RNDN);
72  mpfr_mul_d(interact.centerx, interact.centerx, g, MPFR_RNDN);
73  mpfr_add(interact.centerx, interact.centerx, t, MPFR_RNDN);
74  mpfr_mul_d(t, y, (1 - g), MPFR_RNDN);
75  mpfr_mul_d(interact.centery, interact.centery, g, MPFR_RNDN);
76  mpfr_add(interact.centery, interact.centery, t, MPFR_RNDN);
77  mpfr_clear(t);
78  interact.updated = true;
79 }
80 
81 static void interact_zoom(double factor) {
83 }
84 
85 void interact_mouse(button button, double x, double y, bool shift, bool ctrl) {
86  double factor = (shift ? 5 : 1) * (ctrl ? 10 : 1);
87  mpfr_t vx, vy;
88  mpfr_inits2(53, vx, vy, (mpfr_ptr) 0);
89  interact_coord(vx, vy, x, y);
90  if (button == b_middle) { interact_center(vx, vy);
91  } else if (button == b_left || button == b_up ) { interact_zoom_about(vx, vy, factor);
92  } else if (button == b_right || button == b_down) { interact_zoom_about(vx, vy, -factor);
93  }
94  mpfr_clears(vx, vy, (mpfr_ptr) 0);
95 }
96 
97 void interact_keyboard(key key, bool shift, bool ctrl) {
98  double factor = (shift ? 5 : 1) * (ctrl ? 10 : 1);
99  switch (key) {
100  case k_quit: interact.quit = true; break;
101  case k_show_glitches:
103  log_message(LOG_NOTICE, "show glitches: %s\n", interact.show_glitches ? "yes" : "no");
104  break;
105  case k_zoom_in: interact_zoom( factor); break;
106  case k_zoom_out: interact_zoom(-factor); break;
107  case k_save_screenshot: interact.save_screenshot = true; break;
108  case k_weight_0: interact.weight = 5; break;
109  case k_weight_1: interact.weight = -4; break;
110  case k_weight_2: interact.weight = -3; break;
111  case k_weight_3: interact.weight = -2; break;
112  case k_weight_4: interact.weight = -1; break;
113  case k_weight_5: interact.weight = 0; break;
114  case k_weight_6: interact.weight = 1; break;
115  case k_weight_7: interact.weight = 2; break;
116  case k_weight_8: interact.weight = 3; break;
117  case k_weight_9: interact.weight = 4; break;
118  case k_left: interact_translate(-factor * 10, 0); break;
119  case k_right: interact_translate( factor * 10, 0); break;
120  case k_up: interact_translate(0, -factor * 10); break;
121  case k_down: interact_translate(0, factor * 10); break;
122  }
123 }