aboutsummaryrefslogblamecommitdiffstats
path: root/libart_lgpl/art_affine.c
blob: dd6866ca86e5acf36d7f842bf4246b0177673d8a (plain) (tree)




























                                                                    













                                                                      
                                          
 
               


















                                                                       
                                                        
 
                









                                                    













                                                                      
                                                                                  
 
                                 





















                                                       
                                    








             








                                                       
                                                         









              







                                                       
                                                             



















                                                                     

                                           



                                                         
/* Libart_LGPL - library of basic graphic primitives
 * Copyright (C) 1998 Raph Levien
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/* Simple manipulations with affine transformations */

#include "config.h"
#include "art_affine.h"
#include "art_misc.h" /* for M_PI */

#include <math.h>
#include <stdio.h> /* for sprintf */
#include <string.h> /* for strcpy */

/* According to a strict interpretation of the libart structure, this
   routine should go into its own module, art_point_affine.  However,
   it's only two lines of code, and it can be argued that it is one of
   the natural basic functions of an affine transformation.
*/

/**
 * art_affine_point: Do an affine transformation of a point.
 * @dst: Where the result point is stored.
 * @src: The original point.
 @ @affine: The affine transformation.
 **/
void
art_affine_point (ArtPoint *dst, const ArtPoint *src,
          const gdouble affine[6])
{
  gdouble x, y;

  x = src->x;
  y = src->y;
  dst->x = x * affine[0] + y * affine[2] + affine[4];
  dst->y = x * affine[1] + y * affine[3] + affine[5];
}

/**
 * art_affine_invert: Find the inverse of an affine transformation.
 * @dst: Where the resulting affine is stored.
 * @src: The original affine transformation.
 *
 * All non-degenerate affine transforms are invertible. If the original
 * affine is degenerate or nearly so, expect numerical instability and
 * very likely core dumps on Alpha and other fp-picky architectures.
 * Otherwise, @dst multiplied with @src, or @src multiplied with @dst
 * will be (to within roundoff error) the identity affine.
 **/
void
art_affine_invert (gdouble dst[6], const gdouble src[6])
{
  gdouble r_det;

  r_det = 1.0 / (src[0] * src[3] - src[1] * src[2]);
  dst[0] = src[3] * r_det;
  dst[1] = -src[1] * r_det;
  dst[2] = -src[2] * r_det;
  dst[3] = src[0] * r_det;
  dst[4] = -src[4] * dst[0] - src[5] * dst[2];
  dst[5] = -src[4] * dst[1] - src[5] * dst[3];
}

/**
 * art_affine_multiply: Multiply two affine transformation matrices.
 * @dst: Where to store the result.
 * @src1: The first affine transform to multiply.
 * @src2: The second affine transform to multiply.
 *
 * Multiplies two affine transforms together, i.e. the resulting @dst
 * is equivalent to doing first @src1 then @src2. Note that the
 * PostScript concat operator multiplies on the left, i.e.  "M concat"
 * is equivalent to "CTM = multiply (M, CTM)";
 *
 * It is safe to call this function with @dst equal to @src1 or @src2.
 **/
void
art_affine_multiply (gdouble dst[6], const gdouble src1[6], const gdouble src2[6])
{
  gdouble d0, d1, d2, d3, d4, d5;

  d0 = src1[0] * src2[0] + src1[1] * src2[2];
  d1 = src1[0] * src2[1] + src1[1] * src2[3];
  d2 = src1[2] * src2[0] + src1[3] * src2[2];
  d3 = src1[2] * src2[1] + src1[3] * src2[3];
  d4 = src1[4] * src2[0] + src1[5] * src2[2] + src2[4];
  d5 = src1[4] * src2[1] + src1[5] * src2[3] + src2[5];
  dst[0] = d0;
  dst[1] = d1;
  dst[2] = d2;
  dst[3] = d3;
  dst[4] = d4;
  dst[5] = d5;
}

/**
 * art_affine_identity: Set up the identity matrix.
 * @dst: Where to store the resulting affine transform.
 *
 * Sets up an identity matrix.
 **/
void
art_affine_identity (gdouble dst[6])
{
  dst[0] = 1;
  dst[1] = 0;
  dst[2] = 0;
  dst[3] = 1;
  dst[4] = 0;
  dst[5] = 0;
}

/**
 * art_affine_scale: Set up a scaling matrix.
 * @dst: Where to store the resulting affine transform.
 * @sx: X scale factor.
 * @sy: Y scale factor.
 *
 * Sets up a scaling matrix.
 **/
void
art_affine_scale (gdouble dst[6], gdouble sx, gdouble sy)
{
  dst[0] = sx;
  dst[1] = 0;
  dst[2] = 0;
  dst[3] = sy;
  dst[4] = 0;
  dst[5] = 0;
}

/**
 * art_affine_translate: Set up a translation matrix.
 * @dst: Where to store the resulting affine transform.
 * @tx: X translation amount.
 * @tx: Y translation amount.
 *
 * Sets up a translation matrix.
 **/
void
art_affine_translate (gdouble dst[6], gdouble tx, gdouble ty)
{
  dst[0] = 1;
  dst[1] = 0;
  dst[2] = 0;
  dst[3] = 1;
  dst[4] = tx;
  dst[5] = ty;
}

/**
 * art_affine_expansion: Find the affine's expansion factor.
 * @src: The affine transformation.
 *
 * Finds the expansion factor, i.e. the square root of the factor
 * by which the affine transform affects area. In an affine transform
 * composed of scaling, rotation, shearing, and translation, returns
 * the amount of scaling.
 *
 * Return value: the expansion factor.
 **/
gdouble
art_affine_expansion (const gdouble src[6])
{
  return sqrt (fabs (src[0] * src[3] - src[1] * src[2]));
}