#include "library.h" struct complex { double real, imag; }; struct point { double x, y; }; const double win_width = 700, win_height = 700; double range_min_real = -2, range_max_real = 2; double range_min_imag = -2, range_max_imag = 2; double x_scale = 0.5 * win_width / (range_max_real - range_min_real); double y_scale = 0.5 * win_height / (range_max_imag - range_min_imag); complex make_complex(double r, double i) { complex c; c.real = r; c.imag = i; return c; } point make_point(double x, double y) { point p; p.x = x; p.y = y; return p; } complex point_to_complex(point p) { complex c; c.real = p.x / win_width * (range_max_real - range_min_real) + range_min_real; c.imag = (win_height - p.y) / win_height * (range_max_imag - range_min_imag) + range_min_imag; return c; } point complex_to_point(complex c) { point p; p.x = (c.real - range_min_real) / (range_max_real - range_min_real) * win_width; p.y = win_height - (c.imag - range_min_imag) / (range_max_imag - range_min_imag) * win_height; return p; } void print(complex c) { cout << c.real << " + " << c.imag << "i\n"; } void print(point p) { cout << p.x << ", " << p.y << "\n"; } complex add(complex a, complex b) { complex c; c.real = a.real + b.real; c.imag = a.imag + b.imag; return c; } complex sub(complex a, complex b) { complex c; c.real = a.real - b.real; c.imag = a.imag - b.imag; return c; } complex mul(complex a, complex b) { complex c; c.real = a.real * b.real - a.imag * b.imag; c.imag = a.real * b.imag + a.imag * b.real; return c; } complex div(complex a, complex b) { complex c; double bottom = b.real * b.real + b.imag * b.imag; if (bottom==0.0) cout << "Error, division by zero!\n"; else { c.real = (a.real * b.real + a.imag * b.imag) / bottom; c.imag = (b.real * a.imag - a.real * b.imag) / bottom; } return c; } double magnitude(complex a) { return sqrt(a.real*a.real + a.imag*a.imag); } void move_to(complex c) { point p = complex_to_point(c); move_to(p.x, p.y); } void draw_to(complex c) { point p = complex_to_point(c); draw_to(p.x, p.y); } void draw_point(complex c) { point q = complex_to_point(c); draw_point(q.x, q.y); } void draw_axes() { set_pen_width(1); set_pen_color(color::white); fill_rectangle(0, 0, (int)win_width+1, (int)win_height+1, color::white); set_pen_color(color::grey); complex c; for (c.real = range_min_real; c.real <= range_max_real; c.real += 1) { c.imag = range_min_real; move_to(c); c.imag = range_max_real; draw_to(c); } for (c.imag = range_min_imag; c.imag <= range_max_imag; c.imag += 1) { c.real = range_min_imag; move_to(c); c.real = range_max_imag; draw_to(c); } set_pen_color(color::black); move_to(make_complex(0.0, range_max_imag)); draw_to(make_complex(0.0, range_min_imag)); move_to(make_complex(range_max_real, 0.0)); draw_to(make_complex(range_min_real, 0.0)); } complex click_to_complex() { wait_for_mouse_click(); point p; p.x = get_click_x(); p.y = get_click_y(); return point_to_complex(p); } void zoom_in_on(complex centre, double zoom_factor) { double whole = range_max_real - range_min_real; range_min_real = centre.real - whole/(2*zoom_factor); range_max_real = centre.real + whole/(2*zoom_factor); whole = range_max_imag - range_min_imag; range_min_imag = centre.imag - whole/(2*zoom_factor); range_max_imag = centre.imag + whole/(2*zoom_factor); x_scale = win_width / (range_max_real - range_min_real); y_scale = win_height / (range_max_imag - range_min_imag); } void main() { make_window(win_width, win_height); draw_axes(); set_pen_width(4); point p; while (true) { for (p.x = 0; p.x < win_width; p.x += 1) { for (p.y = 0; p.y < win_height; p.y += 1) { complex c = point_to_complex(p); complex v = c; double m = 0; for (int i=0; i<1000 && m < 3; i+=1) { c = add(mul(c, c), v); m = magnitude(c); } if (m<3) set_pixel_color(p.x, p.y, color::red); else set_pixel_color(p.x, p.y, color::yellow); } } complex c = click_to_complex(); zoom_in_on(c, 2); } }