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

This commit is contained in:
Tomas Frydrych 2007-01-16 08:14:53 +00:00
parent 44a89898ca
commit 884cc0f5cf
4 changed files with 135 additions and 5 deletions

View File

@ -1,3 +1,17 @@
2007-01-16 Tomas Frydrych <tf@openedhand.com>
* 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 <tf@openedhand.com> 2007-01-15 Tomas Frydrych <tf@openedhand.com>
* clutter/clutter-fixed.h: (CLUTTER_FIXED_TO_DOUBLE/FLOAT): * clutter/clutter-fixed.h: (CLUTTER_FIXED_TO_DOUBLE/FLOAT):

View File

@ -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 static guint32
sincx_func (ClutterAlpha *alpha, sincx_func (ClutterAlpha *alpha,
ClutterFixed angle, ClutterFixed angle,
@ -538,7 +572,7 @@ sinc_func (ClutterAlpha *alpha,
return (guint32) (sine * (gdouble) CLUTTER_ALPHA_MAX_ALPHA); return (guint32) (sine * (gdouble) CLUTTER_ALPHA_MAX_ALPHA);
} }
#endif
/** /**
* clutter_sine_func: * clutter_sine_func:
* @alpha: a #ClutterAlpha * @alpha: a #ClutterAlpha
@ -558,7 +592,11 @@ clutter_sine_func (ClutterAlpha *alpha,
#if 0 #if 0
return sinc_func (alpha, 2.0, 1.0); return sinc_func (alpha, 2.0, 1.0);
#else #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 #endif
} }
@ -581,6 +619,10 @@ clutter_sine_inc_func (ClutterAlpha *alpha,
#if 0 #if 0
return sinc_func (alpha, 0.5, 1.0); return sinc_func (alpha, 0.5, 1.0);
#else #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 #endif
} }

View File

@ -86,7 +86,7 @@ static ClutterFixed sin_tbl [] =
/** /**
* clutter_fixed_sin: * clutter_fixed_sin:
* @angle: a #ClutterAlpha * @angle: a #ClutterFixed angle in radians
* *
* Fixed point implementation of sine function * Fixed point implementation of sine function
* Return value: sine value (as fixed point). * Return value: sine value (as fixed point).
@ -99,6 +99,13 @@ clutter_fixed_sin (ClutterFixed angle)
int sign = 1, indx1, indx2; int sign = 1, indx1, indx2;
ClutterFixed low, high, d1, d2; 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) */ /* reduce to <0, 2*pi) */
if (angle >= CFX_2PI) if (angle >= CFX_2PI)
{ {
@ -109,7 +116,7 @@ clutter_fixed_sin (ClutterFixed angle)
/* reduce to first quadrant and sign */ /* reduce to first quadrant and sign */
if (angle > CFX_PI) if (angle > CFX_PI)
{ {
sign = -1; sign = 1 + ~sign;
if (angle > CFX_PI + CFX_PI_2) if (angle > CFX_PI + CFX_PI_2)
{ {
/* fourth qudrant */ /* fourth qudrant */
@ -163,3 +170,64 @@ clutter_fixed_sin (ClutterFixed angle)
return 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;
}

View File

@ -31,6 +31,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef gint32 ClutterFixed; typedef gint32 ClutterFixed;
typedef gint32 ClutterAngle; /* angle such that 1024 == 2*PI */
#define CFX_Q 16 /* Decimal part size in bits */ #define CFX_Q 16 /* Decimal part size in bits */
#define CFX_ONE (1 << CFX_Q) /* 1 */ #define CFX_ONE (1 << CFX_Q) /* 1 */
@ -69,6 +70,11 @@ typedef gint32 ClutterFixed;
/* Fixed point math routines */ /* Fixed point math routines */
ClutterFixed clutter_fixed_sin (ClutterFixed anx); 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 G_END_DECLS