gegl r2645 - in trunk: . bin
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2645 - in trunk: . bin
- Date: Mon, 20 Oct 2008 09:40:24 +0000 (UTC)
Author: ok
Date: Mon Oct 20 09:40:24 2008
New Revision: 2645
URL: http://svn.gnome.org/viewvc/gegl?rev=2645&view=rev
Log:
* bin/gegl-spiro.c: (gegl_vector_spiro_flatten),
(points_to_bezier_path), (gegl_vector_spiro_flatten2),
(gegl_spiro_init): added a new knot type '*' used for a simpler all
control points on curve path. (should probably be replaced with
catmull-rom interpolation and placed in its own file).
Modified:
trunk/ChangeLog
trunk/bin/gegl-spiro.c
Modified: trunk/bin/gegl-spiro.c
==============================================================================
--- trunk/bin/gegl-spiro.c (original)
+++ trunk/bin/gegl-spiro.c Mon Oct 20 09:40:24 2008
@@ -19,6 +19,7 @@
#include "gegl-spiro.h"
#include <gegl/gegl.h>
#include "gegl-vector.h"
+#include <math.h>
#include <spiroentrypoints.h>
@@ -96,10 +97,9 @@
if (!is_spiro)
{
- return gegl_vector_path_flatten (original);
+ return original;
}
-
points = g_new0 (spiro_cp, count);
for (i=0, iter = original; iter; iter=iter->next, i++)
{
@@ -153,8 +153,138 @@
SpiroCPsToBezier(points,count, FALSE, (void*)&bezcontext);
g_free (points);
- ret = gegl_vector_path_flatten (bezcontext.path);
- /* XXX :free path */
+ return bezcontext.path;
+}
+
+static GeglVectorPath *
+points_to_bezier_path (gdouble coord_x[],
+ gdouble coord_y[],
+ gint n_coords)
+{
+ GeglVectorPath *ret = NULL;
+ gint i;
+ gdouble smooth_value;
+
+ smooth_value = 0.8;
+
+ if (!n_coords)
+ return NULL;
+
+ ret = gegl_vector_path_add1 (ret, 'M', coord_x[0], coord_y[0]);
+
+ for (i=1;i<n_coords;i++)
+ {
+ gdouble x2 = coord_x[i];
+ gdouble y2 = coord_y[i];
+
+ gdouble x0,y0,x1,y1,x3,y3;
+
+ if (i==1)
+ {
+ x0=coord_x[i-1];
+ y0=coord_y[i-1];
+ x1 = coord_x[i-1];
+ y1 = coord_y[i-1];
+ }
+ else
+ {
+ x0=coord_x[i-2];
+ y0=coord_y[i-2];
+ x1 = coord_x[i-1];
+ y1 = coord_y[i-1];
+ }
+
+ if (i+1 < n_coords)
+ {
+ x3 = coord_x[i+1];
+ y3 = coord_y[i+1];
+ }
+ else
+ {
+ x3 = coord_x[i];
+ y3 = coord_y[i];
+ }
+
+ {
+ gdouble xc1 = (x0 + x1) / 2.0;
+ gdouble yc1 = (y0 + y1) / 2.0;
+ gdouble xc2 = (x1 + x2) / 2.0;
+ gdouble yc2 = (y1 + y2) / 2.0;
+ gdouble xc3 = (x2 + x3) / 2.0;
+ gdouble yc3 = (y2 + y3) / 2.0;
+ gdouble len1 = sqrt( (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0) );
+ gdouble len2 = sqrt( (x2-x1) * (x2-x1) + (y2-y1) * (y2-y1) );
+ gdouble len3 = sqrt( (x3-x2) * (x3-x2) + (y3-y2) * (y3-y2) );
+ gdouble k1 = len1 / (len1 + len2);
+ gdouble k2 = len2 / (len2 + len3);
+ gdouble xm1 = xc1 + (xc2 - xc1) * k1;
+ gdouble ym1 = yc1 + (yc2 - yc1) * k1;
+ gdouble xm2 = xc2 + (xc3 - xc2) * k2;
+ gdouble ym2 = yc2 + (yc3 - yc2) * k2;
+ gdouble ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;
+ gdouble ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;
+ gdouble ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;
+ gdouble ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;
+
+ if (i==n_coords-1)
+ {
+ ctrl2_x = x2;
+ ctrl2_y = y2;
+ }
+
+ ret = gegl_vector_path_add3 (ret, 'C', ctrl1_x, ctrl1_y,
+ ctrl2_x, ctrl2_y,
+ x2, y2);
+ }
+ }
+ return ret;
+}
+
+
+static GeglVectorPath *gegl_vector_spiro_flatten2 (GeglVectorPath *original)
+{
+ GeglVectorPath *ret;
+ GeglVectorPath *iter;
+ gdouble *coordsx;
+ gdouble *coordsy;
+ gboolean is_spiro = TRUE;
+ gint count;
+ gint i;
+ /* first we do a run through the path checking it's length
+ * and determining whether we can flatten the incoming path
+ */
+ for (count=0,iter = original; iter; iter=iter->next)
+ {
+ switch (iter->d.type)
+ {
+ case '*':
+ break;
+ default:
+ is_spiro=FALSE;
+ break;
+ }
+ count ++;
+ }
+
+ if (!is_spiro)
+ {
+ return original;
+ }
+
+ coordsx = g_new0 (gdouble, count);
+ coordsy = g_new0 (gdouble, count);
+
+ for (i=0, iter = original; iter; iter=iter->next, i++)
+ {
+ coordsx[i] = iter->d.point[0].x;
+ coordsy[i] = iter->d.point[0].y;
+ }
+
+ ret = points_to_bezier_path (coordsx, coordsy, count);
+
+ g_free (coordsx);
+ g_free (coordsy);
+
return ret;
}
@@ -170,5 +300,8 @@
gegl_vector_add_knot_type ('[', 1, "spiro left");
gegl_vector_add_knot_type (']', 1, "spiro right");
+ gegl_vector_add_knot_type ('*', 1, "path");
+
gegl_vector_add_flattener (gegl_vector_spiro_flatten);
-}
+ gegl_vector_add_flattener (gegl_vector_spiro_flatten2);
+}
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]