/* transform.h: all about transformations */ #ifndef _TRANSFORM_H_ #define _TRANSFORM_H_ #ifdef __cplusplus extern "C" { #endif #include #include "Float.h" #include "vectortype.h" /* * |u'| |m[0][0] m[0][1]| | u | |t[0]| * | | = | | * | | + | | * |v'| |m[1][0] m[1][1]| | v | |t[1]| */ typedef struct TRANSFORM2D { Float m[2][2], t[2]; } TRANSFORM2D; #define TRANSFORM_POINT_2D(trans, src, dst) {POINT2D _d_; \ _d_.u = (trans).m[0][0] * (src).u + (trans).m[0][1] * (src).v + (trans).t[0];\ _d_.v = (trans).m[1][0] * (src).u + (trans).m[1][1] * (src).v + (trans).t[1];\ (dst) = _d_;} #define PRINT_TRANSFORM2D(fp, trans) { \ fprintf(fp, "\t%f %f %f\n", (trans).m[0][0], (trans).m[0][1], (trans).t[0]); \ fprintf(fp, "\t%f %f %f\n", (trans).m[0][1], (trans).m[1][1], (trans).t[1]);} /* xf(p) = xf2(xf1(p)) */ #define PRECONCAT_TRANSFORM2D(xf2, xf1, xf) {TRANSFORM2D _xf_; \ _xf_.m[0][0] = (xf2).m[0][0] * (xf1).m[0][0] + (xf2).m[0][1] * (xf1).m[1][0]; \ _xf_.m[0][1] = (xf2).m[0][0] * (xf1).m[0][1] + (xf2).m[0][1] * (xf1).m[1][1]; \ _xf_.m[1][0] = (xf2).m[1][0] * (xf1).m[0][0] + (xf2).m[1][1] * (xf1).m[1][0]; \ _xf_.m[1][1] = (xf2).m[1][0] * (xf1).m[0][1] + (xf2).m[1][1] * (xf1).m[1][1]; \ _xf_.t[0] = (xf2).m[0][0] * (xf1).t[0] + (xf2).m[0][1] * (xf1).t[1] + (xf2).t[0];\ _xf_.t[1] = (xf2).m[1][0] * (xf1).t[0] + (xf2).m[1][1] * (xf1).t[1] + (xf2).t[1];\ (xf) = _xf_;} /* 4x4 transform */ typedef struct TRANSFORM { Float m[4][4]; } TRANSFORM; extern TRANSFORM IdentityTransform; #define SET_3X3MATRIX(m, a, b, c, d, e, f, g, h, i) { \ m[0][0] = a; m[0][1] = b; m[0][2] = c; \ m[1][0] = d; m[1][1] = e; m[1][2] = f; \ m[2][0] = g; m[2][1] = h; m[2][2] = i; \ } extern void PrintTransform(FILE *out, TRANSFORM xf); /* xf(p) = xf2(xf1(p)) */ extern TRANSFORM TransCompose(TRANSFORM xf2, TRANSFORM xf1); /* Create scaling, ... transform. The transforms behave identically as the * corresponding transforms in OpenGL. */ extern TRANSFORM Scale(VECTOR s); extern TRANSFORM RotateX(Float angle /*radians*/), RotateY(Float angle), RotateZ(Float angle); extern TRANSFORM Rotate(Float angle /* radians */, VECTOR axis); extern TRANSFORM Translate(VECTOR t); extern TRANSFORM LookAt(VECTOR eye, VECTOR centre, VECTOR up); extern TRANSFORM Perspective(Float fov /*radians*/, Float aspect, Float near, Float far); extern TRANSFORM Ortho(Float left, Float right, Float bottom, Float top, Float near, Float far); /* Recovers the rotation axis and angle from the given rotation matrix. * There is no check whether the transform really is a rotation. */ extern void RecoverRotation(TRANSFORM xf, float *angle, VECTOR *axis); #define TRANSFORM_POINT_3D(trans, src, dst) {POINT _d_; \ _d_.x = (trans).m[0][0] * (src).x + (trans).m[0][1] * (src).y + (trans).m[0][2] * (src).z + (trans).m[0][3]; \ _d_.y = (trans).m[1][0] * (src).x + (trans).m[1][1] * (src).y + (trans).m[1][2] * (src).z + (trans).m[1][3]; \ _d_.z = (trans).m[2][0] * (src).x + (trans).m[2][1] * (src).y + (trans).m[2][2] * (src).z + (trans).m[2][3]; \ (dst) = _d_;} #define TRANSFORM_VECTOR_3D(trans, src, dst) {VECTOR _d_; \ _d_.x = (trans).m[0][0] * (src).x + (trans).m[0][1] * (src).y + (trans).m[0][2] * (src).z; \ _d_.y = (trans).m[1][0] * (src).x + (trans).m[1][1] * (src).y + (trans).m[1][2] * (src).z; \ _d_.z = (trans).m[2][0] * (src).x + (trans).m[2][1] * (src).y + (trans).m[2][2] * (src).z; \ (dst) = _d_;} #define TRANSFORM_POINT_4D(trans, src, dst) {POINT4D _d_; \ _d_.x = (trans).m[0][0] * (src).x + (trans).m[0][1] * (src).y + (trans).m[0][2] * (src).z + (trans).m[0][3] * (src).w; \ _d_.y = (trans).m[1][0] * (src).x + (trans).m[1][1] * (src).y + (trans).m[1][2] * (src).z + (trans).m[1][3] * (src).w; \ _d_.z = (trans).m[2][0] * (src).x + (trans).m[2][1] * (src).y + (trans).m[2][2] * (src).z + (trans).m[2][3] * (src).w; \ _d_.w = (trans).m[3][0] * (src).x + (trans).m[3][1] * (src).y + (trans).m[3][2] * (src).z + (trans).m[3][3] * (src).w; \ (dst) = _d_;} #ifdef __cplusplus } #endif #endif /*_TRANSFORM_H_*/