btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / libs / agg / agg_trans_bilinear.h
blobf3ab596472583e16df818d0b8d4069f765942159
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 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 //----------------------------------------------------------------------------
16 // Bilinear 2D transformations
18 //----------------------------------------------------------------------------
19 #ifndef AGG_TRANS_BILINEAR_INCLUDED
20 #define AGG_TRANS_BILINEAR_INCLUDED
22 #include "agg_basics.h"
23 #include "agg_simul_eq.h"
25 namespace agg
28 //==========================================================trans_bilinear
29 class trans_bilinear
31 public:
32 //--------------------------------------------------------------------
33 trans_bilinear() : m_valid(false) {}
35 //--------------------------------------------------------------------
36 // Arbitrary quadrangle transformations
37 trans_bilinear(const double* src, const double* dst)
39 quad_to_quad(src, dst);
43 //--------------------------------------------------------------------
44 // Direct transformations
45 trans_bilinear(double x1, double y1, double x2, double y2,
46 const double* quad)
48 rect_to_quad(x1, y1, x2, y2, quad);
52 //--------------------------------------------------------------------
53 // Reverse transformations
54 trans_bilinear(const double* quad,
55 double x1, double y1, double x2, double y2)
57 quad_to_rect(quad, x1, y1, x2, y2);
61 //--------------------------------------------------------------------
62 // Set the transformations using two arbitrary quadrangles.
63 void quad_to_quad(const double* src, const double* dst)
65 double left[4][4];
66 double right[4][2];
68 unsigned i;
69 for(i = 0; i < 4; i++)
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];
78 right[i][0] = dst[ix];
79 right[i][1] = dst[iy];
81 m_valid = simul_eq<4, 2>::solve(left, right, m_mtx);
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)
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);
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)
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);
112 //--------------------------------------------------------------------
113 // Check if the equations were solved successfully
114 bool is_valid() const { return m_valid; }
116 //--------------------------------------------------------------------
117 // Transform a point (x, y)
118 void transform(double* x, double* y) const
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;
128 //--------------------------------------------------------------------
129 class iterator_x
131 double inc_x;
132 double inc_y;
134 public:
135 double x;
136 double y;
138 iterator_x() {}
139 iterator_x(double tx, double ty, double step, const double m[4][2]) :
140 inc_x(m[1][0] * step * ty + m[2][0] * step),
141 inc_y(m[1][1] * step * ty + m[2][1] * step),
142 x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty),
143 y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty)
147 void operator ++ ()
149 x += inc_x;
150 y += inc_y;
154 iterator_x begin(double x, double y, double step) const
156 return iterator_x(x, y, step, m_mtx);
159 private:
160 double m_mtx[4][2];
161 bool m_valid;
166 #endif