xref: /haiku/headers/libs/agg/agg_trans_bilinear.h (revision e39da397f5ff79f2db9f9a3ddf1852b6710578af)
139241fe2SDarkWyrm //----------------------------------------------------------------------------
2*e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4
3*e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
439241fe2SDarkWyrm //
539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software
639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies.
739241fe2SDarkWyrm // This software is provided "as is" without express or implied
839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose.
939241fe2SDarkWyrm //
1039241fe2SDarkWyrm //----------------------------------------------------------------------------
1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com
1239241fe2SDarkWyrm //          mcseemagg@yahoo.com
1339241fe2SDarkWyrm //          http://www.antigrain.com
1439241fe2SDarkWyrm //----------------------------------------------------------------------------
1539241fe2SDarkWyrm //
1639241fe2SDarkWyrm // Bilinear 2D transformations
1739241fe2SDarkWyrm //
1839241fe2SDarkWyrm //----------------------------------------------------------------------------
1939241fe2SDarkWyrm #ifndef AGG_TRANS_BILINEAR_INCLUDED
2039241fe2SDarkWyrm #define AGG_TRANS_BILINEAR_INCLUDED
2139241fe2SDarkWyrm 
2239241fe2SDarkWyrm #include "agg_basics.h"
2339241fe2SDarkWyrm #include "agg_simul_eq.h"
2439241fe2SDarkWyrm 
2539241fe2SDarkWyrm namespace agg
2639241fe2SDarkWyrm {
2739241fe2SDarkWyrm 
2839241fe2SDarkWyrm     //==========================================================trans_bilinear
2939241fe2SDarkWyrm     class trans_bilinear
3039241fe2SDarkWyrm     {
3139241fe2SDarkWyrm     public:
3239241fe2SDarkWyrm         //--------------------------------------------------------------------
trans_bilinear()3339241fe2SDarkWyrm         trans_bilinear() : m_valid(false) {}
3439241fe2SDarkWyrm 
3539241fe2SDarkWyrm         //--------------------------------------------------------------------
3639241fe2SDarkWyrm         // Arbitrary quadrangle transformations
trans_bilinear(const double * src,const double * dst)3739241fe2SDarkWyrm         trans_bilinear(const double* src, const double* dst)
3839241fe2SDarkWyrm         {
3939241fe2SDarkWyrm             quad_to_quad(src, dst);
4039241fe2SDarkWyrm         }
4139241fe2SDarkWyrm 
4239241fe2SDarkWyrm 
4339241fe2SDarkWyrm         //--------------------------------------------------------------------
4439241fe2SDarkWyrm         // Direct transformations
trans_bilinear(double x1,double y1,double x2,double y2,const double * quad)4539241fe2SDarkWyrm         trans_bilinear(double x1, double y1, double x2, double y2,
4639241fe2SDarkWyrm                        const double* quad)
4739241fe2SDarkWyrm         {
4839241fe2SDarkWyrm             rect_to_quad(x1, y1, x2, y2, quad);
4939241fe2SDarkWyrm         }
5039241fe2SDarkWyrm 
5139241fe2SDarkWyrm 
5239241fe2SDarkWyrm         //--------------------------------------------------------------------
5339241fe2SDarkWyrm         // Reverse transformations
trans_bilinear(const double * quad,double x1,double y1,double x2,double y2)5439241fe2SDarkWyrm         trans_bilinear(const double* quad,
5539241fe2SDarkWyrm                        double x1, double y1, double x2, double y2)
5639241fe2SDarkWyrm         {
5739241fe2SDarkWyrm             quad_to_rect(quad, x1, y1, x2, y2);
5839241fe2SDarkWyrm         }
5939241fe2SDarkWyrm 
6039241fe2SDarkWyrm 
6139241fe2SDarkWyrm         //--------------------------------------------------------------------
6239241fe2SDarkWyrm         // Set the transformations using two arbitrary quadrangles.
quad_to_quad(const double * src,const double * dst)6339241fe2SDarkWyrm         void quad_to_quad(const double* src, const double* dst)
6439241fe2SDarkWyrm         {
6539241fe2SDarkWyrm             double left[4][4];
6639241fe2SDarkWyrm             double right[4][2];
6739241fe2SDarkWyrm 
6839241fe2SDarkWyrm             unsigned i;
6939241fe2SDarkWyrm             for(i = 0; i < 4; i++)
7039241fe2SDarkWyrm             {
7139241fe2SDarkWyrm                 unsigned ix = i * 2;
7239241fe2SDarkWyrm                 unsigned iy = ix + 1;
7339241fe2SDarkWyrm                 left[i][0] = 1.0;
7439241fe2SDarkWyrm                 left[i][1] = src[ix] * src[iy];
7539241fe2SDarkWyrm                 left[i][2] = src[ix];
7639241fe2SDarkWyrm                 left[i][3] = src[iy];
7739241fe2SDarkWyrm 
7839241fe2SDarkWyrm                 right[i][0] = dst[ix];
7939241fe2SDarkWyrm                 right[i][1] = dst[iy];
8039241fe2SDarkWyrm             }
8139241fe2SDarkWyrm             m_valid = simul_eq<4, 2>::solve(left, right, m_mtx);
8239241fe2SDarkWyrm         }
8339241fe2SDarkWyrm 
8439241fe2SDarkWyrm 
8539241fe2SDarkWyrm         //--------------------------------------------------------------------
8639241fe2SDarkWyrm         // Set the direct transformations, i.e., rectangle -> quadrangle
rect_to_quad(double x1,double y1,double x2,double y2,const double * quad)8739241fe2SDarkWyrm         void rect_to_quad(double x1, double y1, double x2, double y2,
8839241fe2SDarkWyrm                           const double* quad)
8939241fe2SDarkWyrm         {
9039241fe2SDarkWyrm             double src[8];
9139241fe2SDarkWyrm             src[0] = src[6] = x1;
9239241fe2SDarkWyrm             src[2] = src[4] = x2;
9339241fe2SDarkWyrm             src[1] = src[3] = y1;
9439241fe2SDarkWyrm             src[5] = src[7] = y2;
9539241fe2SDarkWyrm             quad_to_quad(src, quad);
9639241fe2SDarkWyrm         }
9739241fe2SDarkWyrm 
9839241fe2SDarkWyrm 
9939241fe2SDarkWyrm         //--------------------------------------------------------------------
10039241fe2SDarkWyrm         // Set the reverse transformations, i.e., quadrangle -> rectangle
quad_to_rect(const double * quad,double x1,double y1,double x2,double y2)10139241fe2SDarkWyrm         void quad_to_rect(const double* quad,
10239241fe2SDarkWyrm                           double x1, double y1, double x2, double y2)
10339241fe2SDarkWyrm         {
10439241fe2SDarkWyrm             double dst[8];
10539241fe2SDarkWyrm             dst[0] = dst[6] = x1;
10639241fe2SDarkWyrm             dst[2] = dst[4] = x2;
10739241fe2SDarkWyrm             dst[1] = dst[3] = y1;
10839241fe2SDarkWyrm             dst[5] = dst[7] = y2;
10939241fe2SDarkWyrm             quad_to_quad(quad, dst);
11039241fe2SDarkWyrm         }
11139241fe2SDarkWyrm 
11239241fe2SDarkWyrm         //--------------------------------------------------------------------
11339241fe2SDarkWyrm         // Check if the equations were solved successfully
is_valid()11439241fe2SDarkWyrm         bool is_valid() const { return m_valid; }
11539241fe2SDarkWyrm 
11639241fe2SDarkWyrm         //--------------------------------------------------------------------
11739241fe2SDarkWyrm         // Transform a point (x, y)
transform(double * x,double * y)11839241fe2SDarkWyrm         void transform(double* x, double* y) const
11939241fe2SDarkWyrm         {
12039241fe2SDarkWyrm             double tx = *x;
12139241fe2SDarkWyrm             double ty = *y;
12239241fe2SDarkWyrm             double xy = tx * ty;
12339241fe2SDarkWyrm             *x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty;
12439241fe2SDarkWyrm             *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty;
12539241fe2SDarkWyrm         }
12639241fe2SDarkWyrm 
127*e39da397SStephan Aßmus 
128*e39da397SStephan Aßmus         //--------------------------------------------------------------------
129*e39da397SStephan Aßmus         class iterator_x
130*e39da397SStephan Aßmus         {
131*e39da397SStephan Aßmus             double inc_x;
132*e39da397SStephan Aßmus             double inc_y;
133*e39da397SStephan Aßmus 
134*e39da397SStephan Aßmus         public:
135*e39da397SStephan Aßmus             double x;
136*e39da397SStephan Aßmus             double y;
137*e39da397SStephan Aßmus 
iterator_x()138*e39da397SStephan Aßmus             iterator_x() {}
iterator_x(double tx,double ty,double step,const double m[4][2])139*e39da397SStephan Aßmus             iterator_x(double tx, double ty, double step, const double m[4][2]) :
140*e39da397SStephan Aßmus                 inc_x(m[1][0] * step * ty + m[2][0] * step),
141*e39da397SStephan Aßmus                 inc_y(m[1][1] * step * ty + m[2][1] * step),
142*e39da397SStephan Aßmus                 x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty),
143*e39da397SStephan Aßmus                 y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty)
144*e39da397SStephan Aßmus             {
145*e39da397SStephan Aßmus             }
146*e39da397SStephan Aßmus 
147*e39da397SStephan Aßmus             void operator ++ ()
148*e39da397SStephan Aßmus             {
149*e39da397SStephan Aßmus                 x += inc_x;
150*e39da397SStephan Aßmus                 y += inc_y;
151*e39da397SStephan Aßmus             }
152*e39da397SStephan Aßmus         };
153*e39da397SStephan Aßmus 
begin(double x,double y,double step)154*e39da397SStephan Aßmus         iterator_x begin(double x, double y, double step) const
155*e39da397SStephan Aßmus         {
156*e39da397SStephan Aßmus             return iterator_x(x, y, step, m_mtx);
157*e39da397SStephan Aßmus         }
158*e39da397SStephan Aßmus 
15939241fe2SDarkWyrm     private:
16039241fe2SDarkWyrm         double m_mtx[4][2];
16139241fe2SDarkWyrm         bool   m_valid;
16239241fe2SDarkWyrm     };
16339241fe2SDarkWyrm 
16439241fe2SDarkWyrm }
16539241fe2SDarkWyrm 
16639241fe2SDarkWyrm #endif
167