mightymandel v16

GPU-based Mandelbrot set explorer

parse_ppar_corners.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 <assert.h>
6 #include <stdbool.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <mpfr.h>
11 
12 #include "parse.h"
13 #include "parse_ppar_corners.h"
14 #include "logging.h"
15 
16 bool parse_ppar_corners(const char *source, int length, mpfr_t cx, mpfr_t cy, mpfr_t cz) {
17  (void) length;
18  char *source2 = strdup(source);
19  char *s = source2;
20  char *corners = 0; // CORNERS=[xmin/xmax/ymin/ymax[/x3rd/y3rd]]
21  while (s) {
22  char *line = parse_line(&s);
23  if (0 == strncmp(line, "corners=", 8)) {
24  corners = line + 8;
25  debug_message("parse_ppar: corners = %s\n", corners);
26  int len = strlen(line);
27  char *sxmin = malloc(len); sxmin[0] = 0; // string for xmin
28  char *sxmax = malloc(len); sxmax[0] = 0; // string for xmax
29  char *symin = malloc(len); symin[0] = 0; // string for ymin
30  char *symax = malloc(len); symax[0] = 0; // string for ymax
31  s = strtok(corners, "/");
32  strcpy(sxmin, s);
33  int i = 2;
34  while(s != NULL) {
35  s = strtok(NULL, "/");
36  if (s) {
37  switch (i) {
38  case 2: strcpy(sxmax, s); break;
39  case 3: strcpy(symin, s); break;
40  case 4: strcpy(symax, s); break;
41  }
42  }
43  i++;
44  }
45  //check
46  debug_message("parse_ppar: sxmin = %s ; sxmax = %s ; symin = %s ; symax = %s\n", sxmin, sxmax, symin, symax);
47  // variables
48  mpfr_t xmin, xmax, ymin, ymax; // corners
49  mpfr_t dx, dy; // d# = #max - #min
50  // initialize
51  mpfr_inits2(256, xmin, xmax, ymin, ymax, dx, dy, (mpfr_ptr) 0); // FIXME hardcoded precision
52  mpfr_set_str(xmin, sxmin, 10, MPFR_RNDN);
53  mpfr_set_str(xmax, sxmax, 10, MPFR_RNDN);
54  mpfr_set_str(ymin, symin, 10, MPFR_RNDN);
55  mpfr_set_str(ymax, symax, 10, MPFR_RNDN);
56  debug_message("parse_ppar: xmin = %Re\n", xmin);
57  debug_message("parse_ppar: xmax = %Re\n", xmax);
58  debug_message("parse_ppar: ymin = %Re\n", ymin);
59  debug_message("parse_ppar: ymax = %Re\n", ymax);
60  // computing:
61  // cx = center x = xmin + (xmax - xmin) / 2
62  // cy = center y = ymin + radius
63  // cz = radius = (ymax - ymin) / 2
64  mpfr_sub(dx, xmax, xmin, MPFR_RNDN);
65  mpfr_sub(dy, ymax, ymin, MPFR_RNDN);
66  debug_message("parse_ppar: dx = %Re\n", dx);
67  debug_message("parse_ppar: dy = %Re\n", dy);
68  mpfr_div_2ui(dy, dy, 1, MPFR_RNDN);
69  mpfr_div_2ui(dx, dx, 1, MPFR_RNDN);
70  mpfr_abs(cz, dy, MPFR_RNDN);
71  debug_message("parse_ppar: radius = cz = %Re\n", cz);
72  if (! radius_is_valid(cz)) {
73  free(sxmin);
74  free(sxmax);
75  free(symin);
76  free(symax);
77  free(source2);
78  return false;
79  }
80  mpfr_prec_t p = precision_for_radius(cz);
81  mpfr_set_prec(cy, p);
82  mpfr_add(cy, ymin, dy, MPFR_RNDN);
83  debug_message("parse_ppar: cy = %Re\n", cy);
84  mpfr_set_prec(cx, p);
85  mpfr_add(cx, xmin, dx, MPFR_RNDN);
86  debug_message("parse_ppar: cx = %Re\n", cx);
87  // cleanup
88  mpfr_clears(xmin, xmax, ymin, ymax, dx, dy, (mpfr_ptr) 0);
89  free(sxmin);
90  free(sxmax);
91  free(symin);
92  free(symax);
93  free(source2);
94  return true;
95  }
96  }
97  free(source2);
98  return false;
99 }