juliamath.h (5115B)
1 /* 2 Back-end Math for the Julia/Mandelbrot Set header file 3 "juliamath.h" 4 M. Yamanaka 5 email: myamanaka@live.com 6 website: csmyamanaka.com 7 license: MIT (See included "LICENSE" file for details) 8 */ 9 10 #pragma once 11 12 /* 13 I'm using a config file as a part of the source code suckless style 14 Please note that the file to edit is "config.c" not "config.h" 15 */ 16 #include "config.h" 17 #include <stdlib.h> 18 19 /* 20 Complex addition/multiplication 21 Both the Mandelbrot and Julia sets are sets of complex numbers thereby necessitating some complex arithmetics. 22 The arguments from left to right are: 23 float* ... result 24 float* ... first operand 25 float* ... second operand 26 There is a return value of an integer which doesn't do anything for now but 27 eventually, I may implement error codes 28 */ 29 int cmplxAdd(float*, float*, float*); 30 int cmplxMult(float*, float*, float*); 31 32 /* 33 Complex length squared 34 The distance from a given complex number to origin of the complex plane (0 + 0i) is the length or the magnitude 35 of a complex number. This function calculates this value squared as it is easier to calculate and is equally useful 36 in the Julia/Mandelbrot set algorithm. 37 The sole argument to this function is: 38 float* ... input complex number 39 The return value is the result of the calculation 40 */ 41 float cmplxLenSq(float*); 42 43 /* 44 Domain conversion 45 Axis-agnostically converts a number in the pixel domain to the complex domain, namely an integer in [0, # of pixels) is 46 converted to a float in [min, max). 47 The arguments from left to right are: 48 int ... input number in the pixel domain in either axis 49 int ... the length of the axis in the pixel domain 50 float ... minimum value of a given axis in the complex plane 51 float ... maximum value of a given axis in the complex plane 52 The resulting number in the complex plane (irrespective of the axis) is returned. 53 */ 54 float convNtoR(int, int, float, float); 55 56 /* 57 Function of z 58 ... or f(z) = z^2 + C as described by the first reference video (labelled [1] in the "README" file under the "Acknowledgment" section). 59 Although this isn't a mathematically pure implementation (i.e. doesn't return a complex number), it instead updates the z parameter 60 since its address is available to the function. Likewise, variable storing the number of iterations until termination is 61 also incremented through reference. In a purely mathematical sense, the termination condition is described in the first reference 62 video as the instance where the magnitude of f(z) is greater than 2 but in a practical sense, the video also shows a case where 63 it takes many iterations (over 1000 iterations for C = -0.55 + 0.48i in the video) to reach this point in the Mandelbrot set. 64 For this reason, the number of iterations is restricted, favouring computational feasibility over accuracy. For my implementation, 65 this limit is controlled by the variable "iter_max" in the included configuration file "config.c". 66 The second reference video (labelled [2] in the "README" file under "Acknowledgment") shows how this equation can be used to 67 generate both the Julia set as well as the Mandelbrot set by adjusting the parameters appropriately (see "imgIters" below for details). 68 The arguments from left to right are: 69 float* ... first complex number i.e. z 70 float* ... second complex number i.e. C 71 int* ... address keeping track of current iteration count 72 The return value is unused but may be used in the future to indicate errors. 73 */ 74 int fz(float*, float*, int*); 75 76 /* 77 Iteration values over the image 78 For every pixel in the resulting image, this function uses the above function "fz" or f(z) = z^2 + C to calculate the number of iterations 79 to reach the aforementioned termination conditions. According to the second reference video (See [2] in README), the Mandelbrot and Julia 80 sets begin their respective iteration processes by determining which of the variables in the equation f(z) = z^2 + C corresponds to the pixel 81 values and which is constant. The reference video provides a helpful chart showing that for the Mandelbrot set, C corresponds to the pixel 82 values and the initial z value is 0 whereas, for the Julia set, the z corresponds to the pixel values and C is a pre-selected constant which 83 determines the appearance of the resulting fractal. In my implementation, the user can choose this value in the configuration file "config.c" 84 by modifying the value of the variable "julia_C". Based on this reference video, my understanding is that any value reasonably close to and within 85 the borders of the mandelbrot set should produce reasonably nice looking Julia fractals. I have done some experimenting with different C values 86 and found that C = -0.1 - i (i.e. julia_C[2] = {-0.1, -1}) looks ok at 30 iterations (i.e. iter_max = 30 in "config.c"). 87 The variable "fractal_flag" in "config.c" determines which type of fractal is generated (0 ... mandelbrot, else julia). 88 The arguments from left to right are: 89 int ... width 90 int ... height 91 The resulting array is returned. 92 */ 93 int* imgIters(int, int);