// ------------------------------------------------------------------------------------------------ // MODULE : Geometrie // LANGAGE : C++ // CREATEUR : Adolfo VIDE // DATE : Mercredi 16 Septembre 1992 // DESCRIPTION : // COMMENTAIRE : // SCCSID : @(#)geometry.h 1.1 11:50:02 18 Dec 1996 // ---------------------------------------------------------------------------- // Copyright (c) 1999 Digital Imaging Group, Inc. // For conditions of distribution and use, see copyright notice // in Flashpix.h // ---------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------ #ifndef Geometrie_h #define Geometrie_h #ifndef Commun_h #include "common.h" #endif // Commun_h // ------------------------------------------------------------------------------------------------ // Includes // -------- // Constantes // ---------- enum typ_Clipping { clip_Normal, clip_Clippe, clip_Complemente }; enum typ_Operation { op_Soustraction=0, op_Addition=1, op_Alpha_Composite=2}; enum TypePositionnement {T = 1, Sh, Sv, S, TR, TH, TRA, TAn, Gen, FourPoints}; // Declarations des classes // ------------------------ struct TransfoPerspective; typedef TransfoPerspective* ptr_TransfoPerspective; typedef TransfoPerspective& ref_TransfoPerspective; class IntegralTransfo; typedef IntegralTransfo* ptr_IntegralTransfo; typedef IntegralTransfo& ref_IntegralTransfo; struct IntegralPosition; typedef IntegralPosition* ptr_IntegralPosition; typedef IntegralPosition& ref_IntegralPosition; struct Int12Position; typedef Int12Position* ptr_Int12Position; typedef Int12Position& ref_Int12Position; struct Bezier; typedef Bezier* ptr_Bezier; typedef Bezier& ref_Bezier; // pour ne pas inclure FichierLP.h class FichierLP; typedef FichierLP* ptr_FichierLP; typedef FichierLP& ref_FichierLP; // Definitions des classes // ----------------------- // // In 3D homogeneous coordinates, transformation of a plane into a 3D space is expressed as : // // a c e x0 // b d f y0 (see [FOL] p.216 - Eq 5.45) // g h i z0 // 0 0 0 1 // // This general transformation can be simplified in our case taking into account the following model : // // - we will use a perspective projection of center 0 on a z=d plane (see [FOL] p.254 - Fig 6.42) // // - we can fix arbitrary d=1 so the projection matrix will be // 1 0 0 0 // 0 1 0 0 (see [FOL] p.254 - Eq 6.3) // 0 0 1 0 // 0 0 1 0 // so a (x,y,z,1) point becomes (x,y,z,z) which is equivalent in homogeneous coordinates to // (x/z, y/z, 1, 1) // // - because we use only flat 2D shapes and project onto z=1, we can consider every start shape // as belonging to this plane, so the homogeneous coordinates we use are reduced to the form // (x,y,1,1) // // - using this reduction, it's easy to see that all z transforms can be turned into translation terms // so the general matrix becomes : // a c 0 x0 // b d 0 y0 // g h 1 z0 // 0 0 0 1 // // - using only points of the form (x,y,1,1), this matrix can be turned into : // a c x0 0 // b d y0 0 // g h z0 0 // 0 0 0 1 // // - we see the 4th dimension is useless in our case so a simple 3x3 matrix is enough // // - because we use only this transformation to simulate a perspective view of a plane, we // don't need any z0 term and can fix it to 1, leaving the projection plane unchanged. // The final transformation matrix before projection is then : // a c x0 // b d y0 // px py 1 // // px and py are called the perspective coefficients. If they are equal to 0, there is no perspective and // the matrix is similar to the classical affine matrix transformation in 2D homogeneous coordinates. // // References : // [FOL] : Foley, Van Dam : Computer Graphics, second edition, fifth print // // // CAUTION : TransfoPerspective are not affine transformationsÉ // There are affine if and only if px = py = 0 // See usage of IsAffine() and IsScaling() // // Important properties : // ---------------------- // // - When multiplying a vector by a matrix, we always project onto z=1 after multiplication, dividing the // resulting coordinates by (px*x + py*y + 1). // // - Consequence : the multiplication of a vector (getting rid of the translation factor) by a matrix is no more linear // // - To maintain a "1" bottom right value, we always normalize matrices after multiplication // // - The multiplication of matrices and vectors is associative : the combinaison still worksÉ // P1*[P2(X)] = [P1*P2](X) // This is still true with normalized matrices multiplication // struct TransfoPerspective { friend class IntegralTransfo; TransfoPerspective (); TransfoPerspective (const TransfoPerspective& Ta); TransfoPerspective (float a, float b, float c, float d, float x0 = 0, float y0 = 0, float px = 0, float py = 0); // Composition operators TransfoPerspective& operator =(const TransfoPerspective& transfoPerspective); friend TransfoPerspective operator *(const TransfoPerspective& T1, const TransfoPerspective& T2); TransfoPerspective& operator *=(const TransfoPerspective& T); friend PositionMv operator *(const TransfoPerspective& T, const PositionMv& point); // used only in obj_MasqueClippeKi::LocalUnderCrop friend PositionMv MultipMatrixVector(const TransfoPerspective& T, const PositionMv& point); friend VecteurMv operator *(const TransfoPerspective& T, const VecteurMv& vector); TransfoPerspective Produit (const TransfoPerspective& Ta) const; // Inverse transformation void Inverse(); // Old affine transformation methods void ForcerPosition (TypePositionnement type, VecteurMv& v1, VecteurMv& v2, VecteurMv& v3); void ForcerPosition (TypePositionnement type, VecteurMv& v1, VecteurMv& v2, VecteurMv& v3, VecteurMv& v4); void ForcerPosition (PositionMv& pA1, PositionMv& pB1, PositionMv& pA2, PositionMv& pB2, PositionMv& pA3, PositionMv& pB3); // Standard primitive transformations void TransApplyTrans (const PositionMv& center, const TransfoPerspective& transfo); void Translate (const VecteurMv& vector); void Rotate (const PositionMv& center, float theta); void Scale (const PositionMv& center, float sx, float sy); void ShearHorizontal (const PositionMv& center, float sh); void ShearVertical (const PositionMv& center, float sh); void FlipHorizontal (const PositionMv& center); void FlipVertical (const PositionMv& center); void Translate (float dx, float dy); void Rotate (float x0, float y0, float theta); void Scale (float x0, float y0, float sx, float sy); void ShearHorizontal (float x0, float y0, float sh); void ShearVertical (float x0, float y0, float sh); void FlipHorizontal (float x0, float y0); void FlipVertical (float x0, float y0); // Perspective transformation void Set4Points (const PositionMv& a0, const PositionMv& a1, const PositionMv& a2, const PositionMv& a3, const PositionMv& b0, const PositionMv& b1, const PositionMv& b2, const PositionMv& b3); // Get Information Boolean IsAffine(); Boolean IsScaling(); Boolean IsNull(); Boolean IsNonRotatedRectangle(); // Get the translation, rotation, skew and scale which compose this matrix // (angles are given in radian between [-PI, PI]) void GetComponents(float* rotationAngle, float* skewAngle, float* scaleH, float* scaleV, float* translationH, float* translationV, float* perspectiveX = NULL, float* perspectiveY = NULL) const; // Get the different matix components // Use carefully: Implemented to speed up renderings void GetAffineMatrix(float* a, float* b, float* c, float* d, float* x0 = NULL, float* y0 = NULL) const; void GetTranslation(float* translationH, float* translationV) const; void GetPerspective(float* perspectiveX, float* perspectiveY) const; // // In homogeneous coordinates, transformation is expressed as a 3x3 matrix : // // a c x0 // b d y0 // px py 1 // // See explanations above // private: float a; float b; float c; float d; float x0; float y0; float px; float py; }; // INTEGRAL COMPUTATION : TO BE USE FOR FAST ACCESS // In integral computing, dimensions are long used with 12 decimal bits instead of float // Integral transformation matrix used for fast computing : same thing than TransfoPerspective but integral "<<12" class IntegralTransfo { public: IntegralTransfo (); IntegralTransfo& operator =(const TransfoPerspective& transfoPerspective); friend Int12Position operator *(const IntegralTransfo& T, const PositionMv& point); friend Int12Position operator *(const IntegralTransfo& T, const IntegralPosition& point); friend Int12Position operator *(const IntegralTransfo& T, const Int12Position& point); protected: private: long a; long b; long c; long d; long x0; long y0; long px; long py; }; // Integral point coordinates : typically used for screen or output page coordinates struct IntegralPosition { IntegralPosition (); IntegralPosition (long x, long y); // Caution : converting an Int12Position into an IntegralPosition will loose precision IntegralPosition& operator =(const Int12Position& point); friend inline IntegralPosition operator +(const IntegralPosition& p1, const IntegralPosition& p2); friend inline IntegralPosition operator -(const IntegralPosition& p1, const IntegralPosition& p2); IntegralPosition& operator +=(const IntegralPosition& p); long x; long y; }; // Integral point coordinates with 12 decimal bits : same thing than IntegralPosition but "<<12" struct Int12Position { Int12Position (); // Caution : converting an IntegralPosition into an Int12Position will not recover precision Int12Position& operator =(const IntegralPosition& point); Int12Position& operator =(const PositionMv& point); friend inline Int12Position operator +(const Int12Position& p1, const Int12Position& p2); friend inline Int12Position operator -(const Int12Position& p1, const Int12Position& p2); Int12Position& operator +=(const Int12Position& p); long x; long y; }; // BEZIER : struct Bezier { Bezier() {suivant = NULL;} void Init(float p0x, float p0y, float p1x, float p1y, float p2x, float p2y, float p3x, float p3y); static void DetruitSuiteBezier(ptr_Bezier laBezier); static ptr_Bezier ReverseBezier(ptr_Bezier theBezier); float p0x; // The 4 points p0 to p3 float p0y; float p1x; float p1y; float p2x; float p2y; float p3x; float p3y; Boolean d; // True if last point ptr_Bezier suivant; // Next Bezier segment }; // Fonctions 'inline' // ------------------ inline IntegralPosition::IntegralPosition() { x = 0; y = 0; } inline IntegralPosition::IntegralPosition (long x, long y) { this->x = x; this->y = y; } inline Int12Position::Int12Position() { x = 0; y = 0; } inline IntegralPosition& IntegralPosition::operator =(const Int12Position& point) { x = point.x >> 12; y = point.y >> 12; return *this; } inline Int12Position& Int12Position::operator =(const IntegralPosition& point) { x = point.x << 12; y = point.y << 12; return *this; } inline Int12Position& Int12Position::operator =(const PositionMv& point) { x = (long)(point.h * 4096.0); y = (long)(point.v * 4096.0); return *this; } inline IntegralPosition operator +(const IntegralPosition& p1, const IntegralPosition& p2) { IntegralPosition p; p.x = p1.x + p2.x; p.y = p1.y + p2.y; return p; } inline IntegralPosition operator -(const IntegralPosition& p1, const IntegralPosition& p2) { IntegralPosition p; p.x = p1.x - p2.x; p.y = p1.y - p2.y; return p; } inline IntegralPosition& IntegralPosition::operator +=(const IntegralPosition& p) { x += p.x; y += p.y; return *this; } inline Int12Position operator +(const Int12Position& p1, const Int12Position& p2) { Int12Position p; p.x = p1.x + p2.x; p.y = p1.y + p2.y; return p; } inline Int12Position operator -(const Int12Position& p1, const Int12Position& p2) { Int12Position p; p.x = p1.x - p2.x; p.y = p1.y - p2.y; return p; } inline Int12Position& Int12Position::operator +=(const Int12Position& p) { x += p.x; y += p.y; return *this; } inline void TransfoPerspective::GetTranslation(float* translationH, float* translationV) const { *translationH = x0, *translationV = y0; } // Fonctions 'extern' // ------------------ // These functions are to accelerate computation of perspective matrix for 68K #undef MC68000 #ifdef macintosh #ifndef powerc #define MC68000 #endif #endif #ifndef MC68000 typedef float Ratio; #define MakeRatio(x) (x) #define FastDiv(x,y) ((x)/(y)) #else #ifdef applec extern "C" long Div64(long x, long y); #else extern long Div64(long x, long y); #endif typedef long Ratio; #define MakeRatio(x) ((x) * 0x100000) #define FastDiv(x,y) Div64((x),(y)) #endif // Variables 'extern' // ------------------ extern long tableProf[]; // ------------------------------------------------------------------------------------------------ #endif // Geometrie_h // ------------------------------------------------------------------------------------------------