freetype-devel
[Top][All Lists]
Advanced

[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.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]