geometrictransform: make ciclegt "radius" property relative
authorFilippo Argiolas <filippo.argiolas@gmail.com>
Tue, 3 Aug 2010 08:08:34 +0000 (10:08 +0200)
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>
Wed, 4 Aug 2010 23:09:09 +0000 (20:09 -0300)
Make the "radius" property of CircleGeometricTransform relative.
This is more coherent with the way [x,y]-center properties are handled
and allow to set a radius without knowing the video size.
Radius is defined with respect to the circle circumscribed about the
video rectangle so that a point in the center has radius 0.0 and one in
a vertex has radius 1.0.
Note that this is not a regression from the previous absolute way of
defining the radius as a user who knows the video size can easily
calculate the relative radius and set that.

https://bugzilla.gnome.org/show_bug.cgi?id=625959

gst/geometrictransform/gstcircle.c
gst/geometrictransform/gstcirclegeometrictransform.c
gst/geometrictransform/gstcirclegeometrictransform.h
gst/geometrictransform/gstkaleidoscope.c
gst/geometrictransform/gsttwirl.c
gst/geometrictransform/gstwaterripple.c

index fe6a99e..7cfe67c 100644 (file)
@@ -183,7 +183,8 @@ circle_map (GstGeometricTransform * gt, gint x, gint y, gdouble * in_x,
 
   *in_x = gt->width * theta / (circle->spread_angle + 0.0001);
   *in_y =
-      gt->height * (1 - (distance - cgt->radius) / (circle->height + 0.0001));
+      gt->height * (1 - (distance - cgt->precalc_radius) / (circle->height +
+          0.0001));
 
   GST_DEBUG_OBJECT (circle, "Inversely mapped %d %d into %lf %lf",
       x, y, *in_x, *in_y);
index 7f8cf2e..19e0dde 100644 (file)
@@ -72,7 +72,7 @@ enum
 
 #define DEFAULT_X_CENTER 0.5
 #define DEFAULT_Y_CENTER 0.5
-#define DEFAULT_RADIUS 100
+#define DEFAULT_RADIUS 0.35
 
 static void
 gst_circle_geometric_transform_set_property (GObject * object, guint prop_id,
@@ -155,7 +155,10 @@ circle_geometric_transform_precalc (GstGeometricTransform * gt)
 
   cgt->precalc_x_center = cgt->x_center * gt->width;
   cgt->precalc_y_center = cgt->y_center * gt->height;
-  cgt->precalc_radius2 = cgt->radius * cgt->radius;
+  cgt->precalc_radius =
+      cgt->radius * 0.5 * sqrt (gt->width * gt->width +
+      gt->height * gt->height);
+  cgt->precalc_radius2 = cgt->precalc_radius * cgt->precalc_radius;
 
   return TRUE;
 }
@@ -195,7 +198,7 @@ gst_circle_geometric_transform_class_init (GstCircleGeometricTransformClass *
           GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_RADIUS,
       g_param_spec_double ("radius", "radius",
-          "radius of the circle_geometric_transform effect", 0.0, G_MAXDOUBLE,
+          "radius of the circle_geometric_transform effect", 0.0, 1.0,
           DEFAULT_RADIUS,
           GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
index a9539ad..b8b484a 100644 (file)
@@ -76,6 +76,7 @@ struct _GstCircleGeometricTransform
 
   gdouble precalc_x_center;
   gdouble precalc_y_center;
+  gdouble precalc_radius;
   gdouble precalc_radius2;
 };
 
index ecc3690..384037b 100644 (file)
@@ -180,8 +180,8 @@ kaleidoscope_map (GstGeometricTransform * gt, gint x, gint y, gdouble * in_x,
 
   theta = geometric_math_triangle (theta / G_PI * kaleidoscope->sides * 0.5);
 
-  if (cgt->radius != 0) {
-    gdouble radiusc = cgt->radius / cos (theta);
+  if (cgt->precalc_radius != 0) {
+    gdouble radiusc = cgt->precalc_radius / cos (theta);
 
     distance = radiusc * geometric_math_triangle (distance / radiusc);
   }
index 51302d4..8d31d8e 100644 (file)
@@ -155,7 +155,8 @@ twirl_map (GstGeometricTransform * gt, gint x, gint y, gdouble * in_x,
     *in_y = y;
   } else {
     gdouble d = sqrt (distance);
-    gdouble a = atan2 (dy, dx) + twirl->angle * (cgt->radius - d) / cgt->radius;
+    gdouble a = atan2 (dy,
+        dx) + twirl->angle * (cgt->precalc_radius - d) / cgt->precalc_radius;
 
     *in_x = cgt->precalc_x_center + d * cos (a);
     *in_y = cgt->precalc_y_center + d * sin (a);
index d66d983..7e911df 100644 (file)
@@ -183,7 +183,7 @@ water_ripple_map (GstGeometricTransform * gt, gint x, gint y, gdouble * in_x,
         water->amplitude * sin (d / water->wavelength * G_PI * 2 -
         water->phase);
 
-    amount *= (cgt->radius - d) / cgt->radius;
+    amount *= (cgt->precalc_radius - d) / cgt->precalc_radius;
     if (d != 0)
       amount *= water->wavelength / d;
     *in_x = x + dx * amount;