33 #ifndef __INCLUDE_GEOMETRY__
34 #define __INCLUDE_GEOMETRY__
36 #ifndef __INCLUDE_MIST_MATRIX__
40 #ifndef __INCLUDE_MIST_NUMERIC__
44 #ifndef __INCLUDE_MIST_VECTOR__
55 template<
class T,
class Allocator >
59 mat = matrix_type::_33(
70 template<
class T,
class Allocator >
74 mat = matrix_type::_33(
75 cos( radian ), -sin( radian ), 0.0,
76 sin( radian ), cos( radian ), 0.0,
87 template<
class T,
class Allocator >
91 mat = matrix_type::_33(
96 mat *= matrix_type::_33(
97 cos( radian ), -sin( radian ), 0.0,
98 sin( radian ), cos( radian ), 0.0,
101 mat *= matrix_type::_33(
112 template<
class T,
class Allocator >
116 mat = matrix_type::_33(
128 template<
class T,
class Allocator >
131 if( p1.
rows() != 2 || p1.
cols() != 4 ||
134 throw( numerical_exception( 1,
"Incorrect input matrix size is specified." ) );
140 matrix_type tm( 8, 9 );
142 for(
int i = 0 ; i < 4 ; ++i )
144 tm( i * 2 + 0, 0 ) = 0;
145 tm( i * 2 + 0, 1 ) = 0;
146 tm( i * 2 + 0, 2 ) = 0;
147 tm( i * 2 + 0, 3 ) = - w * p1( 0, i );
148 tm( i * 2 + 0, 4 ) = - w * p1( 1, i );
149 tm( i * 2 + 0, 5 ) = -w;
150 tm( i * 2 + 0, 6 ) = p2( 1, i ) * p1( 0, i );
151 tm( i * 2 + 0, 7 ) = p2( 1, i ) * p1( 1, i );
152 tm( i * 2 + 0, 8 ) = p2( 1, i ) * w;
154 tm( i * 2 + 1, 0 ) = w * p1( 0, i );
155 tm( i * 2 + 1, 1 ) = w * p1( 1, i );
156 tm( i * 2 + 1, 2 ) = w;
157 tm( i * 2 + 1, 3 ) = 0;
158 tm( i * 2 + 1, 4 ) = 0;
159 tm( i * 2 + 1, 5 ) = 0;
160 tm( i * 2 + 1, 6 ) = -p2( 0, i ) * p1( 0, i );
161 tm( i * 2 + 1, 7 ) = -p2( 0, i ) * p1( 1, i );
162 tm( i * 2 + 1, 8 ) = -p2( 0, i ) * w;
166 matrix_type u, s, vt;
171 w = 1.0 / vt( 8, 8 );
172 mat( 0, 0 ) = vt( 8, 0 ) * w;
173 mat( 0, 1 ) = vt( 8, 1 ) * w;
174 mat( 0, 2 ) = vt( 8, 2 ) * w;
176 mat( 1, 0 ) = vt( 8, 3 ) * w;
177 mat( 1, 1 ) = vt( 8, 4 ) * w;
178 mat( 1, 2 ) = vt( 8, 5 ) * w;
180 mat( 2, 0 ) = vt( 8, 6 ) * w;
181 mat( 2, 1 ) = vt( 8, 7 ) * w;
182 mat( 2, 2 ) = vt( 8, 8 ) * w;
189 template<
class T,
class Allocator >
190 void transform_point(
int sx,
int sy,
double &dx,
double &dy,
const matrix< T, Allocator > &mat )
192 dx = ( mat( 0, 0 ) * sx + mat( 0, 1 ) * sy + mat( 0, 2 ) ) / ( mat( 2, 0 ) * sx + mat( 2, 1 ) * sy + mat( 2, 2 ) );
193 dy = ( mat( 1, 0 ) * sx + mat( 1, 1 ) * sy + mat( 1, 2 ) ) / ( mat( 2, 0 ) * sx + mat( 2, 1 ) * sy + mat( 2, 2 ) );
196 template<
class T,
class Allocator >
197 void clipping(
int sx0,
int sy0,
int sx1,
int sy1,
198 int &dx0,
int &dy0,
int &dx1,
int &dy1,
199 const matrix< T, Allocator > &mat )
201 double tx[ 4 ], ty[ 4 ];
202 transform_point( sx0, sy0, tx[ 0 ], ty[ 0 ], mat );
203 transform_point( sx1, sy0, tx[ 1 ], ty[ 1 ], mat );
204 transform_point( sx0, sy1, tx[ 2 ], ty[ 2 ], mat );
205 transform_point( sx1, sy1, tx[ 3 ], ty[ 3 ], mat );
211 for(
int i = 0 ; i < 4 ; ++i )
213 dx0 = ( dx0 < static_cast< int >( tx[ i ] ) ) ? dx0 :
static_cast< int >( tx[ i ] );
214 dx1 = ( dx1 >
static_cast< int >( tx[ i ] ) ) ? dx1 :
static_cast< int >( tx[ i ] );
215 dy0 = ( dy0 < static_cast< int >( ty[ i ] ) ) ? dy0 :
static_cast< int >( ty[ i ] );
216 dy1 = ( dy1 >
static_cast< int >( ty[ i ] ) ) ? dy1 :
static_cast< int >( ty[ i ] );
228 template<
class T1,
class Allocator1,
class T2,
class Allocator2 >
233 int w =
static_cast< int >( out.
width() );
234 int h =
static_cast< int >( out.
height() );
235 int iw =
static_cast< int >( in.
width( ) );
236 int ih =
static_cast< int >( in.
height( ) );
238 int dx0, dy0, dx1, dy1;
239 detail::clipping( 0, 0, iw, ih, dx0, dy0, dx1, dy1, mat );
242 for(
int y = 0 ; y < h ; ++y )
245 for(
int x = 0 ; x < w ; ++x )
248 detail::transform_point( x, y, sx, sy, m );
249 int ix =
static_cast< int >( sx );
250 int iy =
static_cast< int >( sy );
252 if( 0 <= ix && ix < iw && 0 <= iy && iy < ih )
254 out( x, y ) = in( ix, iy );
268 template<
class T1,
class Allocator1,
class T2,
class Allocator2 >
273 int w =
static_cast< int >( out.
width( ) );
274 int h =
static_cast< int >( out.
height( ) );
275 int iw =
static_cast< int >( in.
width( ) );
276 int ih =
static_cast< int >( in.
height( ) );
278 int dx0, dy0, dx1, dy1;
279 detail::clipping( 0, 0, iw, ih, dx0, dy0, dx1, dy1, mat );
281 #pragma omp parallel for schedule( guided )
282 for(
int y = 0 ; y < h ; ++y )
285 for(
int x = 0 ; x < w ; ++x )
289 detail::transform_point( x, y, sx, sy, m );
291 int ix =
static_cast< int >( sx );
292 int iy =
static_cast< int >( sy );
296 if( 0 <= ix && ix < iw - 1 && 0 <= iy && iy < ih - 1 )
299 value_type tmp = in( ix, iy ) * ( 1.0 - dx ) * ( 1.0 - dy )
300 + in( ix + 1, iy ) * dx * ( 1.0 - dy )
301 + in( ix, iy + 1 ) * ( 1.0 - dx ) * dy
302 + in( ix + 1, iy + 1 ) * dx * dy;
319 template<
class Value_type1,
class Allocator1,
class Value_type2,
class Allocator2 >
325 #pragma omp parallel for schedule( guided )
326 for(
int y = 0 ; y < static_cast< int >(out.
height()) ; y++ )
328 size_t ii[ 4 ], jj[ 4 ];
329 double fy = y / factor.
y - delta_y;
334 else if( fy > static_cast< int >(in.
height()) - 1 )
339 jj[ 1 ] =
static_cast< size_t >( fy );
340 jj[ 2 ] = jj[ 1 ] < in.
height() - 1 ? jj[ 1 ] + 1 : jj[ 1 ];
342 for(
size_t x = 0 ; x < out.
width() ; x++ )
344 double fx = x / factor.x - delta_x;
350 else if( fx > in.
width() - 1 )
354 ii[ 1 ] =
static_cast< size_t >( fx );
355 ii[ 2 ] = ii[ 1 ] < in.
width() - 1 ? ii[ 1 ] + 1 : ii[ 1 ];
358 out( x, y ) = mist::__linear__::_linear_< is_color< Value_type2 >::value >::interpolate( in, ii[ 1 ], ii[ 2 ], jj[ 1 ], jj[ 2 ], 0, 0, fx, fy, 0 ) ;
371 template<
class T1,
class Allocator1,
class T2,
class Allocator2 >
376 int w =
static_cast< int >( out.
width( ) );
377 int h =
static_cast< int >( out.
height( ) );
378 int iw =
static_cast< int >( in.
width( ) );
379 int ih =
static_cast< int >( in.
height( ) );
381 int dx0, dy0, dx1, dy1;
382 detail::clipping( 0, 0, iw, ih, dx0, dy0, dx1, dy1, mat );
384 #pragma omp parallel for schedule( guided )
385 for(
int y = 0 ; y < h ; ++y )
388 size_t ii[ 4 ], jj[ 4 ], kk[ 4 ];
389 for(
int x = 0 ; x < w ; ++x )
393 detail::transform_point( x, y, sx, sy, m );
395 int ix =
static_cast< int >( sx );
396 int iy =
static_cast< int >( sy );
397 jj[ 1 ] =
static_cast< size_t >( sy );
398 jj[ 0 ] = jj[ 1 ] > 0 ? jj[ 1 ] - 1 : jj[ 1 ];
399 jj[ 2 ] = jj[ 1 ] < ih - 1 ? jj[ 1 ] + 1 : jj[ 1 ];
400 jj[ 3 ] = jj[ 2 ] < ih - 1 ? jj[ 2 ] + 1 : jj[ 2 ];
403 ii[ 1 ] =
static_cast< size_t >( sx );
404 ii[ 0 ] = ii[ 1 ] > 0 ? ii[ 1 ] - 1 : ii[ 1 ];
405 ii[ 2 ] = ii[ 1 ] < iw - 1 ? ii[ 1 ] + 1 : ii[ 1 ];
406 ii[ 3 ] = ii[ 2 ] < iw - 1 ? ii[ 2 ] + 1 : ii[ 2 ];
409 if( 0 <= ix && ix < iw && 0 <= iy && iy < ih )
411 out( x, y ) = mist::__cubic__::_cubic_< false >::interpolate( in, ii, jj, kk, sx, sy, 0 ) ;
427 template<
class Value_type1,
class Allocator1,
class Value_type2,
class Allocator2 >
432 #pragma omp parallel for schedule( guided )
433 for(
int y = 0 ; y < static_cast< int >(out.
height()) ; y++ )
435 size_t ii[ 4 ], jj[ 4 ], kk[ 4 ];
436 double fy = y / factor.
y - delta_y;
441 else if( fy > static_cast< int >(in.
height()) - 1 )
446 jj[ 1 ] =
static_cast< size_t >( fy );
447 jj[ 0 ] = jj[ 1 ] > 0 ? jj[ 1 ] - 1 : jj[ 1 ];
448 jj[ 2 ] = jj[ 1 ] < in.
height() - 1 ? jj[ 1 ] + 1 : jj[ 1 ];
449 jj[ 3 ] = jj[ 2 ] < in.
height() - 1 ? jj[ 2 ] + 1 : jj[ 2 ];
451 for(
size_t x = 0 ; x < out.
width() ; x++ )
453 double fx = x / factor.x - delta_x;
459 else if( fx > in.
width() - 1 )
463 ii[ 1 ] =
static_cast< size_t >( fx );
464 ii[ 0 ] = ii[ 1 ] > 0 ? ii[ 1 ] - 1 : ii[ 1 ];
465 ii[ 2 ] = ii[ 1 ] < in.
width() - 1 ? ii[ 1 ] + 1 : ii[ 1 ];
466 ii[ 3 ] = ii[ 2 ] < in.
width() - 1 ? ii[ 2 ] + 1 : ii[ 2 ];
469 out( x, y ) = mist::__cubic__::_cubic_< is_color< Value_type2 >::value >::interpolate( in, ii, jj, kk, fx, fy, 0 ) ;