home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / libgimp / gimpmatrix.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-06  |  9.3 KB  |  417 lines

  1. /* LIBGIMP - The GIMP Library 
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * gimpmatrix.c
  5.  * Copyright (C) 1998 Jay Cox <jaycox@earthlink.net>
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the
  19.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  */
  22.  
  23. #include <glib.h>
  24.  
  25. #include "gimpmath.h"
  26. #include "gimpmatrix.h"
  27.  
  28.  
  29. #define EPSILON 1e-6
  30.  
  31.  
  32. /**
  33.  * gimp_matrix3_transform_point:
  34.  * @matrix: The transformation matrix.
  35.  * @x: The source X coordinate.
  36.  * @y: The source Y coordinate.
  37.  * @newx: The transformed X coordinate.
  38.  * @newy: The transformed Y coordinate.
  39.  * 
  40.  * Transforms a point in 2D as specified by the transformation matrix.
  41.  */
  42. void
  43. gimp_matrix3_transform_point (GimpMatrix3  matrix, 
  44.                   gdouble      x, 
  45.                   gdouble      y,
  46.                   gdouble     *newx, 
  47.                   gdouble     *newy)
  48. {
  49.   gdouble w;
  50.  
  51.   w = matrix[2][0]*x + matrix[2][1]*y + matrix[2][2];
  52.  
  53.   if (w == 0.0)
  54.     w = 1.0;
  55.   else
  56.     w = 1.0/w;
  57.  
  58.   *newx = (matrix[0][0]*x + matrix[0][1]*y + matrix[0][2])*w;
  59.   *newy = (matrix[1][0]*x + matrix[1][1]*y + matrix[1][2])*w;
  60. }
  61.  
  62. /**
  63.  * gimp_matrix3_mult:
  64.  * @matrix1: The first input matrix.
  65.  * @matrix2: The second input matrix which will be oeverwritten ba the result.
  66.  * 
  67.  * Multiplies two matrices and puts the result into the second one.
  68.  */
  69. void
  70. gimp_matrix3_mult (GimpMatrix3 matrix1, 
  71.            GimpMatrix3 matrix2)
  72. {
  73.   gint i, j;
  74.   GimpMatrix3 tmp;
  75.   gdouble t1, t2, t3;
  76.  
  77.   for (i = 0; i < 3; i++)
  78.     {
  79.       t1 = matrix1[i][0];
  80.       t2 = matrix1[i][1];
  81.       t3 = matrix1[i][2];
  82.       for (j = 0; j < 3; j++)
  83.     {
  84.       tmp[i][j]  = t1 * matrix2[0][j];
  85.       tmp[i][j] += t2 * matrix2[1][j];
  86.       tmp[i][j] += t3 * matrix2[2][j];
  87.     }
  88.     }
  89.  
  90.   /*  put the results in matrix2 */
  91.   memcpy (&matrix2[0][0], &tmp[0][0], sizeof (GimpMatrix3));
  92. }
  93.  
  94. /**
  95.  * gimp_matrix3_identity:
  96.  * @matrix: A matrix.
  97.  * 
  98.  * Sets the matrix to the identity matrix.
  99.  */
  100. void
  101. gimp_matrix3_identity (GimpMatrix3 matrix)
  102. {
  103.   static GimpMatrix3 identity = { { 1.0, 0.0, 0.0 },
  104.                   { 0.0, 1.0, 0.0 },
  105.                   { 0.0, 0.0, 1.0 } };
  106.  
  107.   memcpy (&matrix[0][0], &identity[0][0], sizeof (GimpMatrix3));
  108. }
  109.  
  110. /**
  111.  * gimp_matrix3_translate:
  112.  * @matrix: The matrix that is to be translated.
  113.  * @x: Translation in X direction.
  114.  * @y: Translation in Y direction.
  115.  * 
  116.  * Translates the matrix by x and y.
  117.  */
  118. void
  119. gimp_matrix3_translate (GimpMatrix3 matrix, 
  120.             gdouble     x, 
  121.             gdouble     y)
  122. {
  123.   gdouble g, h, i;
  124.  
  125.   g = matrix[2][0];
  126.   h = matrix[2][1];
  127.   i = matrix[2][2];
  128.  
  129.   matrix[0][0] += x * g;
  130.   matrix[0][1] += x * h;
  131.   matrix[0][2] += x * i;
  132.   matrix[1][0] += y * g;
  133.   matrix[1][1] += y * h;
  134.   matrix[1][2] += y * i;
  135. }
  136.  
  137. /**
  138.  * gimp_matrix3_scale:
  139.  * @matrix: The matrix that is to be scaled.
  140.  * @x: X scale factor.
  141.  * @y: Y scale factor.
  142.  * 
  143.  * Scales the matrix by x and y 
  144.  */
  145. void
  146. gimp_matrix3_scale (GimpMatrix3 matrix, 
  147.             gdouble     x, 
  148.             gdouble     y)
  149. {
  150.   matrix[0][0] *= x;
  151.   matrix[0][1] *= x;
  152.   matrix[0][2] *= x;
  153.  
  154.   matrix[1][0] *= y;
  155.   matrix[1][1] *= y;
  156.   matrix[1][2] *= y;
  157. }
  158.  
  159. /**
  160.  * gimp_matrix3_rotate:
  161.  * @matrix: The matrix that is to be rotated.
  162.  * @theta: The angle of rotation (in radians).
  163.  * 
  164.  * Rotates the matrix by theta degrees.
  165.  */
  166. void
  167. gimp_matrix3_rotate (GimpMatrix3 matrix, 
  168.              gdouble     theta)
  169. {
  170.   gdouble t1, t2;
  171.   gdouble cost, sint;
  172.  
  173.   cost = cos (theta);
  174.   sint = sin (theta);
  175.   
  176.   t1 = matrix[0][0];
  177.   t2 = matrix[1][0];
  178.   matrix[0][0] = cost * t1 - sint * t2;
  179.   matrix[1][0] = sint * t1 + cost * t2;
  180.  
  181.   t1 = matrix[0][1];
  182.   t2 = matrix[1][1];
  183.   matrix[0][1] = cost * t1 - sint * t2;
  184.   matrix[1][1] = sint*t1 + cost*t2;
  185.  
  186.   t1 = matrix[0][2];
  187.   t2 = matrix[1][2];
  188.   matrix[0][2] = cost*t1 - sint*t2;
  189.   matrix[1][2] = sint*t1 + cost*t2;
  190. }
  191.  
  192. /**
  193.  * gimp_matrix3_xshear:
  194.  * @matrix: The matrix that is to be sheared.
  195.  * @amount: X shear amount.
  196.  * 
  197.  * Shears the matrix in the X direction.
  198.  */
  199. void
  200. gimp_matrix3_xshear (GimpMatrix3 matrix, 
  201.              gdouble     amount)
  202. {
  203.   matrix[0][0] += amount * matrix[1][0];
  204.   matrix[0][1] += amount * matrix[1][1];
  205.   matrix[0][2] += amount * matrix[1][2];
  206. }
  207.  
  208. /**
  209.  * gimp_matrix3_yshear:
  210.  * @matrix: The matrix that is to be sheared.
  211.  * @amount: Y shear amount.
  212.  * 
  213.  * Shears the matrix in the Y direction.
  214.  */
  215. void
  216. gimp_matrix3_yshear (GimpMatrix3 matrix, 
  217.              gdouble     amount)
  218. {
  219.   matrix[1][0] += amount * matrix[0][0];
  220.   matrix[1][1] += amount * matrix[0][1];
  221.   matrix[1][2] += amount * matrix[0][2];
  222. }
  223.  
  224. /**
  225.  * gimp_matrix3_determinant:
  226.  * @matrix: The input matrix. 
  227.  * 
  228.  * Calculates the determinant of the given matrix.
  229.  * 
  230.  * Returns: The determinant.
  231.  */
  232. gdouble
  233. gimp_matrix3_determinant (GimpMatrix3 matrix)
  234. {
  235.   gdouble determinant;
  236.  
  237.   determinant  = 
  238.     matrix[0][0] * (matrix[1][1]*matrix[2][2] - matrix[1][2]*matrix[2][1]);
  239.   determinant -= 
  240.     matrix[1][0] * (matrix[0][1]*matrix[2][2] - matrix[0][2]*matrix[2][1]);
  241.   determinant += 
  242.     matrix[2][0] * (matrix[0][1]*matrix[1][2] - matrix[0][2]*matrix[1][1]);
  243.  
  244.   return determinant;
  245. }
  246.  
  247. /**
  248.  * gimp_matrix3_invert:
  249.  * @matrix: The matrix that is to be inverted.
  250.  * @matrix_inv: A matrix the inverted matrix should be written into. 
  251.  * 
  252.  * Inverts the given matrix.
  253.  */
  254. void
  255. gimp_matrix3_invert (GimpMatrix3 matrix, 
  256.              GimpMatrix3 matrix_inv)
  257. {
  258.   gdouble det_1;
  259.  
  260.   det_1 = gimp_matrix3_determinant (matrix);
  261.  
  262.   if (det_1 == 0.0)
  263.     return;
  264.  
  265.   det_1 = 1.0 / det_1;
  266.  
  267.   matrix_inv[0][0] =   
  268.     (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1]) * det_1;
  269.  
  270.   matrix_inv[1][0] = 
  271.     - (matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0]) * det_1;
  272.  
  273.   matrix_inv[2][0] =   
  274.     (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]) * det_1;
  275.  
  276.   matrix_inv[0][1] = 
  277.     - (matrix[0][1] * matrix[2][2] - matrix[0][2] * matrix[2][1] ) * det_1;
  278.  
  279.   matrix_inv[1][1] = 
  280.     (matrix[0][0] * matrix[2][2] - matrix[0][2] * matrix[2][0]) * det_1;
  281.  
  282.   matrix_inv[2][1] = 
  283.     - (matrix[0][0] * matrix[2][1] - matrix[0][1] * matrix[2][0]) * det_1;
  284.   
  285.   matrix_inv[0][2] =
  286.     (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]) * det_1;
  287.   
  288.   matrix_inv[1][2] = 
  289.     - (matrix[0][0] * matrix[1][2] - matrix[0][2] * matrix[1][0]) * det_1;
  290.   
  291.   matrix_inv[2][2] = 
  292.     (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]) * det_1;
  293. }
  294.  
  295.  
  296. /**
  297.  * gimp_matrix3_duplicate:
  298.  * @src: The source matrix.
  299.  * @target: The destination matrix. 
  300.  * 
  301.  * Copies the source matrix to the destination matrix.
  302.  */
  303. void
  304. gimp_matrix3_duplicate (GimpMatrix3 src, 
  305.             GimpMatrix3 target)
  306. {
  307.   memcpy (&target[0][0], &src[0][0], sizeof (GimpMatrix3));
  308. }
  309.  
  310.  
  311. /*  functions to test for matrix properties  */
  312.  
  313.  
  314. /**
  315.  * gimp_matrix3_is_diagonal:
  316.  * @matrix: The matrix that is to be tested.
  317.  * 
  318.  * Checks if the given matrix is diagonal.
  319.  * 
  320.  * Returns: TRUE if the matrix is diagonal.
  321.  */
  322. gboolean
  323. gimp_matrix3_is_diagonal (GimpMatrix3 matrix)
  324. {
  325.   gint i, j;
  326.  
  327.   for (i = 0; i < 3; i++)
  328.     {
  329.       for (j = 0; j < 3; j++)
  330.     {
  331.       if (i != j && fabs (matrix[i][j]) > EPSILON)
  332.         return FALSE;
  333.     }
  334.     }
  335.  
  336.   return TRUE;
  337. }
  338.  
  339. /**
  340.  * gimp_matrix3_is_identity:
  341.  * @matrix: The matrix that is to be tested.
  342.  * 
  343.  * Checks if the given matrix is the identity matrix.
  344.  * 
  345.  * Returns: TRUE if the matrix is the identity matrix.
  346.  */
  347. gboolean
  348. gimp_matrix3_is_identity (GimpMatrix3 matrix)
  349. {
  350.   gint i,j;
  351.  
  352.   for (i = 0; i < 3; i++)
  353.     {
  354.       for (j = 0; j < 3; j++)
  355.     {
  356.       if (i == j)
  357.         {
  358.           if (fabs (matrix[i][j] - 1.0) > EPSILON)
  359.         return FALSE;
  360.         }
  361.       else
  362.         {
  363.           if (fabs (matrix[i][j]) > EPSILON)
  364.         return FALSE;
  365.         }
  366.     }
  367.     }
  368.  
  369.   return TRUE;
  370. }
  371.  
  372. /*  Check if we'll need to interpolate when applying this matrix. 
  373.     This function returns TRUE if all entries of the upper left 
  374.     2x2 matrix are either 0 or 1 
  375.  */
  376.  
  377.  
  378. /**
  379.  * gimp_matrix3_is_simple:
  380.  * @matrix: The matrix that is to be tested.
  381.  * 
  382.  * Checks if we'll need to interpolate when applying this matrix as
  383.  * a transformation.
  384.  * 
  385.  * Returns: TRUE if all entries of the upper left 2x2 matrix are either 
  386.  * 0 or 1
  387.  */
  388. gboolean
  389. gimp_matrix3_is_simple (GimpMatrix3 matrix)
  390. {
  391.   gdouble absm;
  392.   gint i, j;
  393.  
  394.   for (i = 0; i < 2; i++)
  395.     {
  396.       for (j = 0; j < 2; j++)
  397.     {
  398.       absm = fabs (matrix[i][j]);
  399.       if (absm > EPSILON && fabs (absm - 1.0) > EPSILON)
  400.         return FALSE;
  401.     }
  402.     }
  403.  
  404.   return TRUE;
  405. }
  406.  
  407. void
  408. gimp_matrix4_to_deg (GimpMatrix4  matrix,
  409.              gdouble     *a,
  410.              gdouble     *b,
  411.              gdouble     *c)
  412. {
  413.   *a = 180 * (asin (matrix[1][0]) / G_PI_2);
  414.   *b = 180 * (asin (matrix[2][0]) / G_PI_2);
  415.   *c = 180 * (asin (matrix[2][1]) / G_PI_2);
  416. }
  417.