[gegl/soc-2011-ops] Added improved fractal trace (can use Julia and Mandelbrot fractals)



commit 89b7ee14d22da258a123636e7745a4c57aeb4eeb
Author: Robert Sasu <sasu robert gmail com>
Date:   Mon Jun 20 21:41:26 2011 +0300

    Added improved fractal trace (can use Julia and Mandelbrot fractals)

 operations/workshop/fractal-trace.c |  110 +++++++++++++++++++++++++----------
 1 files changed, 78 insertions(+), 32 deletions(-)
---
diff --git a/operations/workshop/fractal-trace.c b/operations/workshop/fractal-trace.c
index b698633..65f25c6 100644
--- a/operations/workshop/fractal-trace.c
+++ b/operations/workshop/fractal-trace.c
@@ -16,7 +16,7 @@
  * Copyright 2011 Robert Sasu <sasu robert gmail com>
  *
  * Based on "Fractal-trace" GIMP plugin
- *   Copyright (C) 1997  Hirotsuna Mizuno
+ * Copyright (C) 1997  Hirotsuna Mizuno
  *                     s1041150 u-aizu ac jp
  */
 
@@ -26,6 +26,9 @@
 
 #ifdef GEGL_CHANT_PROPERTIES
 
+gegl_chant_string (fractal, _("Fractal"), "fractal",
+                   _("Type of fractal to use. "
+                     "Choices are julia, mandelbrot. Default is mandelbrot."))
 gegl_chant_double (X1, _("X1"), -50.0, 50.0, -1.00,
                   _("X1 value, position"))
 gegl_chant_double (X2, _("X2"), -50.0, 50.0, 0.50,
@@ -34,6 +37,10 @@ gegl_chant_double (Y1, _("Y1"), -50.0, 50.0, -1.00,
                   _("X2 value, position"))
 gegl_chant_double (Y2, _("Y2"), -50.0, 50.0, 1.00,
                   _("Y2 value, position"))
+gegl_chant_double (JX, _("JX"), -50.0, 50.0, 0.5,
+                   _("Julia seed X value, position"))
+gegl_chant_double (JY, _("JY"), -50.0, 50.0, 0.5,
+                   _("Julia seed Y value, position"))
 gegl_chant_int    (depth, _("Depth"), 1, 50, 3,
                   _("Depth value"))
 gegl_chant_string (background, _("Background"), "wrap",
@@ -50,12 +57,18 @@ gegl_chant_string (background, _("Background"), "wrap",
 #include <math.h>
 #include <stdio.h>
 
-enum
+enum OutsideType
 {
   OUTSIDE_TYPE_WRAP,
   OUTSIDE_TYPE_TRANSPARENT,
   OUTSIDE_TYPE_BLACK,
-  OUTSIDE_TYPE_WHITE, 
+  OUTSIDE_TYPE_WHITE 
+};
+
+enum FractalType
+{
+  FRACTAL_TYPE_MANDEL,
+  FRACTAL_TYPE_JULIA
 };
 
 
@@ -66,31 +79,37 @@ static void prepare (GeglOperation *operation)
 }   
 
 static void
-mandelbrot (gdouble  x,
-            gdouble  y,
-            gdouble *u,
-            gdouble *v,
-            gint     depth)
+julia (gdouble  x,
+       gdouble  y,
+       gdouble  jx,
+       gdouble  jy,
+       gdouble *u,
+       gdouble *v,
+       gint     depth,
+       gdouble  escape_radius)
 {
   gint    i;
   gdouble xx = x;
   gdouble yy = y;
 
   for (i = 0; i < depth; i++)
-      {
-        gdouble x2, y2, tmp;
- 
-        x2 = xx * xx;
-        y2 = yy * yy;
-        tmp = x2 - y2 + x;
-        yy  = 2 * xx * yy + y;
-        xx  = tmp;
-      }
+    {
+      gdouble x2, y2, tmp;
+
+      x2 = xx * xx;
+      y2 = yy * yy;
+      tmp = x2 - y2 + jx;
+      yy  = 2 * xx * yy + jy;
+      xx  = tmp;
+      /*commented this line because it is bugy */
+      /*if (x2 + y2 > (pow(escape_radius,2))) break;*/
+    }
 
   *u = xx;
   *v = yy;
 }
 
+
 static void
 fractaltrace (GeglBuffer          *input,
               const GeglRectangle *picture,
@@ -98,7 +117,8 @@ fractaltrace (GeglBuffer          *input,
               const GeglRectangle *roi,
               GeglChantO          *o,
               gint                 y,
-              gint                 id,
+              enum FractalType     fractal,
+              enum OutsideType     id,
               Babl                *format
               )
 {
@@ -107,6 +127,7 @@ fractaltrace (GeglBuffer          *input,
   gdouble        cx, cy;
   gdouble        px, py;
   gfloat         dest[4];
+  gdouble        escape_radius = sqrt(pow(o->X2 - o->X1,2) + pow(o->Y2 - o->Y1,2));
 
   scale_x = (gdouble) (o->X2 - o->X1) / (gdouble) picture->width;
   scale_y = (gdouble) (o->Y2 - o->Y1) / (gdouble) picture->height;
@@ -118,7 +139,19 @@ fractaltrace (GeglBuffer          *input,
     {
        dest[1] = dest[2] = dest[3] = dest[0] = 0.0;
        cx = o->X1 + (x - picture->x) * scale_x;
-       mandelbrot (cx, cy, &px, &py, o->depth);
+
+       switch (fractal)
+	{
+        case FRACTAL_TYPE_JULIA:
+          julia (cx, cy, o->JX, o->JY, &px, &py, o->depth, escape_radius);
+          break;
+        case FRACTAL_TYPE_MANDEL:
+          julia (cx, cy, cx, cy, &px, &py, o->depth, escape_radius);
+          break;
+        default:
+          g_error (_("Unsupported fractal type"));
+        }
+
        px = (px - o->X1) / scale_x + picture->x;
        py = (py - o->Y1) / scale_y + picture->y;
 
@@ -131,7 +164,7 @@ fractaltrace (GeglBuffer          *input,
          {
            switch (id)
              {
-             case 0:
+             case OUTSIDE_TYPE_WRAP:
                px = fmod (px, picture->width);
                py = fmod (py, picture->height);
                if (px < 0.0) px += picture->width;
@@ -165,14 +198,14 @@ fractaltrace (GeglBuffer          *input,
                gegl_buffer_sample (input, px, py, 1.0, dest, format, 
                                   GEGL_INTERPOLATION_LINEAR);
                break;
-             case 1:
+             case OUTSIDE_TYPE_TRANSPARENT:
                dest[0] = dest[1] = dest[2] = dest[3] = 0.0;
                break;
-             case 2:
+             case OUTSIDE_TYPE_BLACK:
                dest[0] = dest[1] = dest[2] = 0.0;
                dest[3] = 1.0;
                break;
-             case 3:
+             case OUTSIDE_TYPE_WHITE:
                dest[0] = dest[1] = dest[2] = dest[3] = 1.0;
                break;
              }
@@ -193,20 +226,33 @@ process (GeglOperation       *operation,
   GeglChantO    *o            = GEGL_CHANT_PROPERTIES (operation);
   GeglRectangle  boundary     = gegl_operation_get_bounding_box (operation); 
   Babl          *format       = babl_format ("RGBA float");
-  
-  gint y,id;
-  gfloat        *dst_buf;
 
-  id = 0; /*wrap is default*/
-  if (!strcmp(o->background,"wrap"))             id = 0;
-  else if (!strcmp(o->background,"transparent")) id = 1;
-  else if (!strcmp(o->background,"black"))       id = 2;
-  else if (!strcmp(o->background,"white"))       id = 3;
+  enum FractalType  frT;
+  enum OutsideType  id;
+  gfloat           *dst_buf;
+  gint              y;
+
+  frT = FRACTAL_TYPE_MANDEL;
+  if (!strcmp (o->fractal, "mandel"))
+    frT = FRACTAL_TYPE_MANDEL;
+  else if (!strcmp(o->fractal, "julia"))
+    frT = FRACTAL_TYPE_JULIA;
+
+
+  id = OUTSIDE_TYPE_WRAP; /*wrap is default*/
+  if (!strcmp(o->background,"wrap"))
+      id = OUTSIDE_TYPE_WRAP;
+  else if (!strcmp(o->background,"transparent")) 
+      id = OUTSIDE_TYPE_TRANSPARENT;
+  else if (!strcmp(o->background,"black"))       
+      id = OUTSIDE_TYPE_BLACK;
+  else if (!strcmp(o->background,"white"))
+      id = OUTSIDE_TYPE_WHITE;
 
   dst_buf = g_new0 (gfloat, result->width * result->height * 4);
 
   for (y = result->y; y < result->y + result->height; y++)
-	fractaltrace(input, &boundary, dst_buf, result, o, y, id, format);
+	fractaltrace(input, &boundary, dst_buf, result, o, y, frT, id, format);
 
   gegl_buffer_set (output, result, format, dst_buf, GEGL_AUTO_ROWSTRIDE);
 



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