xref: /haiku/headers/libs/agg/agg_trans_bilinear.h (revision 95bac3fda53a4cb21880712d7b43f8c21db32a2e)
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.2
3 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 //          mcseemagg@yahoo.com
13 //          http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 //
16 // Bilinear 2D transformations
17 //
18 //----------------------------------------------------------------------------
19 #ifndef AGG_TRANS_BILINEAR_INCLUDED
20 #define AGG_TRANS_BILINEAR_INCLUDED
21 
22 #include "agg_basics.h"
23 #include "agg_simul_eq.h"
24 
25 namespace agg
26 {
27 
28     //==========================================================trans_bilinear
29     class trans_bilinear
30     {
31     public:
32         //--------------------------------------------------------------------
33         trans_bilinear() : m_valid(false) {}
34 
35         //--------------------------------------------------------------------
36         // Arbitrary quadrangle transformations
37         trans_bilinear(const double* src, const double* dst)
38         {
39             quad_to_quad(src, dst);
40         }
41 
42 
43         //--------------------------------------------------------------------
44         // Direct transformations
45         trans_bilinear(double x1, double y1, double x2, double y2,
46                        const double* quad)
47         {
48             rect_to_quad(x1, y1, x2, y2, quad);
49         }
50 
51 
52         //--------------------------------------------------------------------
53         // Reverse transformations
54         trans_bilinear(const double* quad,
55                        double x1, double y1, double x2, double y2)
56         {
57             quad_to_rect(quad, x1, y1, x2, y2);
58         }
59 
60 
61         //--------------------------------------------------------------------
62         // Set the transformations using two arbitrary quadrangles.
63         void quad_to_quad(const double* src, const double* dst)
64         {
65             double left[4][4];
66             double right[4][2];
67 
68             unsigned i;
69             for(i = 0; i < 4; i++)
70             {
71                 unsigned ix = i * 2;
72                 unsigned iy = ix + 1;
73                 left[i][0] = 1.0;
74                 left[i][1] = src[ix] * src[iy];
75                 left[i][2] = src[ix];
76                 left[i][3] = src[iy];
77 
78                 right[i][0] = dst[ix];
79                 right[i][1] = dst[iy];
80             }
81             m_valid = simul_eq<4, 2>::solve(left, right, m_mtx);
82         }
83 
84 
85         //--------------------------------------------------------------------
86         // Set the direct transformations, i.e., rectangle -> quadrangle
87         void rect_to_quad(double x1, double y1, double x2, double y2,
88                           const double* quad)
89         {
90             double src[8];
91             src[0] = src[6] = x1;
92             src[2] = src[4] = x2;
93             src[1] = src[3] = y1;
94             src[5] = src[7] = y2;
95             quad_to_quad(src, quad);
96         }
97 
98 
99         //--------------------------------------------------------------------
100         // Set the reverse transformations, i.e., quadrangle -> rectangle
101         void quad_to_rect(const double* quad,
102                           double x1, double y1, double x2, double y2)
103         {
104             double dst[8];
105             dst[0] = dst[6] = x1;
106             dst[2] = dst[4] = x2;
107             dst[1] = dst[3] = y1;
108             dst[5] = dst[7] = y2;
109             quad_to_quad(quad, dst);
110         }
111 
112         //--------------------------------------------------------------------
113         // Check if the equations were solved successfully
114         bool is_valid() const { return m_valid; }
115 
116         //--------------------------------------------------------------------
117         // Transform a point (x, y)
118         void transform(double* x, double* y) const
119         {
120             double tx = *x;
121             double ty = *y;
122             double xy = tx * ty;
123             *x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty;
124             *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty;
125         }
126 
127     private:
128         double m_mtx[4][2];
129         bool   m_valid;
130     };
131 
132 }
133 
134 #endif
135