From 884cc0f5cf5dbe36351288ce5fe5bbec1ada34a7 Mon Sep 17 00:00:00 2001 From: Tomas Frydrych Date: Tue, 16 Jan 2007 08:14:53 +0000 Subject: [PATCH] added ClutterAngle type and fast clutter_angle_sin() function; fixed clutter_fixed to work for negative angles; added convenience macros clutter_fixex_cos and clutter_angle_cos --- ChangeLog | 14 ++++++++ clutter/clutter-alpha.c | 48 +++++++++++++++++++++++++-- clutter/clutter-fixed.c | 72 +++++++++++++++++++++++++++++++++++++++-- clutter/clutter-fixed.h | 6 ++++ 4 files changed, 135 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 312db8bea..b102ea61f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2007-01-16 Tomas Frydrych + + * clutter/clutter-fixed.h: + Added integer ClutterAngle type, protype of clutter_angle_sin and + convenience macros clutter_fixed_cos and clutter_angle_cos + * clutter/clutter-fixed.c: + (clutter_fixed_sin): + Fixed to work for negative angles. + (clutter_angle_sin): + Fast fixed point sin function for ClutterAngle angles. + * clutter/clutter-alpha.c: + (clutter_sin_func, clutter_sin_inc_func): + Changed to use clutter_angle_sin function. + 2007-01-15 Tomas Frydrych * clutter/clutter-fixed.h: (CLUTTER_FIXED_TO_DOUBLE/FLOAT): diff --git a/clutter/clutter-alpha.c b/clutter/clutter-alpha.c index fe0e4f691..c5f715f96 100644 --- a/clutter/clutter-alpha.c +++ b/clutter/clutter-alpha.c @@ -491,6 +491,40 @@ clutter_ramp_func (ClutterAlpha *alpha, } } +static guint32 +sincx1024_func (ClutterAlpha *alpha, + ClutterAngle angle, + ClutterFixed offset) +{ + ClutterTimeline *timeline; + gint current_frame_num, n_frames; + ClutterAngle x; + ClutterFixed sine; + + timeline = clutter_alpha_get_timeline (alpha); + + current_frame_num = clutter_timeline_get_current_frame (timeline); + n_frames = clutter_timeline_get_n_frames (timeline); + + x = angle * current_frame_num / n_frames; + + /* + * x = x*PI - PI/angle + */ + x = (x << 9) - (512 / angle); + + sine = (clutter_angle_sin (x) + offset)/2; + + CLUTTER_NOTE (ALPHA, "sine: %2f\n", CLUTTER_FIXED_TO_DOUBLE (sine)); + + return CLUTTER_FIXED_INT (sine * CLUTTER_ALPHA_MAX_ALPHA); +} + +#if 0 +/* + * The following two functions are left in place for reference + * purposes. + */ static guint32 sincx_func (ClutterAlpha *alpha, ClutterFixed angle, @@ -538,7 +572,7 @@ sinc_func (ClutterAlpha *alpha, return (guint32) (sine * (gdouble) CLUTTER_ALPHA_MAX_ALPHA); } - +#endif /** * clutter_sine_func: * @alpha: a #ClutterAlpha @@ -558,7 +592,11 @@ clutter_sine_func (ClutterAlpha *alpha, #if 0 return sinc_func (alpha, 2.0, 1.0); #else - return sincx_func (alpha, CLUTTER_INT_TO_FIXED (2), CFX_ONE); + /* Conversion to ClutterAngle: + * + * 2.0 rad -> 1024*2.0/(2*PI) = 325.949 + */ + return sincx1024_func (alpha, 326, CFX_ONE); #endif } @@ -581,6 +619,10 @@ clutter_sine_inc_func (ClutterAlpha *alpha, #if 0 return sinc_func (alpha, 0.5, 1.0); #else - return sincx_func (alpha, CFX_ONE / 2, CFX_ONE); + /* Conversion to ClutterAngle: + * + * 0.5 rad -> 1024*0.5/(2*PI) = 81.487 + */ + return sincx1024_func (alpha, 81, CFX_ONE); #endif } diff --git a/clutter/clutter-fixed.c b/clutter/clutter-fixed.c index 8c09ffce7..a59fe285f 100644 --- a/clutter/clutter-fixed.c +++ b/clutter/clutter-fixed.c @@ -86,7 +86,7 @@ static ClutterFixed sin_tbl [] = /** * clutter_fixed_sin: - * @angle: a #ClutterAlpha + * @angle: a #ClutterFixed angle in radians * * Fixed point implementation of sine function * Return value: sine value (as fixed point). @@ -98,6 +98,13 @@ clutter_fixed_sin (ClutterFixed angle) { int sign = 1, indx1, indx2; ClutterFixed low, high, d1, d2; + + /* convert negative angle to positive + sign */ + if ((int)angle < 0) + { + sign = 1 + ~sign; + angle = 1 + ~angle; + } /* reduce to <0, 2*pi) */ if (angle >= CFX_2PI) @@ -109,7 +116,7 @@ clutter_fixed_sin (ClutterFixed angle) /* reduce to first quadrant and sign */ if (angle > CFX_PI) { - sign = -1; + sign = 1 + ~sign; if (angle > CFX_PI + CFX_PI_2) { /* fourth qudrant */ @@ -163,3 +170,64 @@ clutter_fixed_sin (ClutterFixed angle) return angle; } + +/** + * clutter_angle_sin: + * @angle: a #ClutterAngle + * + * Fast fixed point implementation of sine function. + * + * ClutterAngle is an integer such that that 1024 represents + * full circle. + * + * Return value: sine value (as fixed point). + * + * Since: 0.2 + */ +ClutterFixed +clutter_angle_sin (ClutterAngle angle) +{ + int sign = 1; + ClutterFixed result; + + /* reduce negative angle to positive + sign */ + if (angle < 0) + { + sign = 1 + ~sign; + angle = 1 + ~angle; + } + + /* reduce to <0, 2*pi) */ + angle &= 0x7ff; + + /* reduce to first quadrant and sign */ + if (angle > 512) + { + sign = 1 + ~sign; + if (angle > 768) + { + /* fourth qudrant */ + angle = 1024 - angle; + } + else + { + /* third quadrant */ + angle -= 512; + } + } + else + { + if (angle > 256) + { + /* second quadrant */ + angle = 512 - angle; + } + } + + result = sin_tbl[angle]; + + if (sign < 0) + result = (1 + ~result); + + return result; +} diff --git a/clutter/clutter-fixed.h b/clutter/clutter-fixed.h index 3d82cbe0a..91e7aebd5 100644 --- a/clutter/clutter-fixed.h +++ b/clutter/clutter-fixed.h @@ -31,6 +31,7 @@ G_BEGIN_DECLS typedef gint32 ClutterFixed; +typedef gint32 ClutterAngle; /* angle such that 1024 == 2*PI */ #define CFX_Q 16 /* Decimal part size in bits */ #define CFX_ONE (1 << CFX_Q) /* 1 */ @@ -69,6 +70,11 @@ typedef gint32 ClutterFixed; /* Fixed point math routines */ ClutterFixed clutter_fixed_sin (ClutterFixed anx); +ClutterFixed clutter_angle_sin (ClutterAngle angle); + +/* convenience macros for the cos functions */ +#define clutter_fixed_cos(x) clutter_fixed_sin((x) - CFX_PI_2) +#define clutter_angle_cos(x) clutter_fixed_sin((x) - 256) G_END_DECLS