1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: snakewipe.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 #include <canvas/debug.hxx>
35 #include <basegfx/matrix/b2dhommatrix.hxx>
36 #include <basegfx/point/b2dpoint.hxx>
37 #include <basegfx/polygon/b2dpolygon.hxx>
38 #include "snakewipe.hxx"
39 #include "transitiontools.hxx"
45 SnakeWipe::SnakeWipe( sal_Int32 nElements
, bool diagonal
, bool flipOnYAxis
)
46 : m_sqrtElements( static_cast<sal_Int32
>(
47 sqrt( static_cast<double>(nElements
) ) ) ),
48 m_elementEdge( 1.0 / m_sqrtElements
),
50 m_flipOnYAxis(flipOnYAxis
)
54 ::basegfx::B2DPolyPolygon
SnakeWipe::calcSnake( double t
) const
56 ::basegfx::B2DPolyPolygon res
;
57 const double area
= (t
* m_sqrtElements
* m_sqrtElements
);
58 const sal_Int32 line_
= (static_cast<sal_Int32
>(area
) / m_sqrtElements
);
59 const double line
= ::basegfx::pruneScaleValue(
60 static_cast<double>(line_
) / m_sqrtElements
);
61 const double col
= ::basegfx::pruneScaleValue(
62 (area
- (line_
* m_sqrtElements
)) / m_sqrtElements
);
64 if (! ::basegfx::fTools::equalZero( line
)) {
65 ::basegfx::B2DPolygon poly
;
66 poly
.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
67 poly
.append( ::basegfx::B2DPoint( 0.0, line
) );
68 poly
.append( ::basegfx::B2DPoint( 1.0, line
) );
69 poly
.append( ::basegfx::B2DPoint( 1.0, 0.0 ) );
73 if (! ::basegfx::fTools::equalZero( col
))
76 if ((line_
& 1) == 1) {
77 // odd line: => right to left
80 ::basegfx::B2DPolygon poly
;
81 poly
.append( ::basegfx::B2DPoint( offset
, line
) );
82 poly
.append( ::basegfx::B2DPoint( offset
,
83 line
+ m_elementEdge
) );
84 poly
.append( ::basegfx::B2DPoint( offset
+ col
,
85 line
+ m_elementEdge
) );
86 poly
.append( ::basegfx::B2DPoint( offset
+ col
, line
) );
94 ::basegfx::B2DPolyPolygon
SnakeWipe::calcHalfDiagonalSnake(
95 double t
, bool in
) const
97 ::basegfx::B2DPolyPolygon res
;
100 const double sqrtArea2
= sqrt( t
* m_sqrtElements
* m_sqrtElements
);
101 const double edge
= ::basegfx::pruneScaleValue(
102 static_cast<double>( static_cast<sal_Int32
>(sqrtArea2
) ) /
105 ::basegfx::B2DPolygon poly
;
106 if (! ::basegfx::fTools::equalZero( edge
)) {
107 poly
.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
108 poly
.append( ::basegfx::B2DPoint( 0.0, edge
) );
109 poly
.append( ::basegfx::B2DPoint( edge
, 0.0 ) );
110 poly
.setClosed(true);
113 const double a
= (M_SQRT1_2
/ m_sqrtElements
);
114 const double d
= (sqrtArea2
- static_cast<sal_Int32
>(sqrtArea2
));
115 const double len
= (t
* M_SQRT2
* d
);
116 const double height
= ::basegfx::pruneScaleValue( M_SQRT1_2
/ m_sqrtElements
);
118 poly
.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
119 poly
.append( ::basegfx::B2DPoint( 0.0, height
) );
120 poly
.append( ::basegfx::B2DPoint( len
+ a
, height
) );
121 poly
.append( ::basegfx::B2DPoint( len
+ a
, 0.0 ) );
122 poly
.setClosed(true);
123 ::basegfx::B2DHomMatrix aTransform
;
124 if ((static_cast<sal_Int32
>(sqrtArea2
) & 1) == 1) {
126 aTransform
.rotate( M_PI_2
+ M_PI_4
);
127 aTransform
.translate( edge
+ m_elementEdge
, 0.0 );
130 aTransform
.translate( -a
, 0.0 );
131 aTransform
.rotate( -M_PI_4
);
132 aTransform
.translate( 0.0, edge
);
134 poly
.transform( aTransform
);
139 const double sqrtArea2
= sqrt( t
* m_sqrtElements
* m_sqrtElements
);
140 const double edge
= ::basegfx::pruneScaleValue(
141 static_cast<double>( static_cast<sal_Int32
>(sqrtArea2
) ) /
144 ::basegfx::B2DPolygon poly
;
145 if (! ::basegfx::fTools::equalZero( edge
)) {
146 poly
.append( ::basegfx::B2DPoint( 0.0, 1.0 ) );
147 poly
.append( ::basegfx::B2DPoint( edge
, 1.0 ) );
148 poly
.append( ::basegfx::B2DPoint( 1.0, edge
) );
149 poly
.append( ::basegfx::B2DPoint( 1.0, 0.0 ) );
150 poly
.setClosed(true);
153 const double a
= (M_SQRT1_2
/ m_sqrtElements
);
154 const double d
= (sqrtArea2
- static_cast<sal_Int32
>(sqrtArea2
));
155 const double len
= ((1.0 - t
) * M_SQRT2
* d
);
156 const double height
= ::basegfx::pruneScaleValue( M_SQRT1_2
/ m_sqrtElements
);
158 poly
.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
159 poly
.append( ::basegfx::B2DPoint( 0.0, height
) );
160 poly
.append( ::basegfx::B2DPoint( len
+ a
, height
) );
161 poly
.append( ::basegfx::B2DPoint( len
+ a
, 0.0 ) );
162 poly
.setClosed(true);
163 ::basegfx::B2DHomMatrix aTransform
;
164 if ((static_cast<sal_Int32
>(sqrtArea2
) & 1) == 1) {
166 aTransform
.translate( 0.0, -height
);
167 aTransform
.rotate( M_PI_2
+ M_PI_4
);
168 aTransform
.translate( 1.0, edge
);
171 aTransform
.rotate( -M_PI_4
);
172 aTransform
.translate( edge
, 1.0 );
174 poly
.transform( aTransform
);
181 ::basegfx::B2DPolyPolygon
SnakeWipe::operator () ( double t
)
183 ::basegfx::B2DPolyPolygon res
;
187 res
.append( calcHalfDiagonalSnake( 1.0, true ) );
188 res
.append( calcHalfDiagonalSnake( 2.0 * (t
- 0.5), false ) );
191 res
.append( calcHalfDiagonalSnake( 2.0 * t
, true ) );
196 return m_flipOnYAxis
? flipOnYAxis(res
) : res
;
199 ::basegfx::B2DPolyPolygon
ParallelSnakesWipe::operator () ( double t
)
201 ::basegfx::B2DPolyPolygon res
;
204 OSL_ASSERT( m_opposite
);
205 ::basegfx::B2DPolyPolygon
half(
206 calcHalfDiagonalSnake( t
, false /* out */ ) );
207 // flip on x axis and rotate 90 degrees:
208 ::basegfx::B2DHomMatrix aTransform
;
209 aTransform
.scale( 1.0, -1.0 );
210 aTransform
.translate( -0.5, 0.5 );
211 aTransform
.rotate( M_PI_2
);
212 aTransform
.translate( 0.5, 0.5 );
213 half
.transform( aTransform
);
216 // rotate 180 degrees:
217 aTransform
.identity();
218 aTransform
.translate( -0.5, -0.5 );
219 aTransform
.rotate( M_PI
);
220 aTransform
.translate( 0.5, 0.5 );
221 half
.transform( aTransform
);
226 ::basegfx::B2DPolyPolygon
half( calcSnake( t
/ 2.0 ) );
227 // rotate 90 degrees:
228 ::basegfx::B2DHomMatrix aTransform
;
229 aTransform
.translate( -0.5, -0.5 );
230 aTransform
.rotate( M_PI_2
);
231 aTransform
.translate( 0.5, 0.5 );
232 half
.transform( aTransform
);
233 res
.append( flipOnYAxis(half
) );
234 res
.append( m_opposite
? flipOnXAxis(half
) : half
);
237 return m_flipOnYAxis
? flipOnYAxis(res
) : res
;