|
|
#ifndef __FIXED_H__
#define __FIXED_H__
#include <math.h>
#ifdef __cplusplus
extern "C" { #endif
#ifndef PI
#define PI (3.1415926535897932384626433832795028841971693993751)
#endif
/* Default table size for precomputed sincos table */ #define FA_TABLE_SIZE 360
/*
Flags for initialization FA_CARTESIAN_Y - Y axis is positive up */ #define FA_DEFAULT 0
#define FA_CARTESIAN_Y 1
#if defined(FX_DOUBLE) || defined(FX_SINGLE)
#ifdef FX_DOUBLE
typedef double FxValue;
#define FX_MAX_VALUE (1e100)
#define FX_MIN_VALUE (1e-10)
#else
typedef float FxValue;
#define FX_MAX_VALUE (1e38f)
#define FX_MIN_VALUE (1e-7f)
#endif
#define FxVal(i) ((FxValue)(i))
#define FxInt(v) ((int)(v))
#define FxFltVal(f) ((FxValue)(f))
#define FxFlt(v) ((double)(v))
#define FxPromote(v) (v)
#define FxDemote(v) (v)
#define FxMul(a, b) ((a)*(b))
#define FxDemotedMul(a, b) FxMul(a, b)
#define FxDiv(a, b) ((a)/(b))
#define FxDemotedDiv(a, b) FxDiv(a, b)
#define FxMulToInt(a, b) FxInt((a)*(b))
#define FxDivToInt(a, b) ((int)((a)/(b)))
#define FxMulDiv(a, m, d) (((a)*(m))/(d))
#define FxSqrt(v) ((FxValue)sqrt((double)(v)))
#define FxDemotedSqrt(v) FxSqrt(v)
typedef FxValue FaAngle;
#define FaAng(a) (a)
#define FaSin(v) ((FxValue)-sin((double)(v)))
#define FaCos(v) ((FxValue)cos((double)(v)))
#define FaAdd(a, d) ((a)+(d))
FaAngle FaNorm(FaAngle a); #define FaDeg(da) ((da)*(FxValue)(PI/180.0))
#define FaRad(ra) (ra)
#define FaAngVal(aa) (aa)
#define FaFltDegVal(a) ((a)*180.0/PI)
#define FaFltRadVal(a) (a)
#define FxInitialize(table_size, flags) ((flags) == FA_DEFAULT)
#define FxEnd()
#else
/* If integer sqrt isn't interesting, define FX_PRECISE_SQRT
and the floating point sqrt will be used */
#ifndef FX_SHIFT
#define FX_SHIFT 10
#endif
#define FX_MULT (1L << FX_SHIFT)
typedef long FxValue;
#define FX_MAX_VALUE (0x7fffffff)
#define FX_MIN_VALUE (1)
#define FxVal(i) FxPromote((FxValue)(i))
#define FxInt(v) ((int)FxDemote(v))
#define FxFltVal(f) ((FxValue)((f)*(double)FX_MULT))
#define FxFlt(v) (((double)(v))/(double)FX_MULT)
#define FxPromote(v) ((v) << FX_SHIFT)
#define FxDemote(v) ((v) >> FX_SHIFT)
#if FX_SHIFT != 16
/* These can overflow if the shift and numbers are too large */ #define FxMul(a, b) FxDemote((a)*(b))
#define FxDiv(a, b) (FxPromote(a)/(b))
#define FxMulToInt(a, b) FxInt(FxDemote((a)*(b)))
#define FxMulDiv(a, m, d) (((a)*(m))/(d))
#else
/* For FX_SHIFT == 16 and certain platforms, assembly routines are
provided which do 64-bit intermediate math, preserving accuracy There is still a danger of overflow if the results don't fit in 32 bits, though */ FxValue FxMul(FxValue a, FxValue b); FxValue FxDiv(FxValue a, FxValue b); int FxMulToInt(FxValue a, FxValue b); FxValue FxMulDiv(FxValue a, FxValue m, FxValue d); #endif
#ifndef FX_PRECISE_SQRT
FxValue FxSqrt(FxValue v); /* Computing the square root of a demoted value leaves it out of
adjustment by sqrt(FX_MULT) so shift by FX_SHIFT/2 to restore fixed point FX_SHIFT should be even for this to work */ #define FxDemotedSqrt(v) (FxSqrt(FxDemote(v)) << (FX_SHIFT/2))
#else
#define FxSqrt(v) FxFltVal(sqrt(FxFlt(v)))
#define FxDemotedSqrt(v) FxSqrt(v)
#endif
#define FxDemotedMul(a, b) (FxDemote(a)*(b))
#define FxDemotedDiv(a, b) FxPromote((a)/(b))
#define FxDivToInt(a, b) ((int)((a)/(b)))
/* One unit of angle is the table quantum
One unit of angle equals 360/_fa_table_size degrees */ typedef FxValue FaAngle;
extern int _fa_table_size;
extern FxValue *_fa_sines; extern FxValue *_fa_cosines;
#define FaAng(a) FxDemote(a)
#define FaSin(a) _fa_sines[(int)FaAng(a)]
#define FaCos(a) _fa_cosines[(int)FaAng(a)]
FaAngle FaAdd(FaAngle a, FaAngle d); FaAngle FaBisectingAngle(FaAngle f, FaAngle t); #define FaNorm(a) FaAdd(FxVal(0), a)
#define FaDeg(da) \
FaNorm(FxMulDiv(FxVal(da), _fa_table_size, 360)) #define FaRad(ra) FaNorm(FxFltVal((ra)*_fa_table_size/PI2))
#define FaAngVal(aa) FaNorm(FxVal(aa))
#define FaFltDegVal(ang) FxFltVal(FxMulDiv(ang, 360, _fa_table_size))
#define FaFltRadVal(ang) (FxFltVal(ang)*PI2/_fa_table_size)
BOOL FxInitialize(int table_size, ULONG flags); void FxEnd(void);
#endif
typedef struct _FxPt2 { FxValue x, y; } FxPt2; typedef FxPt2 FxVec2;
typedef struct _FxBox2 { FxPt2 min, max; } FxBox2;
typedef struct _FxPt3 { FxValue x, y, z; } FxPt3; typedef FxPt3 FxVec3;
typedef struct _FxBox3 { FxPt3 min, max; } FxBox3;
typedef struct _FxPt4 { FxValue x, y, z, w; } FxPt4; typedef FxPt4 FxVec4;
void FxBBox2Empty(FxBox2 *bb); void FxBBox2AddPt(FxBox2 *bb, FxPt2 *pt);
void FxBBox3Empty(FxBox3 *bb); void FxBBox3AddPt(FxBox3 *bb, FxPt3 *pt);
#define FxV2Set(v, xv, yv) \
((v)->x = (xv), (v)->y = (yv)) #define FxV2Add(a, b, r) \
((r)->x = (a)->x+(b)->x, (r)->y = (a)->y+(b)->y) #define FxV2Sub(a, b, r) \
((r)->x = (a)->x-(b)->x, (r)->y = (a)->y-(b)->y) #define FxV2Dot(a, b) \
(FxMul((a)->x, (b)->x)+FxMul((a)->y, (b)->y)) #define FxV2Neg(v, r) \
((r)->x = -(v)->x, (r)->y = -(v)->y) #define FxV2NegV(v) FxV2Neg(v, v)
#define FxV2NormV(v) FxV2Norm(v, v)
FxValue FxV2Len(FxVec2 *v); FxValue FxV2Norm(FxVec2 *v, FxVec2 *r);
#define FxvV2Set(v, xv, yv) FxV2Set(&(v), xv, yv)
#define FxvV2Add(a, b, r) FxV2Add(&(a), &(b), &(r))
#define FxvV2Sub(a, b, r) FxV2Sub(&(a), &(b), &(r))
#define FxvV2Dot(a, b) FxV2Dot(&(a), &(b))
#define FxvV2Neg(v, r) FxV2Neg(&(v), &(r))
#define FxvV2NegV(v) FxV2NegV(&(v))
#define FxvV2Len(v) FxV2Len(&(v))
#define FxvV2Norm(v, r) FxV2Norm(&(v), &(r))
#define FxvV2NormV(v) FxV2NormV(&(v))
#define FxV3Set(v, xv, yv, zv) \
((v)->x = (xv), (v)->y = (yv), (v)->z = (zv)) #define FxV3Add(a, b, r) \
((r)->x = (a)->x+(b)->x, (r)->y = (a)->y+(b)->y, (r)->z = (a)->z+(b)->z) #define FxV3Sub(a, b, r) \
((r)->x = (a)->x-(b)->x, (r)->y = (a)->y-(b)->y, (r)->z = (a)->z-(b)->z) #define FxV3Dot(a, b) \
(FxMul((a)->x, (b)->x)+FxMul((a)->y, (b)->y)+FxMul((a)->z, (b)->z)) #define FxV3Neg(v, r) \
((r)->x = -(v)->x, (r)->y = -(v)->y, (r)->z = -(v)->z) #define FxV3NegV(v) FxV3Neg(v, v)
#define FxV3Cross(a, b, r) \
((r)->x = (a)->y*(b)->z-(b)->y*(a)->z,\ (r)->y = (a)->z*(b)->x-(b)->z*(a)->x,\ (r)->z = (a)->x*(b)->y-(b)->x*(a)->y) #define FxV3NormV(v) FxV3Norm(v, v)
FxValue FxV3Len(FxVec3 *v); FxValue FxV3Norm(FxVec3 *v, FxVec3 *r);
#define FxvV3Set(v, xv, yv, zv) FxV3Set(&(v), xv, yv, zv)
#define FxvV3Add(a, b, r) FxV3Add(&(a), &(b), &(r))
#define FxvV3Sub(a, b, r) FxV3Sub(&(a), &(b), &(r))
#define FxvV3Dot(a, b) FxV3Dot(&(a), &(b))
#define FxvV3Neg(v, r) FxV3Neg(&(v), &(r))
#define FxvV3NegV(v) FxV3NegV(&(v))
#define FxvV3Cross(a, b, r) FxV3Cross(&(a), &(b), &(r))
#define FxvV3Len(v) FxV3Len(&(v))
#define FxvV3Norm(v, r) FxV3Norm(&(v), &(r))
#define FxvV3NormV(v) FxV3NormV(&(v))
typedef FxValue FxMatrix2[2][2]; typedef FxValue FxMatrix3[3][3]; typedef FxValue FxMatrix4[4][4];
typedef FxValue FxTMatrix2[2][3]; typedef FxValue FxTMatrix3[3][4];
void FxT2Ident(FxTMatrix2 m); void FxT2Mul(FxTMatrix2 a, FxTMatrix2 b, FxTMatrix2 r); void FxT2Vec2(FxTMatrix2 m, int n, FxVec2 *f, FxVec2 *t);
void FxT3Ident(FxTMatrix3 m); void FxT3Mul(FxTMatrix3 a, FxTMatrix3 b, FxTMatrix3 r); void FxT3Vec3(FxTMatrix3 m, int n, FxVec3 *f, FxVec3 *t);
#ifdef __cplusplus
} #endif
#endif
|