fixedmath.h
上传用户:sdaoma
上传日期:2013-08-07
资源大小:3838k
文件大小:17k
源码类别:

GPS编程

开发平台:

C/C++

  1. /**
  2.  * file fixedmath.h
  3.  * author Wei Yongming <ymwei@minigui.org>
  4.  * date 2002/01/12
  5.  * 
  6.  *  This file includes fixed point and three-dimension math routines.
  7.  *
  8.  verbatim
  9.     Copyright (C) 1998-2002 Wei Yongming.
  10.     Copyright (C) 2002-2004 Feynman Software.
  11.     This file is part of MiniGUI, a compact cross-platform Graphics 
  12.     User Interface (GUI) support system for real-time embedded systems.
  13.     This program is free software; you can redistribute it and/or modify
  14.     it under the terms of the GNU General Public License as published by
  15.     the Free Software Foundation; either version 2 of the License, or
  16.     (at your option) any later version.
  17.     This program is distributed in the hope that it will be useful,
  18.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.     GNU General Public License for more details.
  21.     You should have received a copy of the GNU General Public License
  22.     along with this program; if not, write to the Free Software
  23.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  endverbatim
  25.  */
  26. /*
  27.  * $Id: fixedmath.h,v 1.20 2004/06/26 08:41:44 weiym Exp $
  28.  *
  29.  *             MiniGUI for Linux/uClinux, eCos, uC/OS-II, and VxWorks version 1.6.x
  30.  *             Copyright (C) 1998-2002 Wei Yongming.
  31.  *             Copyright (C) 2002-2004 Feynman Software.
  32.  *
  33.  *             Fix point math routins come from Allegro
  34.  *             By Shawn Hargreaves and others.
  35.  *             So thank for their great work and good license.
  36.  *
  37.  *             "Allegro is a gift-software" 
  38.  *
  39.  *         ______   ___    ___
  40.  *        /  _   /_   /_ 
  41.  *          L \//  //       __     __   _ __   ___
  42.  *            __           /'__` /'_ `/`'__/ __`
  43.  *            /  _ _ _ _/  __// L   // L 
  44.  *            _ _/____/____ ____ ____  _\ ____/
  45.  *            /_//_//____//____//____//___L /_/ /___/
  46.  *                                           /____/
  47.  *                                           _/__/
  48.  *
  49.  */
  50. #ifndef _MGUI_FIXED_MATH_H
  51. #define _MGUI_FIXED_MATH_H
  52. #include <errno.h>
  53. #include <math.h>
  54. /* Set up for C function definitions, even when using C++ */
  55. #ifdef __cplusplus
  56. extern "C" {
  57. #endif
  58. #ifdef _FIXED_MATH
  59.     /**
  60.      * addtogroup fns Functions
  61.      * @{
  62.      */
  63.     /**
  64.      * addtogroup global_fns Global/general functions
  65.      * @{
  66.      */
  67.     /**
  68.      * defgroup fixed_math_fns Fixed point math functions
  69.      * 
  70.      * You know that the float point mathematics routines are very
  71.      * expensive. If you do not want precision mathematics result, 
  72.      * you can use fixed point. MiniGUI uses a double word (32-bit)
  73.      * integer to represent a fixed point ranged from -32767.0 to 
  74.      * 32767.0, and defines some fixed point mathematics routines for 
  75.      * your application. Some GDI functions need fixed point 
  76.      * math routines, like a Arc.
  77.      *
  78.      * Example 1:
  79.      * 
  80.      * include fixed_point.c
  81.      *
  82.      * Example 2:
  83.      * 
  84.      * include fixedpoint.c
  85.      * @{
  86.      */
  87. /**
  88.  * fn fixed fsqrt (fixed x)
  89.  * brief Returns the non-negative square root of a fixed point value.
  90.  *
  91.  * This function returns the non-negative square root of a x.
  92.  * It fails and sets errno to EDOM, if x is negative.
  93.  *
  94.  * sa fhypot
  95.  */
  96. fixed fsqrt (fixed x);
  97. /**
  98.  * fn fixed fhypot (fixed x, fixed y)
  99.  * brief Returns the Euclidean distance from the origin.
  100.  * 
  101.  * The function returns the a sqrt(x*x+y*y). This is the length of 
  102.  * the hypotenuse of a right-angle triangle with sides of length a x and a y, 
  103.  * or the distance of the point a (x,y) from the origin.
  104.  *
  105.  * sa fsqrt
  106.  */
  107. fixed fhypot (fixed x, fixed y);
  108. /**
  109.  * fn fixed fatan (fixed x)
  110.  * brief Calculates the arc tangent of a fixed point value.
  111.  *
  112.  * This function calculates the arc tangent of a x; that is the value 
  113.  * whose tangent is a x.
  114.  *
  115.  * return Returns the arc tangent in radians and the value is 
  116.  *         mathematically defined to be between -PI/2 and PI/2 (inclusive).
  117.  *
  118.  * sa fatan2
  119.  */
  120. fixed fatan (fixed x);
  121. /**
  122.  * fn fixed fatan2 (fixed y, fixed x)
  123.  * brief Calclulates the arc tangent of two fixed point variables.
  124.  *
  125.  *  This function calculates the arc tangent of the two variables a x and a y.
  126.  *  It is similar to calculating the arc tangent of a y / a x, except that 
  127.  *  the signs of both arguments are used to determine the quadrant of the result.
  128.  *
  129.  * return Returns the result in radians, which is between -PI and PI (inclusive).
  130.  *
  131.  * sa fatan
  132.  */
  133. fixed fatan2 (fixed y, fixed x);
  134. extern fixed _cos_tbl[];
  135. extern fixed _tan_tbl[];
  136. extern fixed _acos_tbl[];
  137. /************************** inline fixed point math functions *****************/
  138. /* ftofix and fixtof are used in generic C versions of fmul and fdiv */
  139. /**
  140.  * fn fixed ftofix (double x)
  141.  * brief Converts a float point value to a fixed point value.
  142.  *
  143.  * This function converts the specified float point value a x to 
  144.  * a fixed point value.
  145.  *
  146.  * note The float point should be ranged from -32767.0 to 32767.0.
  147.  * If it runs out of the range, this function sets a errno to a ERANGE.
  148.  *
  149.  * sa fixtof
  150.  */
  151. static inline fixed ftofix (double x)
  152.    if (x > 32767.0) {
  153.       errno = ERANGE;
  154.       return 0x7FFFFFFF;
  155.    }
  156.    if (x < -32767.0) {
  157.       errno = ERANGE;
  158.       return -0x7FFFFFFF;
  159.    }
  160.    return (long)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); 
  161. }
  162. /**
  163.  * fn double fixtof (fixed x)
  164.  * brief Converts a fixed point value to a float point value.
  165.  *
  166.  * This function converts the specified fixed point value a x to 
  167.  * a float point value.
  168.  *
  169.  * sa ftofix
  170.  */
  171. static inline double fixtof (fixed x)
  172.    return (double)x / 65536.0; 
  173. }
  174. /**
  175.  * fn fixed fadd (fixed x, fixed y)
  176.  * brief Returns the sum of two fixed point values.
  177.  *
  178.  * This function adds two fixed point values a x and a y, and
  179.  * returns the sum.
  180.  *
  181.  * param x x,y: Two addends.
  182.  * param y x,y: Two addends.
  183.  * return The sum. If the result runs out of range of fixed point, this function
  184.  *         sets a errno to a ERANGE.
  185.  *
  186.  * sa fsub
  187.  */
  188. static inline fixed fadd (fixed x, fixed y)
  189. {
  190.    fixed result = x + y;
  191.    if (result >= 0) {
  192.       if ((x < 0) && (y < 0)) {
  193.  errno = ERANGE;
  194.  return -0x7FFFFFFF;
  195.       }
  196.       else
  197.  return result;
  198.    }
  199.    else {
  200.       if ((x > 0) && (y > 0)) {
  201.  errno = ERANGE;
  202.  return 0x7FFFFFFF;
  203.       }
  204.       else
  205.  return result;
  206.    }
  207. }
  208. /**
  209.  * fn fixed fsub (fixed x, fixed y)
  210.  * brief Subtract a fixed point value from another.
  211.  *
  212.  * This function subtracts the fixed point values a y from the fixed point value a x,
  213.  * and returns the difference.
  214.  *
  215.  * param x The minuend.
  216.  * param y The subtrahend.
  217.  * return The difference. If the result runs out of range of fixed point, this function
  218.  *         sets a errno to a ERANGE.
  219.  *
  220.  * sa fadd
  221.  */
  222. static inline fixed fsub (fixed x, fixed y)
  223. {
  224.    fixed result = x - y;
  225.    if (result >= 0) {
  226.       if ((x < 0) && (y > 0)) {
  227.  errno = ERANGE;
  228.  return -0x7FFFFFFF;
  229.       }
  230.       else
  231.  return result;
  232.    }
  233.    else {
  234.       if ((x > 0) && (y < 0)) {
  235.  errno = ERANGE;
  236.  return 0x7FFFFFFF;
  237.       }
  238.       else
  239.  return result;
  240.    }
  241. }
  242. /**
  243.  * fn fixed fmul (fixed x, fixed y)
  244.  * brief Returns the product of two fixed point values.
  245.  * 
  246.  * This function returns the product of two fixed point values a x and a y.
  247.  *
  248.  * param x The faciend.
  249.  * param y The multiplicato.
  250.  * return The prodcut. If the result runs out of range of fixed point, this function
  251.  *         sets a errno to a ERANGE.
  252.  * 
  253.  * sa fdiv
  254.  */
  255. static inline fixed fmul (fixed x, fixed y)
  256. {
  257.    return ftofix(fixtof(x) * fixtof(y));
  258. }
  259. /**
  260.  * fn fixed fdiv (fixed x, fixed y)
  261.  * brief Returns the quotient of two fixed point values.
  262.  * 
  263.  * This function returns the quotient of two fixed point values a x and a y.
  264.  *
  265.  * param x The dividend.
  266.  * param y The divisor.
  267.  * return The quotient. If the result runs out of range of fixed point, this function
  268.  *         sets a errno to a ERANGE.
  269.  * 
  270.  * sa fmul
  271.  */
  272. static inline fixed fdiv (fixed x, fixed y)
  273. {
  274.    if (y == 0) {
  275.       errno = ERANGE;
  276.       return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF;
  277.    }
  278.    else
  279.       return ftofix(fixtof(x) / fixtof(y));
  280. }
  281. /**
  282.  * fn int fceil (fixed x)
  283.  * brief Rounds a fixed point value to the nearest integer.
  284.  *
  285.  * This function rounds the fixed point value a x to the nearest integer
  286.  * and returns it.
  287.  *
  288.  * return The rounded integer value.
  289.  */
  290. static inline int fceil (fixed x)
  291. {
  292.    x += 0xFFFF;
  293.    if (x >= 0x80000000) {
  294.       errno = ERANGE;
  295.       return 0x7FFF;
  296.    }
  297.    return (x >> 16);
  298. }
  299. /**
  300.  * fn fixed itofix (int x)
  301.  * brief Converts an integer to a fixed point value.
  302.  *
  303.  * This function converts the integer a x to a fixed point value.
  304.  *
  305.  * sa fixtoi
  306.  */
  307. static inline fixed itofix (int x)
  308.    return x << 16;
  309. }
  310. /**
  311.  * fn int fixtoi (fixed x)
  312.  * brief Converts an fixed point value to an integer.
  313.  *
  314.  * This function converts the fixed point a x to an integer.
  315.  *
  316.  * sa itofix
  317.  */
  318. static inline int fixtoi (fixed x)
  319.    return (x >> 16) + ((x & 0x8000) >> 15);
  320. }
  321. /**
  322.  * fn fixed fcos (fixed x)
  323.  * brief Returns the cosine of a fixed point.
  324.  *
  325.  * This function returns the cosine of the fixed point a x, 
  326.  * where a x is given in radians.
  327.  *
  328.  * sa facos
  329.  */
  330. static inline fixed fcos (fixed x)
  331. {
  332.    return _cos_tbl[((x + 0x4000) >> 15) & 0x1FF];
  333. }
  334. /**
  335.  * fn fixed fsin (fixed x)
  336.  * brief Returns the sine of a fixed point.
  337.  *
  338.  * This function returns the sine of the fixed point a x, 
  339.  * where a x is given in radians.
  340.  *
  341.  * sa fasin
  342.  */
  343. static inline fixed fsin (fixed x)
  344.    return _cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF];
  345. }
  346. /**
  347.  * fn fixed ftan (fixed x)
  348.  * brief Returns the tangent of a fixed point.
  349.  *
  350.  * This function returns the tangent of the fixed point a x, 
  351.  * where a x is given in radians.
  352.  *
  353.  * sa fcos, fsin
  354.  */
  355. static inline fixed ftan (fixed x)
  356.    return _tan_tbl[((x + 0x4000) >> 15) & 0xFF];
  357. }
  358. /**
  359.  * fn fixed facos (fixed x)
  360.  * brief Calculates and returns the arc cosine of a fixed point.
  361.  *
  362.  * This function calculates the arc cosine of the fixed point a x; 
  363.  * that is the value whose cosine is a x. If a x falls outside
  364.  * the range -1 to 1, this function fails and a errno is set to EDOM.
  365.  *
  366.  * return Returns the arc cosine in radians and the value is mathematically 
  367.  *         defined to be between 0 and PI (inclusive).
  368.  *
  369.  * sa fcos
  370.  */
  371. static inline fixed facos (fixed x)
  372. {
  373.    if ((x < -65536) || (x > 65536)) {
  374.       errno = EDOM;
  375.       return 0;
  376.    }
  377.    return _acos_tbl[(x+65536+127)>>8];
  378. }
  379. /**
  380.  * fn fixed fasin (fixed x)
  381.  * brief Calculates and returns the arc sine of a fixed point.
  382.  *
  383.  * This function calculates the arc sine of the fixed point a x; 
  384.  * that is the value whose sine is a x. If a x falls outside
  385.  * the range -1 to 1, this function fails and a errno is set to EDOM.
  386.  *
  387.  * return Returns the arc sine in radians and the value is mathematically 
  388.  *         defined to be between -PI/2 and PI/2 (inclusive).
  389.  *
  390.  * sa fsin
  391.  */
  392. static inline fixed fasin (fixed x)
  393.    if ((x < -65536) || (x > 65536)) {
  394.       errno = EDOM;
  395.       return 0;
  396.    }
  397.    return 0x00400000 - _acos_tbl[(x+65536+127)>>8];
  398. }
  399.     /** @} end of fixed_math_fns */
  400. #ifdef _MATH_3D
  401. typedef struct MATRIX            /* transformation matrix (fixed point) */
  402. {
  403.    fixed v[3][3];                /* scaling and rotation */
  404.    fixed t[3];                   /* translation */
  405. } MATRIX;
  406. typedef struct MATRIX_f          /* transformation matrix (floating point) */
  407. {
  408.    float v[3][3];                /* scaling and rotation */
  409.    float t[3];                   /* translation */
  410. } MATRIX_f;
  411. extern MATRIX identity_matrix;
  412. extern MATRIX_f identity_matrix_f;
  413. void get_translation_matrix (MATRIX *m, fixed x, fixed y, fixed z);
  414. void get_translation_matrix_f (MATRIX_f *m, float x, float y, float z);
  415. void get_scaling_matrix (MATRIX *m, fixed x, fixed y, fixed z);
  416. void get_scaling_matrix_f (MATRIX_f *m, float x, float y, float z);
  417. void get_x_rotate_matrix (MATRIX *m, fixed r);
  418. void get_x_rotate_matrix_f (MATRIX_f *m, float r);
  419. void get_y_rotate_matrix (MATRIX *m, fixed r);
  420. void get_y_rotate_matrix_f (MATRIX_f *m, float r);
  421. void get_z_rotate_matrix (MATRIX *m, fixed r);
  422. void get_z_rotate_matrix_f (MATRIX_f *m, float r);
  423. void get_rotation_matrix (MATRIX *m, fixed x, fixed y, fixed z);
  424. void get_rotation_matrix_f (MATRIX_f *m, float x, float y, float z);
  425. void get_align_matrix (MATRIX *m, fixed xfront, fixed yfront, fixed zfront, fixed xup, fixed yup, fixed zup);
  426. void get_align_matrix_f (MATRIX_f *m, float xfront, float yfront, float zfront, float xup, float yup, float zup);
  427. void get_vector_rotation_matrix (MATRIX *m, fixed x, fixed y, fixed z, fixed a);
  428. void get_vector_rotation_matrix_f (MATRIX_f *m, float x, float y, float z, float a);
  429. void get_transformation_matrix (MATRIX *m, fixed scale, fixed xrot, fixed yrot, fixed zrot, fixed x, fixed y, fixed z);
  430. void get_transformation_matrix_f (MATRIX_f *m, float scale, float xrot, float yrot, float zrot, float x, float y, float z);
  431. void get_camera_matrix (MATRIX *m, fixed x, fixed y, fixed z, fixed xfront, fixed yfront, fixed zfront, 
  432.                 fixed xup, fixed yup, fixed zup, fixed fov, fixed aspect);
  433. void get_camera_matrix_f (MATRIX_f *m, float x, float y, float z, float xfront, float yfront, float zfront, 
  434.                 float xup, float yup, float zup, float fov, float aspect);
  435. void qtranslate_matrix (MATRIX *m, fixed x, fixed y, fixed z);
  436. void qtranslate_matrix_f (MATRIX_f *m, float x, float y, float z);
  437. void qscale_matrix (MATRIX *m, fixed scale);
  438. void qscale_matrix_f (MATRIX_f *m, float scale);
  439. void matrix_mul (AL_CONST MATRIX *m1, AL_CONST MATRIX *m2, MATRIX *out);
  440. void matrix_mul_f (AL_CONST MATRIX_f *m1, AL_CONST MATRIX_f *m2, MATRIX_f *out);
  441. fixed vector_length (fixed x, fixed y, fixed z);
  442. float vector_length_f (float x, float y, float z);
  443. void normalize_vector (fixed *x, fixed *y, fixed *z);
  444. void normalize_vector_f (float *x, float *y, float *z);
  445. void cross_product (fixed x1, fixed y1, fixed z1, fixed x2, fixed y2, fixed z2, fixed *xout, fixed *yout, fixed *zout);
  446. void cross_product_f (float x1, float y1, float z1, float x2, float y2, float z2, float *xout, float *yout, float *zout);
  447. fixed polygon_z_normal (AL_CONST V3D *v1, AL_CONST V3D *v2, AL_CONST V3D *v3);
  448. float polygon_z_normal_f (AL_CONST V3D_f *v1, AL_CONST V3D_f *v2, AL_CONST V3D_f *v3);
  449. void apply_matrix_f (AL_CONST MATRIX_f *m, float x, float y, float z, float *xout, float *yout, float *zout);
  450. extern fixed _persp_xscale;
  451. extern fixed _persp_yscale;
  452. extern fixed _persp_xoffset;
  453. extern fixed _persp_yoffset;
  454. extern float _persp_xscale_f;
  455. extern float _persp_yscale_f;
  456. extern float _persp_xoffset_f;
  457. extern float _persp_yoffset_f;
  458. void set_projection_viewport (int x, int y, int w, int h);
  459. typedef struct QUAT
  460. {
  461.    float w, x, y, z;
  462. } QUAT;
  463. extern QUAT, identity_quat;
  464. void quat_mul (AL_CONST QUAT *p, AL_CONST QUAT *q, QUAT *out)
  465. void get_x_rotate_quat (QUAT *q, float r);
  466. void get_y_rotate_quat (QUAT *q, float r);
  467. void get_z_rotate_quat (QUAT *q, float r);
  468. void get_rotation_quat (QUAT *q, float x, float y, float z);
  469. void get_vector_rotation_quat (QUAT *q, float x, float y, float z, float a);
  470. void quat_to_matrix (AL_CONST QUAT *q, MATRIX_f *m);
  471. void matrix_to_quat (AL_CONST MATRIX_f *m, QUAT *q);
  472. void apply_quat (AL_CONST QUAT *q, float x, float y, float z, float *xout, float *yout, float *zout);
  473. void quat_slerp (AL_CONST QUAT *from, AL_CONST QUAT *to, float t, QUAT *out, int how);
  474. #define QUAT_SHORT   0
  475. #define QUAT_LONG    1
  476. #define QUAT_CW      2
  477. #define QUAT_CCW     3
  478. #define QUAT_USER    4
  479. #define quat_interpolate(from, to, t, out)   quat_slerp((from), (to), (t), (out), QUAT_SHORT)
  480. static inline fixed dot_product (fixed x1, fixed y1, fixed z1, fixed x2, fixed y2, fixed z2)
  481. {
  482.    return fmul(x1, x2) + fmul(y1, y2) + fmul(z1, z2);
  483. }
  484. static inline float dot_product_f (float x1, float y1, float z1, float x2, float y2, float z2)
  485. {
  486.    return (x1 * x2) + (y1 * y2) + (z1 * z2);
  487. }
  488. #define CALC_ROW(n)     (fmul(x, m->v[n][0]) +        
  489.                          fmul(y, m->v[n][1]) +        
  490.                          fmul(z, m->v[n][2]) +        
  491.                          m->t[n])
  492. static inline void apply_matrix (MATRIX *m, fixed x, fixed y, fixed z, fixed *xout, fixed *yout, fixed *zout)
  493. {
  494.    *xout = CALC_ROW(0);
  495.    *yout = CALC_ROW(1);
  496.    *zout = CALC_ROW(2);
  497. }
  498. #undef CALC_ROW
  499. static inline void persp_project (fixed x, fixed y, fixed z, fixed *xout, fixed *yout)
  500. {
  501.    *xout = fmul(fdiv(x, z), _persp_xscale) + _persp_xoffset;
  502.    *yout = fmul(fdiv(y, z), _persp_yscale) + _persp_yoffset;
  503. }
  504. static inline void persp_project_f (float x, float y, float z, float *xout, float *yout)
  505. {
  506.    float z1 = 1.0f / z;
  507.    *xout = ((x * z1) * _persp_xscale_f) + _persp_xoffset_f;
  508.    *yout = ((y * z1) * _persp_yscale_f) + _persp_yoffset_f;
  509. }
  510. #endif /* _MATH_3D */
  511.     /** @} end of global_fns */
  512.     /** @} end of fns */
  513. #endif /* _FIXED_MATH */
  514. /* Ends C function definitions when using C++ */
  515. #ifdef __cplusplus
  516. }
  517. #endif
  518. #endif /* _MGUI_FIXED_MATH_H */