📄 fixedmath.h
字号:
/**
* \file fixedmath.h
* \author Wei Yongming <ymwei@minigui.org>
* \date 2002/01/12
*
* This file includes fixed point and three-dimension math routines.
*
\verbatim
Copyright (C) 1998-2002 Wei Yongming.
Copyright (C) 2002-2004 Feynman Software.
This file is part of MiniGUI, a compact cross-platform Graphics
User Interface (GUI) support system for real-time embedded systems.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\endverbatim
*/
/*
* $Id: fixedmath.h,v 1.20 2004/06/26 08:41:44 weiym Exp $
*
* MiniGUI for Linux/uClinux, eCos, uC/OS-II, and VxWorks version 1.6.x
* Copyright (C) 1998-2002 Wei Yongming.
* Copyright (C) 2002-2004 Feynman Software.
*
* Fix point math routins come from Allegro
* By Shawn Hargreaves and others.
* So thank for their great work and good license.
*
* "Allegro is a gift-software"
*
* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
*/
#ifndef _MGUI_FIXED_MATH_H
#define _MGUI_FIXED_MATH_H
#include <errno.h>
#include <math.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _FIXED_MATH
/**
* \addtogroup fns Functions
* @{
*/
/**
* \addtogroup global_fns Global/general functions
* @{
*/
/**
* \defgroup fixed_math_fns Fixed point math functions
*
* You know that the float point mathematics routines are very
* expensive. If you do not want precision mathematics result,
* you can use fixed point. MiniGUI uses a double word (32-bit)
* integer to represent a fixed point ranged from -32767.0 to
* 32767.0, and defines some fixed point mathematics routines for
* your application. Some GDI functions need fixed point
* math routines, like \a Arc.
*
* Example 1:
*
* \include fixed_point.c
*
* Example 2:
*
* \include fixedpoint.c
* @{
*/
/**
* \fn fixed fsqrt (fixed x)
* \brief Returns the non-negative square root of a fixed point value.
*
* This function returns the non-negative square root of \a x.
* It fails and sets errno to EDOM, if x is negative.
*
* \sa fhypot
*/
fixed fsqrt (fixed x);
/**
* \fn fixed fhypot (fixed x, fixed y)
* \brief Returns the Euclidean distance from the origin.
*
* The function returns the \a sqrt(x*x+y*y). This is the length of
* the hypotenuse of a right-angle triangle with sides of length \a x and \a y,
* or the distance of the point \a (x,y) from the origin.
*
* \sa fsqrt
*/
fixed fhypot (fixed x, fixed y);
/**
* \fn fixed fatan (fixed x)
* \brief Calculates the arc tangent of a fixed point value.
*
* This function calculates the arc tangent of \a x; that is the value
* whose tangent is \a x.
*
* \return Returns the arc tangent in radians and the value is
* mathematically defined to be between -PI/2 and PI/2 (inclusive).
*
* \sa fatan2
*/
fixed fatan (fixed x);
/**
* \fn fixed fatan2 (fixed y, fixed x)
* \brief Calclulates the arc tangent of two fixed point variables.
*
* This function calculates the arc tangent of the two variables \a x and \a y.
* It is similar to calculating the arc tangent of \a y / \a x, except that
* the signs of both arguments are used to determine the quadrant of the result.
*
* \return Returns the result in radians, which is between -PI and PI (inclusive).
*
* \sa fatan
*/
fixed fatan2 (fixed y, fixed x);
extern fixed _cos_tbl[];
extern fixed _tan_tbl[];
extern fixed _acos_tbl[];
/************************** inline fixed point math functions *****************/
/* ftofix and fixtof are used in generic C versions of fmul and fdiv */
/**
* \fn fixed ftofix (double x)
* \brief Converts a float point value to a fixed point value.
*
* This function converts the specified float point value \a x to
* a fixed point value.
*
* \note The float point should be ranged from -32767.0 to 32767.0.
* If it runs out of the range, this function sets \a errno to \a ERANGE.
*
* \sa fixtof
*/
static inline fixed ftofix (double x)
{
if (x > 32767.0) {
errno = ERANGE;
return 0x7FFFFFFF;
}
if (x < -32767.0) {
errno = ERANGE;
return -0x7FFFFFFF;
}
return (long)(x * 65536.0 + (x < 0 ? -0.5 : 0.5));
}
/**
* \fn double fixtof (fixed x)
* \brief Converts a fixed point value to a float point value.
*
* This function converts the specified fixed point value \a x to
* a float point value.
*
* \sa ftofix
*/
static inline double fixtof (fixed x)
{
return (double)x / 65536.0;
}
/**
* \fn fixed fadd (fixed x, fixed y)
* \brief Returns the sum of two fixed point values.
*
* This function adds two fixed point values \a x and \a y, and
* returns the sum.
*
* \param x x,y: Two addends.
* \param y x,y: Two addends.
* \return The sum. If the result runs out of range of fixed point, this function
* sets \a errno to \a ERANGE.
*
* \sa fsub
*/
static inline fixed fadd (fixed x, fixed y)
{
fixed result = x + y;
if (result >= 0) {
if ((x < 0) && (y < 0)) {
errno = ERANGE;
return -0x7FFFFFFF;
}
else
return result;
}
else {
if ((x > 0) && (y > 0)) {
errno = ERANGE;
return 0x7FFFFFFF;
}
else
return result;
}
}
/**
* \fn fixed fsub (fixed x, fixed y)
* \brief Subtract a fixed point value from another.
*
* This function subtracts the fixed point values \a y from the fixed point value \a x,
* and returns the difference.
*
* \param x The minuend.
* \param y The subtrahend.
* \return The difference. If the result runs out of range of fixed point, this function
* sets \a errno to \a ERANGE.
*
* \sa fadd
*/
static inline fixed fsub (fixed x, fixed y)
{
fixed result = x - y;
if (result >= 0) {
if ((x < 0) && (y > 0)) {
errno = ERANGE;
return -0x7FFFFFFF;
}
else
return result;
}
else {
if ((x > 0) && (y < 0)) {
errno = ERANGE;
return 0x7FFFFFFF;
}
else
return result;
}
}
/**
* \fn fixed fmul (fixed x, fixed y)
* \brief Returns the product of two fixed point values.
*
* This function returns the product of two fixed point values \a x and \a y.
*
* \param x The faciend.
* \param y The multiplicato.
* \return The prodcut. If the result runs out of range of fixed point, this function
* sets \a errno to \a ERANGE.
*
* \sa fdiv
*/
static inline fixed fmul (fixed x, fixed y)
{
return ftofix(fixtof(x) * fixtof(y));
}
/**
* \fn fixed fdiv (fixed x, fixed y)
* \brief Returns the quotient of two fixed point values.
*
* This function returns the quotient of two fixed point values \a x and \a y.
*
* \param x The dividend.
* \param y The divisor.
* \return The quotient. If the result runs out of range of fixed point, this function
* sets \a errno to \a ERANGE.
*
* \sa fmul
*/
static inline fixed fdiv (fixed x, fixed y)
{
if (y == 0) {
errno = ERANGE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -