From 1192c4575ea7afdf38e3fa0df4587a08620af11e Mon Sep 17 00:00:00 2001 From: root Date: Tue, 21 Jul 2020 10:00:46 +0200 Subject: SZS v2.18a --- project/dclib/dclib-numeric.h | 839 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 839 insertions(+) create mode 100644 project/dclib/dclib-numeric.h (limited to 'project/dclib/dclib-numeric.h') diff --git a/project/dclib/dclib-numeric.h b/project/dclib/dclib-numeric.h new file mode 100644 index 0000000..19fefda --- /dev/null +++ b/project/dclib/dclib-numeric.h @@ -0,0 +1,839 @@ + +/*************************************************************************** + * * + * _____ ____ * + * | __ \ / __ \ _ _ _____ * + * | | \ \ / / \_\ | | | | _ \ * + * | | \ \| | | | | | |_| | * + * | | | || | | | | | ___/ * + * | | / /| | __ | | | | _ \ * + * | |__/ / \ \__/ / | |___| | |_| | * + * |_____/ \____/ |_____|_|_____/ * + * * + * Wiimms source code library * + * * + *************************************************************************** + * * + * Copyright (c) 2012-2020 by Dirk Clemens * + * * + *************************************************************************** + * * + * 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. * + * * + * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt * + * * + ***************************************************************************/ + +#ifndef DCLIB_NUMERIC_H +#define DCLIB_NUMERIC_H 1 + +#include "dclib-types.h" +#include "dclib-debug.h" +#include + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// float vector /////////////// +/////////////////////////////////////////////////////////////////////////////// +// [[float3]] + +typedef struct float3 +{ + union + { + u32 u[3]; + float v[3]; + struct + { + float x; + float y; + float z; + } + __attribute__ ((packed)); + } + __attribute__ ((packed)); +} +__attribute__ ((packed)) float3; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// [[float3List_t]] + +typedef struct float3List_t +{ + float3 *list; // list of data + uint *sort; // NULL or 'size' alloced elements + uint used; // used elements of 'list' + uint size; // alloced elements of 'list' + +} float3List_t; + +//----------------------------------------------------------------------------- + +void InitializeF3L +( + float3List_t *f3l, // valid data + uint bin_search // >0: enable binary search + // and allocate 'bin_search' elements +); + +void ResetF3L ( float3List_t * f3l ); +float3 * AppendF3L ( float3List_t * f3l ); +uint FindInsertFloatF3L ( float3List_t * f3l, float3 *val, bool fast ); +float3 * GrowF3L ( float3List_t * f3l, uint n ); + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// double vector /////////////// +/////////////////////////////////////////////////////////////////////////////// +// [[double3]] + +typedef struct double3 +{ + union + { + u64 u[3]; + double v[3]; + struct + { + double x; + double y; + double z; + }; + }; + +} double3; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// [[double3List_t]] + +typedef struct double3List_t +{ + double3 *list; // list of data + uint used; // used elements of 'list' + uint size; // alloced elements of 'list' + +} double3List_t; + +//----------------------------------------------------------------------------- + +void InitializeD3L ( double3List_t * d3l ); +void ResetD3L ( double3List_t * d3l ); +double3 * AppendD3L ( double3List_t * d3l ); +uint FindInsertFloatD3L ( double3List_t * d3l, double3 *val, bool fast ); +double3 * GrowD3L ( double3List_t * d3l, uint n ); + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// 2D vector macros /////////////// +/////////////////////////////////////////////////////////////////////////////// + +#define SideOfLine(ax,ay,bx,by,px,py) \ + ( ((bx)-(ax)) * ((py)-(ay)) - ((by)-(ay)) * ((px)-(ax)) ) +#define SideOfLineXY(a,b,p) \ + ( ((b).x-(a).x) * ((p).y-(a).y) - ((b).y-(a).y) * ((p).x-(a).x) ) +#define SideOfLineXZ(a,b,p) \ + ( ((b).x-(a).x) * ((p).z-(a).z) - ((b).z-(a).z) * ((p).x-(a).x) ) +#define SideOfLineYZ(a,b,p) \ + ( ((b).y-(a).y) * ((p).z-(a).z) - ((b).z-(a).z) * ((p).y-(a).y) ) + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// 3D vector macros /////////////// +/////////////////////////////////////////////////////////////////////////////// + +#define NULL_EPSILON 1e-9 // 'fabs(value) < NULL_EPSILON' is 0.0 +#define MIN_DEGREE 1e-4 // 'fabs(value) < MIN_DEGREE' is 0.0 + +#define Assign3(d,s) do { (d).x = (s).x; (d).y = (s).y; (d).z = (s).z; } while (0) + +#define IsNull3(d) ( (d).x == 0.0 && (d).y == 0.0 && (d).z == 0.0 ) +#define IsNull3e(d,e) ( fabs((d).x) < (e) \ + && fabs((d).y) < (e) \ + && fabs((d).z) < (e) ) + +#define IsOne3(d) ( (d).x == 1.0 && (d).y == 1.0 && (d).z == 1.0 ) +#define IsOne3e(d,e) ( fabs((d).x-1.0) < (e) \ + && fabs((d).y-1.0) < (e) \ + && fabs((d).z-1.0) < (e) ) + +#define IsVal3(d,v) ( (d).x == (v) && (d).y == (v) && (d).z == (v) ) +#define IsVal3e(d,v,e) ( fabs( (d).x - (v) ) < (e) \ + && fabs( (d).y - (v) ) < (e) \ + && fabs( (d).z - (v) ) < (e) ) + +#define IsEQ3(a,b) ( (a).x == (b).x && (a).y == (b).y && (a).z == (b).z ) +#define IsEQ3e(a,b,e) ( fabs( (a).x - (b).x ) < (e) \ + && fabs( (a).y - (b).y ) < (e) \ + && fabs( (a).z - (b).z ) < (e) ) + +#define Add3(d,a,b) do { (d).x = (a).x + (b).x; \ + (d).y = (a).y + (b).y; \ + (d).z = (a).z + (b).z; \ + } while (0) + +#define Sub3(d,a,b) do { (d).x = (a).x - (b).x; \ + (d).y = (a).y - (b).y; \ + (d).z = (a).z - (b).z; \ + } while (0) + +#define Neg3(v) do { (v).x = -(v).x; (v).y = -(v).y; (v).z = -(v).z; } while (0) + +#define Div3f(d,a,f) do { (d).x = (a).x / (f); \ + (d).y = (a).y / (f); \ + (d).z = (a).z / (f); \ + } while (0) + +#define Mult3f(d,a,f) do { (d).x = (a).x * (f); \ + (d).y = (a).y * (f); \ + (d).z = (a).z * (f); \ + } while (0) + +#define LengthSqare3(d) ( (d).x*(d).x + (d).y*(d).y + (d).z*(d).z ) +#define Length3(d) sqrt( (d).x*(d).x + (d).y*(d).y + (d).z*(d).z ) +#define DotProd3(a,b) ( (a).x*(b).x + (a).y*(b).y + (a).z*(b).z ) + +#define CrossProd3(d,a,b) do { (d).x = (a).y*(b).z - (a).z*(b).y; \ + (d).y = (a).z*(b).x - (a).x*(b).z; \ + (d).z = (a).x*(b).y - (a).y*(b).x; \ + } while (0) + +#define CrossProd3x(d,a,b) do { typeof((d).x) xx = (a).y*(b).z - (a).z*(b).y; \ + typeof((d).y) yy = (a).z*(b).x - (a).x*(b).z; \ + (d).z = (a).x*(b).y - (a).y*(b).x; \ + (d).x = xx; (d).y = yy; \ + } while (0) + +#define Unit3(v) do { double l = Length3(v); \ + if (l) { (v).x /= l; (v).y /= l; (v).z /= l; }} while (0) +#define Unit3f(v,f) do { double l = Length3(v); \ + if (l) { l = (f)/l; \ + (v).x *= l; (v).y *= l; (v).z *= l; }} while (0) + +#define MinMax3p(min,max,a,b,c) do { \ + if (a c ? b : c; } \ + else { min = b < c ? b : c; max = a > c ? a : c; } } while (0) + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// check numbers /////////////// +/////////////////////////////////////////////////////////////////////////////// + +static inline bool IsNormalF ( float f ) +{ + return isfinite(f); +// const int fpclass = fpclassify(f); +// return fpclass == FP_NORMAL || fpclass == FP_ZERO; +} + +static inline bool IsNormalD ( double d ) +{ + return isfinite(d); +// const int fpclass = fpclassify(d); +// return fpclass == FP_NORMAL || fpclass == FP_ZERO; +} + +bool IsNormalF3 ( float *f3 ); +bool IsNormalF3be ( float *f3 ); // big endian! +bool IsNormalD3 ( double *d3 ); + +bool IsEqualD3 ( const double3 *a, const double3 *b, + double null_epsilon, double diff_epsilon ); + +//--- new functions +bool IsSameF ( float a, float b, int bit_diff ); +bool IsSameD ( double a, double b, int bit_diff ); +bool IsSameF3 ( const float *a, const float *b, int bit_diff ); +bool IsSameD3 ( const double *a, const double *b, int bit_diff ); + +//--- radiant and gegree +#define rad2deg(n) ( (n)*(180.0/M_PI) ) +#define deg2rad(n) ( (n)*(M_PI/180.0) ) + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// 2D vector functions /////////////// +/////////////////////////////////////////////////////////////////////////////// + +uint PointsInConvexPolygonF +( + // return, how many points are inside the polygon + + float *pts, // points: pointer to a array with '2*n_pts' elements + uint n_pts, // Number of (x,y) pairs in 'pts' + + float *pol, // polygon: pointer to a array with '2*n_pol' elements + uint n_pol, // number of (x,y) pairs in 'pol' + + bool all, // false: count the numbers of points inside + // true: return '1' for all points inside and otherwise '0' + + int *r_dir // If not NULL then return: + // -1: polygon is defined counterclockwise + // 0: unknown + // +1: polygon is defined clockwise + // If at least one point is inside, the result is known. +); + +//----------------------------------------------------------------------------- + +uint PointsInConvexPolygonD +( + // return, how many points are inside the polygon + + double *pts, // points: pointer to a array with '2*n_pts' elements + uint n_pts, // Number of (x,y) pairs in 'pts' + + double *pol, // polygon: pointer to a array with '2*n_pol' elements + uint n_pol, // number of (x,y) pairs in 'pol' + + bool all, // false: count the numbers of points inside + // true: return '1' for all points inside and otherwise '0' + + int *r_dir // If not NULL then return: + // -1: polygon is defined counterclockwise + // 0: unknown + // +1: polygon is defined clockwise + // If at least one point is inside, the result is known. +); + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// float34 /////////////// +/////////////////////////////////////////////////////////////////////////////// +// [[float34]] + +typedef struct float34 // transformation matrix +{ + union + { + float v[12]; + float m[3][4]; + struct + { + float x[4]; + float y[4]; + float z[4]; + } + __attribute__ ((packed)); + } + __attribute__ ((packed)); +} +__attribute__ ((packed)) float34; + +//----------------------------------------------------------------------------- + +void ClearFloat34 ( float34 *f34 ); +void SetupFloat34 ( float34 *f34 ); + +void SetupMatrixF34 +( + float34 *mat, // data to setup + float3 *scale, // NULL or scaling vector + float3 *rotate, // NULL or rotation vector in *radiant* + float3 *translate // NULL or translation vector +); + +void CalcInverseMatrixF34 +( + float34 *i, // store inverse matrix here + const float34 *t // transformation matrix +); + +void MultiplyF34 +( + float34 *dest, // valid, store result here, may be 'src1' or 'src2' + const float34 *src1, // first valid source, if NULL use dest + const float34 *src2 // second valid source, if NULL use dest +); + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// double34 /////////////// +/////////////////////////////////////////////////////////////////////////////// +// [[double34]] + +typedef struct double34 // transformation matrix +{ + union + { + double v[12]; + double m[3][4]; + struct + { + double x[4]; + double y[4]; + double z[4]; + } + __attribute__ ((packed)); + } + __attribute__ ((packed)); +} +__attribute__ ((packed)) double34; + +//----------------------------------------------------------------------------- + +void ClearDouble34 ( double34 *d34 ); +void SetupDouble34 ( double34 *d34 ); + +void SetupMatrixD34 +( + double34 *mat, // data to setup + double3 *scale, // NULL or scaling vector + double3 *rotate, // NULL or rotation vector in *radiant* + double3 *translate // NULL or translation vector +); + +void CalcInverseMatrixD34 +( + double34 *i, // store inverse matrix here + const double34 *t // transformation matrix +); + +void MultiplyD34 +( + double34 *dest, // valid, store result here, may be 'src1' or 'src2' + const double34 *src1, // first valid source, if NULL use dest + const double34 *src2 // second valid source, if NULL use dest +); + +//----------------------------------------------------------------------------- + +void CopyF34toD34 +( + double34 *dest, // destination matrix + const float34 *src // source matrix +); + +void CopyD34toF34 +( + float34 *dest, // destination matrix + const double34 *src // source matrix +); + +//----------------------------------------------------------------------------- + +static inline float3 TransformF3D34 ( const double34 *d34, const float3 *val ) +{ + DASSERT(d34); + DASSERT(val); + const double *m = d34->v; + float3 res; + res.x = m[ 0] * val->x + m[ 1] * val->y + m[ 2] * val->z + m[ 3]; + res.y = m[4+0] * val->x + m[4+1] * val->y + m[4+2] * val->z + m[4+3]; + res.z = m[8+0] * val->x + m[8+1] * val->y + m[8+2] * val->z + m[8+3]; + return res; +} + +static inline double3 TransformD3D34 ( const double34 *d34, const double3 *val ) +{ + DASSERT(d34); + DASSERT(val); + const double *m = d34->v; + double3 res; + res.x = m[ 0] * val->x + m[ 1] * val->y + m[ 2] * val->z + m[ 3]; + res.y = m[4+0] * val->x + m[4+1] * val->y + m[4+2] * val->z + m[4+3]; + res.z = m[8+0] * val->x + m[8+1] * val->y + m[8+2] * val->z + m[8+3]; + return res; +} + +static inline float3 TransformF3F34 ( const float34 *d34, const float3 *val ) +{ + DASSERT(d34); + DASSERT(val); + const float *m = d34->v; + float3 res; + res.x = m[ 0] * val->x + m[ 1] * val->y + m[ 2] * val->z + m[ 3]; + res.y = m[4+0] * val->x + m[4+1] * val->y + m[4+2] * val->z + m[4+3]; + res.z = m[8+0] * val->x + m[8+1] * val->y + m[8+2] * val->z + m[8+3]; + return res; +} + +static inline double3 TransformD3F34 ( const float34 *d34, const double3 *val ) +{ + DASSERT(d34); + DASSERT(val); + const float *m = d34->v; + double3 res; + res.x = m[ 0] * val->x + m[ 1] * val->y + m[ 2] * val->z + m[ 3]; + res.y = m[4+0] * val->x + m[4+1] * val->y + m[4+2] * val->z + m[4+3]; + res.z = m[8+0] * val->x + m[8+1] * val->y + m[8+2] * val->z + m[8+3]; + return res; +} + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// MatrixD_t /////////////// +/////////////////////////////////////////////////////////////////////////////// +// [[MatrixD_t]] + +typedef struct MatrixD_t +{ + //--- status + + bool valid; // false: data structure needs initialization + bool norm_valid; // false: normed values are invalid + bool tmatrix_valid; // false: transformation matrix is invalid + bool imatrix_valid; // false: inverse matrix is invalid + uint sequence_number; // Used for tracking. It is incremented + // on every new calculation by CalcNormMatrixD() + + //--- matrix usage status + + u8 use_matrix; // 0: matrix not needed for transformation + // 1: matrix needed for transformation + // 2: matrix is the only valid reference + + //--- status, only valid, if 'norm_valid' + + u8 scale_enabled; // scaling is enabled: 1=x, 2=y, 4=z + u8 rotate_enabled; // rotation is enabled: 1=x, 2=y, 4=z + u8 translate_enabled; // translation is enabled: 1=x, 2=y, 4=z + u8 transform_enabled; // 'OR' result of the 3 enabled values above + // OR 'use_matrix<<3' + + //--- base values: clear 'norm_valid' and '*matrix_valid' on change + + double3 scale; // scale vector + double3 scale_origin; // origin for scaling + double3 shift; // shift vector + double3 rotate_deg; // rotation in degree and radiant. + double3 rotate_rad; // both values are used as sum. + double3 rotate_origin[3]; // origin for rotation + double3 translate; // translation vector + + //--- normed values, calculated by CalcNormMatrixD() + + double3 norm_scale; // scale vector + double3 norm_rotate_deg; // rotation vector in degree + double3 norm_rotate_rad; // rotation vector in radiant + double3 norm_translate; // translation vector + double3 norm_pos2d; // recommended positions for 2d transformations + + //--- matrices, calculated by CalcMatrixD() + + double34 trans_matrix; // transformation matrix + double34 inv_matrix; // inverse transformation matrix +} +MatrixD_t; + +//----------------------------------------------------------------------------- + +// statistics +extern u64 N_MatrixD_forward; // total number of forward transformations +extern u64 N_MatrixD_inverse; // total number of inverse transformations + +//----------------------------------------------------------------------------- + +void InitializeMatrixD ( MatrixD_t * mat ); + +void CopyMatrixD +( + MatrixD_t *dest, // valid destination + const + MatrixD_t *src // NULL or source +); + +void TermAssignMatrixD +( + // called after dirext matrix manipulations + MatrixD_t * mat // valid data structure +); + +//----------------------------------------------------------------------------- + +MatrixD_t * SetScaleMatrixD +( + MatrixD_t * mat, // valid data structure + double3 * scale, // NULL: clear scale, not NULL: set scale + double3 * origin // not NULL: Origin for scaling +); + +MatrixD_t * SetShiftMatrixD +( + MatrixD_t * mat, // valid data structure + double3 * shift // NULL: clear Shift, not NULL: set Shift +); + +MatrixD_t * SetScaleShiftMatrixD +( + MatrixD_t * mat, // valid data structure + uint xyz, // 0..2: x/y/z coordinate to set + double old1, // old value of first point + double new1, // new value of first point + double old2, // old value of second point + double new2 // new value of second point +); + +MatrixD_t * SetRotateMatrixD +( + MatrixD_t * mat, // valid data structure + uint xyz, // 0..2: x/y/z coordinate to set + double degree, // angle in degree + double radiant, // angle in radiant + double3 * origin // not NULL: Origin for the rotation +); + +MatrixD_t * SetTranslateMatrixD +( + MatrixD_t * mat, // valid data structure + double3 * translate // NULL: clear translate, not NULL: set translate +); + +MatrixD_t * SetMatrixD +( + MatrixD_t * mat, // valid data structure + const + double34 * src // NULL or matrix to set +); + +//----------------------------------------------------------------------------- + +MatrixD_t * SetAScaleMatrixD +( + // calculate the matrix as rotation around a specified axis + + MatrixD_t * mat, // valid data structure + double scale, // scale factor + double3 * dir // NULL or scaling direction as vector +); + +MatrixD_t * SetARotateMatrixD +( + // calculate the matrix as rotation around a specified axis + + MatrixD_t * mat, // valid data structure + double degree, // angle in degree + double radiant, // angle in radiant, add to degree with factor + double3 * pt1, // point #1 to define the axis; if NULL use (0,0,0) + double3 * pt2 // point #2 to define the axis; if NULL use (0,0,0) +); + +//----------------------------------------------------------------------------- + +MatrixD_t * CheckStatusMatrixD +( + MatrixD_t * mat // valid data structure +); + +MatrixD_t * CalcNormMatrixD +( + MatrixD_t * mat // valid data structure +); + +MatrixD_t * CalcTransMatrixD +( + MatrixD_t * mat, // valid data structure + bool always // false: calc transformation matrix only + // if needed for transformation + // true: ignore 'rotate_enabled' +); + +MatrixD_t * CalcMatrixD +( + MatrixD_t * mat, // valid data structure + bool always // false: calc both matrices only + // if needed for transformation + // true: calc matrices always +); + +MatrixD_t * MultiplyMatrixD +( + MatrixD_t *dest, // valid, store result here, may be 'src1' or 'src2' + MatrixD_t *src1, // first valid source, if NULL use dest + MatrixD_t *src2, // second valid source, if NULL use dest + uint inverse_mode // bit field: + // 1: use inverse matrix of src1 + // 2: use inverse matrix of src2 +); + +MatrixD_t * CalcVectorsMatrixD +( + MatrixD_t * mat, // valid data structure + bool always // false: calc vectors only if matrix is valid + // true: calc matrix if invalid & vectors always +); + +static inline bool TransformationEnabledMatrixD ( MatrixD_t * mat ) +{ + return CalcNormMatrixD(mat)->transform_enabled != 0; +} + +//----------------------------------------------------------------------------- + +double3 TransformD3MatrixD +( + MatrixD_t * mat, // valid data structure + const + double3 * val // value to transform +); + +double3 InvTransformD3MatrixD +( + MatrixD_t * mat, // valid data structure + const + double3 * val // value to transform +); + +void TransformD3NMatrixD +( + MatrixD_t * mat, // valid data structure + double3 * val, // value array to transform + int n, // number of 3D vectors in 'val' + uint off // if n>1: offset from one to next 'val' vector +); + +void InvTransformD3NMatrixD +( + MatrixD_t * mat, // valid data structure + double3 * val, // value array to transform + int n, // number of 3D vectors in 'val' + uint off // if n>1: offset from one to next 'val' vector +); + +//----------------------------------------------------------------------------- + +float3 TransformF3MatrixD +( + MatrixD_t * mat, // valid data structure + const + float3 * val // value to transform +); + +float3 InvTransformF3MatrixD +( + MatrixD_t * mat, // valid data structure + const + float3 * val // value to transform +); + +void TransformF3NMatrixD +( + MatrixD_t * mat, // valid data structure + float3 * val, // value array to transform + int n, // number of 3D vectors in 'val' + uint off // if n>1: offset from one to next 'val' vector +); + +void InvTransformF3NMatrixD +( + MatrixD_t * mat, // valid data structure + float3 * val, // value array to transform + int n, // number of 3D vectors in 'val' + uint off // if n>1: offset from one to next 'val' vector +); + +//----------------------------------------------------------------------------- + +double3 BaseTransformD3MatrixD +( + // transform using the base parameters + + MatrixD_t * mat, // valid data structure + const + double3 * val // value to transform +); + + +double3 NormTransformD3MatrixD +( + // transform using the norm parameters + + MatrixD_t * mat, // valid data structure + const + double3 * val // value to transform +); + +double3 TransformHelperD3MatrixD +( + // transform using vectors + + double3 *scale, // NULL or scale vector + double3 *scale_origin, // NULL or origin for scaling + double3 *shift, // NULL or shift vector + double3 *rotate_deg, // NULL or rotation in degree + double3 *xrot_origin, // NULL or origin for x-rotation + double3 *yrot_origin, // NULL or origin for y-rotation + double3 *zrot_origin, // NULL or origin for z-rotation + double3 *translate, // NULL or translation vector + + const + double3 * val // value to transform +); + +//----------------------------------------------------------------------------- + +void PrintMatrixD +( + FILE * f, // file to print to + uint indent, // indention + ccp eol, // not NULL: print as 'end of line' + + MatrixD_t * mat, // valid data structure + uint create, // bitfield for setup: + // 1: create normals if invalid + // 2: create transform matrix if invalid + // 4: create inverse matrix if invalid + uint print // bitfield print selection: + // 1: print base vectors + // 2: print normalized values, if valid + // 4: print transformation matrix, if valid + // 8: print inverse matrix, if valid + // 0x10: print also header, if only 1 section is print + // 0x20: print all, don't suppress NULL vectors + // 0x40: print an additional EOL behind each section +); + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// CRC16 /////////////// +/////////////////////////////////////////////////////////////////////////////// + +#define CRC16_CCITT_POLYNOM 0x1021 + +void CreateCRC16Table ( u16 table[0x100], u16 polynom ); +const u16 * GetCRC16Table ( u16 polynom ); + +u16 CalcCRC16 ( cvp data, uint data_size, u16 polynom, u16 preset ); +static inline u16 CalcCRC16CCITT ( cvp data, uint data_size ) + { return CalcCRC16(data,data_size,CRC16_CCITT_POLYNOM,0); } + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// misc /////////////// +/////////////////////////////////////////////////////////////////////////////// + +static inline int float2int ( float f ) { return (int) truncf(f+0.5); } +static inline int double2int ( double d ) { return (int) trunc (d+0.5); } +static inline s64 float2int64 ( float f ) { return (s64) truncf(f+0.5); } +static inline s64 double2int64 ( double d ) { return (s64) trunc (d+0.5); } + +/////////////////////////////////////////////////////////////////////////////// + +// all values are multiple of 26*26*100 = 67600 = 0x10810 +#define GOOD_MAX_NICE4_5 67600 // 1 * 67600 +#define GOOD_MAX_NICE4_6 946400 // 14 * 67600 +#define GOOD_MAX_NICE4_7 9937200 // 147 * 67600 +#define GOOD_MAX_NICE4_8 99980400 // 1479 * 67600 +#define GOOD_MAX_NICE4_9 999939200 // 14792 * 67600 +#define GOOD_MAX_NICE4 4294966000 // 63535 * 67600 = 0xfffffaf0 = -1296 + +ccp PrintNiceID4 ( uint nice_gid ); +char * ScanNiceID4 ( int * res, ccp arg ); + +// +/////////////////////////////////////////////////////////////////////////////// +/////////////// E N D /////////////// +/////////////////////////////////////////////////////////////////////////////// + +#endif // DCLIB_NUMERIC_H + -- cgit v1.3.1