qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs fractal.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs fractal.c
Date: Sat, 29 Apr 2017 05:22:45 -0400 (EDT)

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        17/04/29 05:22:45

Modified files:
        .              : fractal.c 

Log message:
        tests: add fractal types

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/fractal.c?cvsroot=qemacs&r1=1.2&r2=1.3

Patches:
Index: fractal.c
===================================================================
RCS file: /sources/qemacs/qemacs/fractal.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- fractal.c   28 Apr 2017 13:32:43 -0000      1.2
+++ fractal.c   29 Apr 2017 09:22:45 -0000      1.3
@@ -319,12 +319,15 @@
 #define MFT  "%.16Lg"
 #endif
 
+typedef struct { fnum_t a, b; } cnum_t;
+
 typedef struct FractalState FractalState;
 
 struct FractalState {
     QEModeData base;
 
     int cols, rows;
+    int type;
     int maxiter;        /* maximum iteration number */
     int cb, nc;         /* color palette base and length */
     int rot;            /* rotation in degrees */
@@ -353,6 +356,136 @@
     return qe_get_buffer_mode_data(e->b, &fractal_mode, status ? e : NULL);
 }
 
+static fnum_t cmod2(cnum_t z) {
+    return z.a * z.a + z.b * z.b;
+}
+
+static cnum_t cpower(cnum_t z, int exp) {
+    cnum_t r = { 1, 0 };
+    fnum_t a;
+
+    while (exp > 0) {
+        if (exp & 1) {
+            a = r.a;
+            r.a = a * z.a - r.b * z.b;
+            r.b = a * z.b + r.b * z.a;
+        }
+        exp >>= 1;
+        a = z.a;
+        z.a = a * a - z.b * z.b;
+        z.b = 2 * a * z.b;
+    }
+    return r;
+}
+
+static int mandelbrot_func(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) {
+    fnum_t a, b, c;
+    int i;
+    for (a = b = i = 0; a * a + b * b <= bailout && i++ < maxiter;) {
+        c = a;
+        a = a * a - b * b + x;
+        b = 2 * c * b + y;
+    }
+    return i;
+}
+
+static int mandelbrot3_func(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) {
+    fnum_t a, b, c;
+    int i;
+    for (a = b = i = 0; a * a + b * b <= bailout && i++ < maxiter;) {
+        c = a;
+        a = a * a * a - 3 * a * b * b + x;
+        b = 3 * c * c * b - b * b * b + y;
+    }
+    return i;
+}
+
+static int mandelbrot4_func(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) {
+    fnum_t a, b, a2, b2;
+    int i;
+    for (a = b = i = 0; a * a + b * b <= bailout && i++ < maxiter;) {
+        a2 = a * a - b * b;
+        b2 = 2 * a * b;
+        a = a2 * a2 - b2 * b2 + x;
+        b = 2 * a2 * b2 + y;
+    }
+    return i;
+}
+
+static int mandelbrot5_func(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) {
+    fnum_t a, b, a2, b2, a3, b3;
+    int i;
+    for (a = b = i = 0; a * a + b * b <= bailout && i++ < maxiter;) {
+        a3 = a * a * a - 3 * a * b * b;
+        b3 = 3 * a * a * b - b * b * b;
+        a2 = a * a - b * b;
+        b2 = 2 * a * b;
+        a = a2 * a3 - b2 * b3 + x;
+        b = b2 * a3 + a2 * b3 + y;
+    }
+    return i;
+}
+
+static int mandelbrot6_func(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) {
+    fnum_t a, b, a3, b3;
+    int i;
+    for (a = b = i = 0; a * a + b * b <= bailout && i++ < maxiter;) {
+        a3 = a * a * a - 3 * a * b * b;
+        b3 = 3 * a * a * b - b * b * b;
+        a = a3 * a3 - b3 * b3 + x;
+        b = 2 * a3 * b3 + y;
+    }
+    return i;
+}
+
+static int mandelbrot7_func(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) {
+    cnum_t z = { 0, 0 };
+    int i;
+    for (i = 0; cmod2(z) <= bailout && i++ < maxiter;) {
+        z = cpower(z, 7);
+        z.a += x;
+        z.b += y;
+    }
+    return i;
+}
+
+static int mandelbrot8_func(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) {
+    cnum_t z = { 0, 0 };
+    int i;
+    for (i = 0; cmod2(z) <= bailout && i++ < maxiter;) {
+        z = cpower(z, 8);
+        z.a += x;
+        z.b += y;
+    }
+    return i;
+}
+
+static int mandelbrot9_func(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) {
+    cnum_t z = { 0, 0 };
+    int i;
+    for (i = 0; cmod2(z) <= bailout && i++ < maxiter;) {
+        z = cpower(z, 9);
+        z.a += x;
+        z.b += y;
+    }
+    return i;
+}
+
+static struct FractalType {
+    const char *name;
+    const char *formula;
+    int (*func)(fnum_t x, fnum_t y, fnum_t bailout, int maxiter);
+} const fractal_type[] = {
+    { "Mandelbrot", "z=z^2+c", mandelbrot_func },
+    { "Mandelbrot3", "z=z^3+c", mandelbrot3_func },
+    { "Mandelbrot4", "z=z^4+c", mandelbrot4_func },
+    { "Mandelbrot5", "z=z^5+c", mandelbrot5_func },
+    { "Mandelbrot6", "z=z^6+c", mandelbrot6_func },
+    { "Mandelbrot7", "z=z^7+c", mandelbrot7_func },
+    { "Mandelbrot8", "z=z^8+c", mandelbrot8_func },
+    { "Mandelbrot9", "z=x^9+c", mandelbrot9_func },
+};
+
 static void fractal_set_rotation(FractalState *ms, int rot) {
     ms->rot = rot;
     /* compute rotation matrix */
@@ -377,6 +510,9 @@
         p += strspn(p, ";, \t\r\n");
         if (*p == '\0')
             break;
+        if (strstart(p, "type=", &p)) {
+            ms->type = clamp(strtol(p, (char **)&p, 0), 0, 
countof(fractal_type));
+        } else
         if (strstart(p, "maxiter=", &p)) {
             ms->maxiter = strtol(p, (char **)&p, 0);
         } else
@@ -414,42 +550,34 @@
     int i, j, nx, ny, fg, bg;
     fnum_t xc = ms->x, yc = ms->y, scale = ms->scale;
     fnum_t bailout = ms->bailout;
-    fnum_t sx, sy, x, y, dx, dy, xr, yr, a, b, c;
+    fnum_t x, y, dx, dy, xr, yr;
+    int (*func)(fnum_t x, fnum_t y, fnum_t bailout, int maxiter) =
+        fractal_type[ms->type].func;
 
     if (s->height == 0 || s->width == 0 || rows == 0 || cols == 0 || nc == 0)
         return;
 
-    sx = 3.2 * scale;
+    dx = 3.2 * scale / cols;
     if (s->width == s->cols) {
         /* character based, assume 80x25 4/3 aspect ratio */
-        sy = sx * 3 / 4 * 80 / 23 * rows / cols;
+        dy = dx * 2.4;
     } else {
         /* pixel based, assume 100% pixel aspect ratio */
-        sy = sx * s->height / s->width;
+        dy = dx * cols / s->width * s->height / rows;
     }
-    dx = sx / cols;
-    dy = sy / rows;
 
     s->b->flags &= ~BF_READONLY;
 
     eb_delete_range(s->b, 0, s->b->total_size);
 
-    for (ny = 0, y = -sy / 2; ny < rows; ny++, y += dy) {
-        for (nx = 0, x = -sx / 2; nx < cols; nx++, x += dx) {
+    for (ny = 0, y = -dy * rows / 2; ny < rows; ny++, y += dy) {
+        for (nx = 0, x = -dx * cols / 2; nx < cols; nx++, x += dx) {
             xr = xc + x * ms->m0 + y * ms->m1;
             yr = yc + x * ms->m2 + y * ms->m3;
-            for (a = b = i = 0;
-                 a * a + b * b <= bailout && i++ < maxiter;
-                 c = a, a = a * a - b * b + xr, b = 2 * c * b + yr)
-                continue;
-            //xr = xc + x * ms->m0 + (y + dy / 2) * ms->m1;
-            //yr = yc + x * ms->m2 + (y + dy / 2) * ms->m3;
+            i = (*func)(xr, yr, bailout, maxiter);
             xr += dy / 2 * ms->m1;
             yr += dy / 2 * ms->m3;
-            for (a = b = j = 0;
-                 a * a + b * b <= bailout && j++ < maxiter;
-                 c = a, a = a * a - b * b + xr, b = 2 * c * b + yr)
-                continue;
+            j = (*func)(xr, yr, bailout, maxiter);
             bg = i >= maxiter ? 0 : cb + i % nc;
             fg = j >= maxiter ? 0 : cb + j % nc;
             s->b->cur_style = QE_TERM_COMPOSITE | QE_TERM_MAKE_COLOR(fg, bg);
@@ -460,7 +588,8 @@
     }
     s->b->flags |= BF_READONLY;
 
-    put_status(s, "Mandelbrot set x="MFT", y="MFT", zoom=%d, scale=%.6g, 
rot=%d",
+    put_status(s, "%s set x="MFT", y="MFT", zoom=%d, scale=%.6g, rot=%d",
+               fractal_type[ms->type].name,
                ms->x, ms->y, ms->zoom, (double)ms->scale, ms->rot);
 }
 
@@ -524,6 +653,14 @@
     }
 }
 
+static void do_fractal_set_type(EditState *s, int key) {
+    FractalState *ms = fractal_get_state(s, 1);
+    if (ms) {
+        ms->type = key - '1';
+        do_fractal_refresh(s);
+    }
+}
+
 static void do_fractal_set_parameters(EditState *s, const char *params) {
     FractalState *ms = fractal_get_state(s, 1);
     if (ms) {
@@ -546,7 +683,8 @@
 
     eb_printf(b, "Fractal description:\n\n");
 
-    eb_printf(b, "%*s: %s\n", w, "type", "Mandelbrot");
+    eb_printf(b, "%*s: %s\n", w, "type", fractal_type[ms->type].name);
+    eb_printf(b, "%*s: %s\n", w, "formula", fractal_type[ms->type].formula);
     eb_printf(b, "%*s: "MFT"\n", w, "x", ms->x);
     eb_printf(b, "%*s: "MFT"\n", w, "y", ms->y);
     eb_printf(b, "%*s: %d\n", w, "maxiter", ms->maxiter);
@@ -610,6 +748,8 @@
           "fractal-module-less", do_fractal_module, ESi, -1, "v")
     CMD3( '>', KEY_NONE,
           "fractal-module-more", do_fractal_module, ESi, +1, "v")
+    CMD2( '1', '2',
+          "fractal-set-type", do_fractal_set_type, ESi, "ki")
     CMD2( '=', KEY_NONE,
           "fractal-set-parameters", do_fractal_set_parameters, ESs,
           "s{Fractal parameters: }[mparm]|mparm|")
@@ -640,8 +780,17 @@
     return 0;
 }
 
+static void fractal_mode_free(EditBuffer *b, void *state) {
+#if 0
+    FractalState *ms = state;
+
+    /* XXX: free bitmap and palette */
+#endif
+}
+
 static void do_mandelbrot_test(EditState *s) {
     EditBuffer *b;
+    const char *p;
 
     if (!fractal_mode.name) {
         /* populate and register shell mode and commands */
@@ -651,10 +800,14 @@
         fractal_mode.mode_probe = fractal_mode_probe;
         fractal_mode.buffer_instance_size = sizeof(FractalState);
         fractal_mode.mode_init = fractal_mode_init;
+        fractal_mode.mode_free = fractal_mode_free;
         fractal_mode.display_hook = fractal_display_hook;
         fractal_mode.default_wrap = WRAP_TRUNCATE;
         qe_register_mode(&fractal_mode, MODEF_NOCMD | MODEF_VIEW);
         qe_register_cmd_table(fractal_commands, &fractal_mode);
+        for (p = "2345678"; *p; p++) {
+            qe_register_binding(*p, "fractal-set-type", &fractal_mode);
+        }
     }
 
     b = eb_find("*Mandelbrot*");



reply via email to

[Prev in Thread] Current Thread [Next in Thread]