[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Devel] [bug?] FT_Vector_Rotate
From: |
David Turner |
Subject: |
Re: [Devel] [bug?] FT_Vector_Rotate |
Date: |
Fri, 16 May 2003 11:44:38 +0200 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.3) Gecko/20030312 |
Hello Joseph,
Joseph Koshy wrote:
The description of 'FT_Vector_Rotate' in the HTML documentation
has a function prototype:
FT_EXPORT( void )
FT_Vector_Rotate( FT_Vector* vec,
FT_Angle angle );
However the description describes 'angle' as:
angle The address of angle.
Either way, I seem to be missing something since I'm not getting the
results that I'm expecting. For example, rotating a vector [x = 1, y = 0]
by 90 degrees does not result in a new vector [x = 0, y = 1].
$ ./a.out
old v1 = [1.0, 0.0]
new v1 = [-1.63, 0.63]
The test program is enclosed. How *does* one use FT_Vector_Rotate?
Well, this is a simple rounding bug in the implementation. Despite what
Graham said, there is *no* need to use 16.16 numbers in this function
(it's simply that the error is smaller with numbers in this scale).
Here's a "fixed" version, I haven't tested it very thoroughly but it
should work well. Note that:
vec->x = ( v.x + half + FT_SIGN_LONG(v.x) ) >> shift;
is equivalent to:
if ( v.x >= 0 )
vec->x = ( v.x + half ) >> shift;
else
vec->x = ( v.x + half - 1 ) >> shift;
but avoids a test and two jumps.
==========================================================================
/* these macros return 0 for positive numbers, and -1 for negative ones
*/
#define FT_SIGN_LONG(x) ( (x) >> (FT_SIZEOF_LONG*8-1) )
#define FT_SIGN_INT(x) ( (x) >> (FT_SIZEOF_INT*8-1) )
#define FT_SIGN_INT32(x) ( (x) >> 31 )
#define FT_SIGN_INT16(x) ( (x) >> 15 )
FT_EXPORT_DEF( void )
FT_Vector_Rotate( FT_Vector* vec,
FT_Angle angle )
{
FT_Int shift;
FT_Vector v;
v.x = vec->x;
v.y = vec->y;
if ( angle && ( v.x != 0 || v.y != 0 ) )
{
shift = ft_trig_prenorm( &v );
ft_trig_pseudo_rotate( &v, angle );
v.x = ft_trig_downscale( v.x );
v.y = ft_trig_downscale( v.y );
if ( shift > 0 )
{
FT_Int32 half = 1L << (shift-1);
vec->x = (v.x + half + FT_SIGN_LONG(v.x)) >> shift;
vec->y = (v.y + half + FT_SIGN_LONG(v.y)) >> shift;
}
else
{
shift = -shift;
vec->x = v.x << shift;
vec->y = v.y << shift;
}
}
}
=============================================================================
Again, could someone commit this to the CVS ?
Regards,
- David Turner
- The FreeType Project (www.freetype.org)
--
This message and any attachments (the "message") is intended solely for the
addressees and is confidential. If you receive this message in error, please
delete it and immediately notify the sender.
Any use not in accordance with its purpose, any dissemination or disclosure,
either whole or partial, is prohibited except formal approval.
The E-Mail transmission can not guarantee the integrity of this message.
CANAL+TECHNOLOGIES will not therefore be liable for the message if modified.