Blame fractal.c

7321a1
7321a1
#include <helianthus.h></helianthus.h>
7321a1
#include <math.h></math.h>
7321a1
7321a1
7321a1
Animation anim = 0;
7321a1
unsigned char pixels[512][512][4];
7321a1
double r = 0.4, i = 0.6;
7321a1
double mx, my, zmx, zmy;
7321a1
double z = 1/128.0;
7321a1
double cx = -2;
7321a1
double cy = -2;
7321a1
7321a1
7321a1
void hsvToRgb(double h, double s, double v, unsigned char *pixel) {
7321a1
  h -= floor(h/360)*360;
7321a1
  s /= 100;
7321a1
  v = v/100*255;
7321a1
  s = s > 0 ? (s < 1 ? s : 1) : 0;
7321a1
  v = v > 0 ? (v < 255 ? v : 255) : 0;
7321a1
7321a1
  h /= 60.0;
7321a1
  int i = (int)h;
7321a1
  double f = h - i;
7321a1
  int pp = v*(1 - s);
7321a1
  int qq = v*(1 - s*f);
7321a1
  int tt = v*(1 - s*(1 - f));
7321a1
7321a1
  unsigned char p = (unsigned char)(pp > 0 ? (pp < 255 ? pp : 255) : 0);
7321a1
  unsigned char q = (unsigned char)(qq > 0 ? (qq < 255 ? qq : 255) : 0);
7321a1
  unsigned char t = (unsigned char)(tt > 0 ? (tt < 255 ? tt : 255) : 0);
7321a1
  unsigned char u = (unsigned char)v;
7321a1
7321a1
  switch(i) {
7321a1
    case  0: pixel[0] = u, pixel[1] = t, pixel[2] = p; break;
7321a1
    case  1: pixel[0] = q, pixel[1] = u, pixel[2] = p; break;
7321a1
    case  2: pixel[0] = p, pixel[1] = u, pixel[2] = t; break;
7321a1
    case  3: pixel[0] = p, pixel[1] = q, pixel[2] = u; break;
7321a1
    case  4: pixel[0] = t, pixel[1] = p, pixel[2] = u; break;
7321a1
    default: pixel[0] = u, pixel[1] = p, pixel[2] = q; break;
7321a1
  }
7321a1
  pixel[3] = 255;
7321a1
}
7321a1
7321a1
7321a1
void setColor(double x, unsigned char *pixel) {
7321a1
  double h0 = 240;
7321a1
  double h1 = 0;
7321a1
  double h = h0 + (h1 - h0)*x;
7321a1
  hsvToRgb(h, 100, 100, pixel);
7321a1
}
7321a1
7321a1
7321a1
void julia(double r, double i) {
7321a1
  for(int y = 0; y < 512; ++y) {
7321a1
    for(int x = 0; x < 512; ++x) {
7321a1
      double rr = x*z + cx;
7321a1
      double ii = y*z + cy;
7321a1
      int b;
7321a1
      for(b = 0; b < 64; ++b) {
7321a1
        if (rr*rr + ii*ii > 4) break;
7321a1
        double x = rr*rr - ii*ii + r;
7321a1
        ii = 2*rr*ii + i;
7321a1
        rr = x;
7321a1
      }
7321a1
      setColor(b/64.0, pixels[y][x]);
7321a1
    }
7321a1
  }
7321a1
7321a1
}
7321a1
7321a1
7321a1
void fractal() {
7321a1
  if (anim) animationDestroy(anim);
7321a1
  julia(r, i);
7321a1
  anim = createAnimationFromImageEx(512, 512, pixels, FALSE, FALSE, FALSE, FALSE);
7321a1
}
7321a1
7321a1
7321a1
void init() {
7321a1
  fractal();
7321a1
}
7321a1
7321a1
7321a1
void draw() {
7321a1
  double dt = worldGetFrameTime();
7321a1
  int changed = 0;
7321a1
7321a1
  if (mouseDown("middle")) {
7321a1
    r += (mouseX() - mx)*z/10;
7321a1
    i += (mouseY() - my)*z/10;
7321a1
    changed = 1;
7321a1
  }
7321a1
7321a1
  if (mouseDown("left") || mouseDown("right")) {
7321a1
    double k = pow(4, dt);
7321a1
    if (mouseDown("left")) k = 1/k;
7321a1
    cx += mouseX()*z*(1 - k);
7321a1
    cy += mouseY()*z*(1 - k);
7321a1
    z *= k;
7321a1
    changed = 1;
7321a1
  }
7321a1
7321a1
  mx = mouseX();
7321a1
  my = mouseY();
7321a1
7321a1
  if (changed) fractal();
7321a1
  fill(colorByName("white"));
7321a1
  rectTextured(anim, 0, 0, 512, 512);
7321a1
}
7321a1
7321a1
7321a1
int main() {
7321a1
  worldSetInit(&init);
7321a1
  worldSetDraw(&draw);
7321a1
  worldSetFrameRateEx(1, 100);
7321a1
  worldRun();
7321a1
}