[gegl] operations: fix wave to actually originate from a point



commit 55c281386e21091beccd3c67ad6d70902acc1d24
Author: Michael Natterer <mitch gimp org>
Date:   Sat Jun 1 15:48:16 2013 +0200

    operations: fix wave to actually originate from a point
    
    also add an aspect ratio property.

 operations/common/waves.c |  154 +++++++++++++++++++++++++--------------------
 1 files changed, 86 insertions(+), 68 deletions(-)
---
diff --git a/operations/common/waves.c b/operations/common/waves.c
index d9cd691..1824510 100644
--- a/operations/common/waves.c
+++ b/operations/common/waves.c
@@ -14,7 +14,7 @@
  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
  *
  * Copyright 2011 Audrey Mandet <mandet audrey gmail com>
- * Copyright (c) 1997 Eric L. Hernes (erich rrnet com)
+ * Copyright (c) 1997 Eric L. Hernes (erich rrnet com), Stephen Norris
  */
 
 #include "config.h"
@@ -23,53 +23,61 @@
 
 #ifdef GEGL_CHANT_PROPERTIES
 
-gegl_chant_double_ui (x, _("X"), -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, 0.0, 1024.0, 1.0,
-                   _("X coordinate of the center of the waves"))
+gegl_chant_double_ui (x, _("X"),
+                      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, 0.0, 1024.0, 1.0,
+                      _("X coordinate of the center of the waves"))
 
-gegl_chant_double_ui (y, _("Y"), -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, 0.0, 1024.0, 1.0,
-                   _("Coordinate y of the center of the waves"))
+gegl_chant_double_ui (y, _("Y"),
+                      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, 0.0, 1024.0, 1.0,
+                      _("Y coordinate of the center of the waves"))
 
-gegl_chant_double (amplitude, _("Amplitude"), 0.0, 1000.0, 25.0,
-                   _("Amplitude of the ripple"))
+gegl_chant_double    (amplitude, _("Amplitude"),
+                      0.0, 1000.0, 25.0,
+                      _("Amplitude of the ripple"))
 
-gegl_chant_double (period, _("Period"), 0.0, 1000.0, 200.0,
-                   _("Period of the ripple"))
+gegl_chant_double    (period, _("Period"),
+                      0.0, 1000.0, 200.0,
+                      _("Period (wavelength) of the ripple"))
 
-gegl_chant_double (phi, _("Phase shift"), -1.0, 1.0, 0.0,
-                   _("Phase shift"))
+gegl_chant_double    (phi, _("Phase shift"),
+                      -1.0, 1.0, 0.0,
+                      _("Phase shift"))
 
-gegl_chant_enum (sampler_type, _("Sampler"), GeglSamplerType, gegl_sampler_type,
-                 GEGL_SAMPLER_CUBIC, _("Sampler used internally"))
+gegl_chant_double    (aspect, _("Aspect ratio"),
+                      0.1, 10.0, 1.0,
+                      _("Aspect ratio"))
 
-gegl_chant_boolean (clamp, _("Clamp deformation"), FALSE,
-                    _("Limit deformation in the image area."))
+gegl_chant_enum      (sampler_type, _("Sampler"),
+                      GeglSamplerType, gegl_sampler_type,
+                      GEGL_SAMPLER_CUBIC,
+                      _("Sampler used internally"))
+
+gegl_chant_boolean   (clamp, _("Clamp deformation"),
+                      FALSE,
+                      _("Limit deformation in the image area."))
 
 #else
 
 #define GEGL_CHANT_TYPE_AREA_FILTER
-#define GEGL_CHANT_C_FILE       "waves.c"
+#define GEGL_CHANT_C_FILE "waves.c"
 
 #include "gegl-chant.h"
 #include <stdio.h>
 #include <math.h>
 
-static void prepare (GeglOperation *operation)
+static void
+prepare (GeglOperation *operation)
 {
-  GeglChantO              *o;
-  GeglOperationAreaFilter *op_area;
-
-  op_area = GEGL_OPERATION_AREA_FILTER (operation);
-  o       = GEGL_CHANT_PROPERTIES (operation);
+  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
+  GeglChantO              *o       = GEGL_CHANT_PROPERTIES (operation);
 
   op_area->left   = o->amplitude;
   op_area->right  = o->amplitude;
   op_area->top    = o->amplitude;
   op_area->bottom = o->amplitude;
 
-  gegl_operation_set_format (operation, "input",
-                             babl_format ("RGBA float"));
-  gegl_operation_set_format (operation, "output",
-                             babl_format ("RGBA float"));
+  gegl_operation_set_format (operation, "input",  babl_format ("RGBA float"));
+  gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
 }
 
 static gboolean
@@ -79,54 +87,63 @@ process (GeglOperation       *operation,
          const GeglRectangle *result,
          gint                 level)
 {
-  GeglChantO *o                    = GEGL_CHANT_PROPERTIES (operation);
+  GeglChantO  *o = GEGL_CHANT_PROPERTIES (operation);
+  gint         x = result->x; /* initial x                   */
+  gint         y = result->y; /*           and y coordinates */
 
-  gint x = result->x; /* initial x                   */
-  gint y = result->y; /*           and y coordinates */
+  gfloat      *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof (gfloat));
 
-  gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof(gfloat));
-
-  gfloat *out_pixel = dst_buf;
+  gfloat      *out_pixel = dst_buf;
 
   GeglSampler *sampler = gegl_buffer_sampler_new (input,
                                                   babl_format ("RGBA float"),
                                                   o->sampler_type);
 
-  gint n_pixels = result->width * result->height;
-
+  gint         n_pixels = result->width * result->height;
   GeglAbyssPolicy abyss = o->clamp ? GEGL_ABYSS_CLAMP : GEGL_ABYSS_NONE;
 
+  gdouble scalex;
+  gdouble scaley;
+
+  if (o->aspect > 1.0)
+    {
+      scalex = 1.0;
+      scaley = o->aspect;
+    }
+  else if (o->aspect < 1.0)
+    {
+      scalex = 1.0 / o->aspect;
+      scaley = 1.0;
+    }
+  else
+    {
+      scalex = 1.0;
+      scaley = 1.0;
+    }
+
   while (n_pixels--)
     {
-      gdouble coordsx = 0.0;
-      gdouble coordsy = 0.0;
-      gdouble radius = 0.0;
-      gdouble shift = 0.0;
-      gdouble ux = 0.0; /* unit vector of the radius */
-      gdouble uy = 0.0;
-      gdouble vx = 0.0; /* orthogonal vector of u */
-      gdouble vy = 0.0;
-      gdouble dx = 0.0;
-      gdouble dy = 0.0;
-
-      dx = (gdouble)x-o->x;
-      dy = (gdouble)y-o->y;
-
-      radius = sqrt( dx * dx + dy * dy );
-      shift = o->amplitude * sin(2.0 * G_PI * radius / o->period + 2.0 * G_PI * o->phi);
+      gdouble radius;
+      gdouble shift;
+      gdouble dx;
+      gdouble dy;
+      gdouble ux;
+      gdouble uy;
 
-      ux = dx / radius;
-      uy = dy / radius;
-      vx = -uy;
-      vy = ux;
+      dx = (x - o->x) * scalex;
+      dy = (y - o->y) * scaley;
 
-      coordsx = x + shift * vx;
-      coordsy = y + shift * vy;
+      radius = sqrt (dx * dx + dy * dy);
 
+      shift = o->amplitude * sin (2.0 * G_PI * radius / o->period +
+                                  2.0 * G_PI * o->phi);
+
+      ux = dx / radius;
+      uy = dy / radius;
 
       gegl_sampler_get (sampler,
-                        coordsx,
-                        coordsy,
+                        x + (shift + ux) / scalex,
+                        y + (shift + uy) / scaley,
                         NULL,
                         out_pixel,
                         abyss);
@@ -135,22 +152,23 @@ process (GeglOperation       *operation,
 
       /* update x and y coordinates */
       x++;
-      if (x>=result->x + result->width)
+      if (x >= result->x + result->width)
         {
-          x=result->x;
+          x = result->x;
           y++;
         }
     }
 
-  gegl_buffer_set (output, result, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
-  g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf);
+  gegl_buffer_set (output, result, 0, babl_format ("RGBA float"),
+                   dst_buf, GEGL_AUTO_ROWSTRIDE);
+
+  g_slice_free1 (result->width * result->height * 4 * sizeof (gfloat), dst_buf);
 
   g_object_unref (sampler);
 
-  return  TRUE;
+  return TRUE;
 }
 
-
 static void
 gegl_chant_class_init (GeglChantClass *klass)
 {
@@ -160,13 +178,13 @@ gegl_chant_class_init (GeglChantClass *klass)
   operation_class = GEGL_OPERATION_CLASS (klass);
   filter_class    = GEGL_OPERATION_FILTER_CLASS (klass);
 
-  filter_class->process    = process;
   operation_class->prepare = prepare;
+  filter_class->process    = process;
 
   gegl_operation_class_set_keys (operation_class,
-    "name"       , "gegl:waves",
-    "categories" , "distort",
-    "description", _("Transform the buffer with waves"),
+    "name",        "gegl:waves",
+    "categories",  "distort",
+    "description", _("Distort the image with waves"),
     NULL);
 }
 


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