1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Perspective 2D transformations
18 //----------------------------------------------------------------------------
19 #ifndef AGG_TRANS_PERSPECTIVE_INCLUDED
20 #define AGG_TRANS_PERSPECTIVE_INCLUDED
22 #include "agg_basics.h"
23 #include "agg_simul_eq.h"
27 //=======================================================trans_perspective
28 class trans_perspective
31 //--------------------------------------------------------------------
32 trans_perspective() : m_valid(false) {}
35 //--------------------------------------------------------------------
36 // Arbitrary quadrangle transformations
37 trans_perspective(const double* src
, const double* dst
)
39 quad_to_quad(src
, dst
);
43 //--------------------------------------------------------------------
44 // Direct transformations
45 trans_perspective(double x1
, double y1
, double x2
, double y2
,
48 rect_to_quad(x1
, y1
, x2
, y2
, quad
);
52 //--------------------------------------------------------------------
53 // Reverse transformations
54 trans_perspective(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
)
70 for (i
= 0; i
< 4; i
++)
76 left
[ix
][1] = src
[ix
];
77 left
[ix
][2] = src
[iy
];
81 left
[ix
][6] = -src
[ix
] * dst
[ix
];
82 left
[ix
][7] = -src
[iy
] * dst
[ix
];
83 right
[ix
][0] = dst
[ix
];
89 left
[iy
][4] = src
[ix
];
90 left
[iy
][5] = src
[iy
];
91 left
[iy
][6] = -src
[ix
] * dst
[iy
];
92 left
[iy
][7] = -src
[iy
] * dst
[iy
];
93 right
[iy
][0] = dst
[iy
];
95 m_valid
= simul_eq
<8, 1>::solve(left
, right
, m_mtx
);
99 //--------------------------------------------------------------------
100 // Set the direct transformations, i.e., rectangle -> quadrangle
101 void rect_to_quad(double x1
, double y1
, double x2
, double y2
,
105 src
[0] = src
[6] = x1
;
106 src
[2] = src
[4] = x2
;
107 src
[1] = src
[3] = y1
;
108 src
[5] = src
[7] = y2
;
109 quad_to_quad(src
, quad
);
113 //--------------------------------------------------------------------
114 // Set the reverse transformations, i.e., quadrangle -> rectangle
115 void quad_to_rect(const double* quad
,
116 double x1
, double y1
, double x2
, double y2
)
119 dst
[0] = dst
[6] = x1
;
120 dst
[2] = dst
[4] = x2
;
121 dst
[1] = dst
[3] = y1
;
122 dst
[5] = dst
[7] = y2
;
123 quad_to_quad(quad
, dst
);
126 //--------------------------------------------------------------------
127 // Check if the equations were solved successfully
128 bool is_valid() const { return m_valid
; }
130 //--------------------------------------------------------------------
131 // Transform a point (x, y)
132 void transform(double* x
, double* y
) const
136 double d
= 1.0 / (m_mtx
[6][0] * tx
+ m_mtx
[7][0] * ty
+ 1.0);
137 *x
= (m_mtx
[0][0] + m_mtx
[1][0] * tx
+ m_mtx
[2][0] * ty
) * d
;
138 *y
= (m_mtx
[3][0] + m_mtx
[4][0] * tx
+ m_mtx
[5][0] * ty
) * d
;
141 //--------------------------------------------------------------------
156 iterator_x(double tx
, double ty
, double step
, const double m
[8][1]) :
157 den(m
[6][0] * tx
+ m
[7][0] * ty
+ 1.0),
158 den_step(m
[6][0] * step
),
159 nom_x(m
[0][0] + m
[1][0] * tx
+ m
[2][0] * ty
),
160 nom_x_step(m
[1][0] * step
),
161 nom_y(m
[3][0] + m
[4][0] * tx
+ m
[5][0] * ty
),
162 nom_y_step(m
[4][0] * step
),
173 double d
= 1.0 / den
;
179 //--------------------------------------------------------------------
180 iterator_x
begin(double x
, double y
, double step
) const
182 return iterator_x(x
, y
, step
, m_mtx
);