[base] Reduce trigonometric algorithms.

After we get within 45 degrees by means of true 90-degree rotations,
we can remove initial 45-degree CORDIC iteration and start from
atan(1/2) pseudorotation, reducing expansion factor thereby.

* src/base/fttrigon.c (FT_TRIG_SCALE, FT_TRIG_COSCALE): Update macros.
(ft_trig_pseudo_rotate, ft_trig_pseudo_polarize): Update.

* src/tools/cordic.py: Bring up to date with trigonometric core.

* docs/CHANGES: Old typo.
This commit is contained in:
Alexei Podtelezhnikov 2013-01-02 22:21:37 -05:00
parent 50e634abe1
commit b4ac30b0ed
4 changed files with 68 additions and 31 deletions

View File

@ -1,4 +1,19 @@
2012-12-21 Alexei Podtelezhnikov <apodtele@gmail.com> 2013-01-02 Alexei Podtelezhnikov <apodtele@gmail.com>
[base] Reduce trigonometric algorithms.
After we get within 45 degrees by means of true 90-degree rotations,
we can remove initial 45-degree CORDIC iteration and start from
atan(1/2) pseudorotation, reducing expansion factor thereby.
* src/base/fttrigon.c (FT_TRIG_SCALE, FT_TRIG_COSCALE): Update macros.
(ft_trig_pseudo_rotate, ft_trig_pseudo_polarize): Update.
* src/tools/cordic.py: Bring up to date with trigonometric core.
* docs/CHANGES: Old typo.
2013-01-02 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/pshinter/pshalgo.h: Remove unused code. * src/pshinter/pshalgo.h: Remove unused code.

View File

@ -2486,7 +2486,7 @@ CHANGES BETWEEN 2.0.3 and 2.0.2
number. see <freetype/fterrors.h> for details. number. see <freetype/fterrors.h> for details.
- A new public header file has been introduced, named - A new public header file has been introduced, named
FT_TRIGONOMETRY_H (include/freetype/fttrig.h), providing FT_TRIGONOMETRY_H (include/freetype/fttrigon.h), providing
trigonometric functions to compute sines, cosines, arctangents, trigonometric functions to compute sines, cosines, arctangents,
etc. with 16.16 fixed precision. The implementation is based on etc. with 16.16 fixed precision. The implementation is based on
the CORDIC algorithm and is very fast while being sufficiently the CORDIC algorithm and is very fast while being sufficiently

View File

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType trigonometric functions (body). */ /* FreeType trigonometric functions (body). */
/* */ /* */
/* Copyright 2001-2005, 2012 by */ /* Copyright 2001-2005, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -26,20 +26,20 @@
#endif #endif
/* the Cordic shrink factor 0.607252935008887 * 2^32 */ /* the Cordic shrink factor 0.858785336480436 * 2^32 */
#define FT_TRIG_SCALE 0x9B74EDA8UL #define FT_TRIG_SCALE 0xDBD95B16UL
/* the following is 0.607252935008887 * 2^30 */ /* the following is 0.858785336480436 * 2^30 */
#define FT_TRIG_COSCALE 0x26DD3B6AUL #define FT_TRIG_COSCALE 0x36F656C6UL
/* this table was generated for FT_PI = 180L << 16, i.e. degrees */ /* this table was generated for FT_PI = 180L << 16, i.e. degrees */
#define FT_TRIG_MAX_ITERS 23 #define FT_TRIG_MAX_ITERS 23
static const FT_Fixed static const FT_Fixed
ft_trig_arctan_table[23] = ft_trig_arctan_table[] =
{ {
2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L,
29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
57L, 29L, 14L, 7L, 4L, 2L, 1L 57L, 29L, 14L, 7L, 4L, 2L, 1L
}; };
@ -199,25 +199,27 @@
x = vec->x; x = vec->x;
y = vec->y; y = vec->y;
/* Get angle between -90 and 90 degrees */ /* Rotate inside [-PI/4,PI/4] sector */
while ( theta <= -FT_ANGLE_PI2 ) while ( theta < -FT_ANGLE_PI4 )
{ {
x = -x; xtemp = y;
y = -y; y = -x;
theta += FT_ANGLE_PI; x = xtemp;
theta += FT_ANGLE_PI2;
} }
while ( theta > FT_ANGLE_PI2 ) while ( theta > FT_ANGLE_PI4 )
{ {
x = -x; xtemp = -y;
y = -y; y = x;
theta -= FT_ANGLE_PI; x = xtemp;
theta -= FT_ANGLE_PI2;
} }
arctanptr = ft_trig_arctan_table; arctanptr = ft_trig_arctan_table;
/* Pseudorotations, with right shifts */ /* Pseudorotations, with right shifts */
i = 0; i = 1;
do do
{ {
if ( theta < 0 ) if ( theta < 0 )
@ -253,22 +255,42 @@
x = vec->x; x = vec->x;
y = vec->y; y = vec->y;
/* Get the vector into the right half plane */ /* Get the vector into [-PI/4,PI/4] sector */
theta = 0; if ( y > x )
if ( x < 0 )
{ {
x = -x; if ( y > -x )
y = -y; {
theta = 2 * FT_ANGLE_PI2; theta = FT_ANGLE_PI2;
xtemp = y;
y = -x;
x = xtemp;
}
else
{
theta = y > 0 ? FT_ANGLE_PI : -FT_ANGLE_PI;
x = -x;
y = -y;
}
}
else
{
if ( y < -x )
{
theta = -FT_ANGLE_PI2;
xtemp = -y;
y = x;
x = xtemp;
}
else
{
theta = 0;
}
} }
if ( y > 0 )
theta = - theta;
arctanptr = ft_trig_arctan_table; arctanptr = ft_trig_arctan_table;
/* Pseudorotations, with right shifts */ /* Pseudorotations, with right shifts */
i = 0; i = 1;
do do
{ {
if ( y > 0 ) if ( y > 0 )

View File

@ -10,7 +10,7 @@ comma = ""
print "" print ""
print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units" print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units"
for n in range(0,32): for n in range(1,32):
x = 0.5**n # tangent value x = 0.5**n # tangent value