xref: /aoo41x/main/basegfx/test/testtools.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_basegfx.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "testtools.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
34*cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx>
35*cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
36*cdf0e10cSrcweir #include <basegfx/curve/b2dcubicbezier.hxx>
37*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
38*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #include <algorithm>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir namespace basegfx
44*cdf0e10cSrcweir {
45*cdf0e10cSrcweir     namespace testtools
46*cdf0e10cSrcweir     {
47*cdf0e10cSrcweir         Plotter::Plotter( ::std::ostream& rOutputStream ) :
48*cdf0e10cSrcweir             mrOutputStream(rOutputStream),
49*cdf0e10cSrcweir             maPoints(),
50*cdf0e10cSrcweir             mbFirstElement( true )
51*cdf0e10cSrcweir         {
52*cdf0e10cSrcweir             // output gnuplot setup. We switch gnuplot to parametric
53*cdf0e10cSrcweir             // mode, therefore every plot has at least _two_
54*cdf0e10cSrcweir             // functions: one for the x and one for the y value, both
55*cdf0e10cSrcweir             // depending on t.
56*cdf0e10cSrcweir             mrOutputStream << "#!/usr/bin/gnuplot -persist" << ::std::endl
57*cdf0e10cSrcweir                            << "#" << ::std::endl
58*cdf0e10cSrcweir                            << "# automatically generated by basegfx::testtools::Plotter, don't change!" << ::std::endl
59*cdf0e10cSrcweir                            << "#" << ::std::endl
60*cdf0e10cSrcweir                            << "set parametric" << ::std::endl
61*cdf0e10cSrcweir                 // This function plots a cubic bezier curve. P,q,r,s
62*cdf0e10cSrcweir                 // are the control point elements of the corresponding
63*cdf0e10cSrcweir                 // output coordinate component (i.e. x components for
64*cdf0e10cSrcweir                 // the x plot, and y components for the y plot)
65*cdf0e10cSrcweir                            << "cubicBezier(p,q,r,s,t) = p*(1-t)**3+q*3*(1-t)**2*t+r*3*(1-t)*t**2+s*t**3" << ::std::endl
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir                 // This function plots the derivative of a cubic
68*cdf0e10cSrcweir                 // bezier curve. P,q,r,s are the control point
69*cdf0e10cSrcweir                 // components of the _original_ curve
70*cdf0e10cSrcweir                            << "cubicBezDerivative(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2" << ::std::endl
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir                 // Plot a line's x component of a line in implicit
73*cdf0e10cSrcweir                 // form ax + by + c = 0
74*cdf0e10cSrcweir                            << "implicitLineX(a,b,c,t) = a*-c + t*-b" << ::std::endl
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir                 // Plot a line's y component of a line in implicit
77*cdf0e10cSrcweir                 // form ax + by + c = 0
78*cdf0e10cSrcweir                            << "implicitLineY(a,b,c,t) = b*-c + t*a" << ::std::endl
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir                 // Plot a line's component of a line between a and b
81*cdf0e10cSrcweir                 // (where a and b should be the corresponding
82*cdf0e10cSrcweir                 // components of the line's start and end point,
83*cdf0e10cSrcweir                 // respectively)
84*cdf0e10cSrcweir                            << "line(a,b,t) = a*(1-t) + b*t" << ::std::endl << ::std::endl
85*cdf0e10cSrcweir                            << "# end of setup" << ::std::endl << ::std::endl
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir                 // Start the actual plot line
88*cdf0e10cSrcweir                            << "plot [t=0:1] ";
89*cdf0e10cSrcweir         }
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir         namespace
92*cdf0e10cSrcweir         {
93*cdf0e10cSrcweir             class PointWriter
94*cdf0e10cSrcweir             {
95*cdf0e10cSrcweir             public:
96*cdf0e10cSrcweir                 PointWriter( ::std::ostream& rOutputStream ) :
97*cdf0e10cSrcweir                     mrOutputStream( rOutputStream )
98*cdf0e10cSrcweir                 {
99*cdf0e10cSrcweir                 }
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir                 void operator()( const B2DPoint& rPoint ) const
102*cdf0e10cSrcweir                 {
103*cdf0e10cSrcweir                     mrOutputStream << rPoint.getX() << "\t" << rPoint.getY() << ::std::endl;
104*cdf0e10cSrcweir                     mrOutputStream << "e" << ::std::endl;
105*cdf0e10cSrcweir                 }
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir             private:
108*cdf0e10cSrcweir                 ::std::ostream& 	mrOutputStream;
109*cdf0e10cSrcweir             };
110*cdf0e10cSrcweir         }
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir         Plotter::~Plotter()
113*cdf0e10cSrcweir         {
114*cdf0e10cSrcweir             // End the plot line
115*cdf0e10cSrcweir             mrOutputStream << ::std::endl;
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir             // write stored data points. Cannot write before, since
118*cdf0e10cSrcweir             // this is an inline dataset, which must be after the plot <...>
119*cdf0e10cSrcweir             // line
120*cdf0e10cSrcweir             ::std::for_each( maPoints.begin(), maPoints.end(), PointWriter(mrOutputStream) );
121*cdf0e10cSrcweir         }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir         void Plotter::plot( const B2DPolygon& rPoly )
124*cdf0e10cSrcweir         {
125*cdf0e10cSrcweir             const sal_uInt32 pointCount( rPoly.count() );
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir             if( pointCount < 1 )
128*cdf0e10cSrcweir                 return;
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir             if( pointCount == 1 )
131*cdf0e10cSrcweir             {
132*cdf0e10cSrcweir                 plot( rPoly.getB2DPoint(0) );
133*cdf0e10cSrcweir                 return;
134*cdf0e10cSrcweir             }
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir             sal_uInt32 i;
137*cdf0e10cSrcweir             for( i=0; i<pointCount-1; ++i )
138*cdf0e10cSrcweir             {
139*cdf0e10cSrcweir                 if(rPoly.isNextControlPointUsed(i) || rPoly.isPrevControlPointUsed(i + 1))
140*cdf0e10cSrcweir                 {
141*cdf0e10cSrcweir 					const B2DCubicBezier aBezierPlot(
142*cdf0e10cSrcweir 						rPoly.getB2DPoint(i), rPoly.getNextControlPoint(i),
143*cdf0e10cSrcweir 						rPoly.getPrevControlPoint(i + 1), rPoly.getB2DPoint(i + 1));
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir 					plot(aBezierPlot);
146*cdf0e10cSrcweir                 }
147*cdf0e10cSrcweir                 else
148*cdf0e10cSrcweir                 {
149*cdf0e10cSrcweir                     plot( rPoly.getB2DPoint(i), rPoly.getB2DPoint(i+1) );
150*cdf0e10cSrcweir                 }
151*cdf0e10cSrcweir             }
152*cdf0e10cSrcweir         }
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir         void Plotter::plot( const B2DPolyPolygon& rPolyPoly )
155*cdf0e10cSrcweir         {
156*cdf0e10cSrcweir             const sal_uInt32 nPolyCount( rPolyPoly.count() );
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir             sal_uInt32 i;
159*cdf0e10cSrcweir             for( i=0; i<nPolyCount; ++i )
160*cdf0e10cSrcweir             {
161*cdf0e10cSrcweir                 plot( rPolyPoly.getB2DPolygon(i) );
162*cdf0e10cSrcweir             }
163*cdf0e10cSrcweir         }
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir         void Plotter::plot( const B2DPoint& rPoint )
166*cdf0e10cSrcweir         {
167*cdf0e10cSrcweir             maPoints.push_back( rPoint );
168*cdf0e10cSrcweir             writeSeparator();
169*cdf0e10cSrcweir             mrOutputStream << "'-' using ($1):($2) title \"Point " << maPoints.size() << "\" with points";
170*cdf0e10cSrcweir         }
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir         void Plotter::plot( const B2DRange& rRect )
173*cdf0e10cSrcweir         {
174*cdf0e10cSrcweir             // TODO: do that also as a data file plot. maPoints must
175*cdf0e10cSrcweir             // then become polymorph, but WTF.
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir             // decompose into four lines
178*cdf0e10cSrcweir             plot( B2DPoint(rRect.getMinX(),
179*cdf0e10cSrcweir                            rRect.getMinY()),
180*cdf0e10cSrcweir                   B2DPoint(rRect.getMaxX(),
181*cdf0e10cSrcweir                            rRect.getMinY()) );
182*cdf0e10cSrcweir             plot( B2DPoint(rRect.getMaxX(),
183*cdf0e10cSrcweir                            rRect.getMinY()),
184*cdf0e10cSrcweir                   B2DPoint(rRect.getMaxX(),
185*cdf0e10cSrcweir                            rRect.getMaxY()) );
186*cdf0e10cSrcweir             plot( B2DPoint(rRect.getMaxX(),
187*cdf0e10cSrcweir                            rRect.getMaxY()),
188*cdf0e10cSrcweir                   B2DPoint(rRect.getMinX(),
189*cdf0e10cSrcweir                            rRect.getMaxY()) );
190*cdf0e10cSrcweir             plot( B2DPoint(rRect.getMinX(),
191*cdf0e10cSrcweir                            rRect.getMaxY()),
192*cdf0e10cSrcweir                   B2DPoint(rRect.getMinX(),
193*cdf0e10cSrcweir                            rRect.getMinY()) );
194*cdf0e10cSrcweir         }
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir         void Plotter::plot( const B2DPoint& rStartPoint, const B2DPoint& rEndPoint )
197*cdf0e10cSrcweir         {
198*cdf0e10cSrcweir             writeSeparator();
199*cdf0e10cSrcweir             mrOutputStream << "line(" << rStartPoint.getX()
200*cdf0e10cSrcweir                            << "," << rEndPoint.getX()
201*cdf0e10cSrcweir                            << ",t), "
202*cdf0e10cSrcweir                            << "line(" << rStartPoint.getY()
203*cdf0e10cSrcweir                            << "," << rEndPoint.getY()
204*cdf0e10cSrcweir                            << ",t)";
205*cdf0e10cSrcweir         }
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir         void Plotter::plot( const B2DCubicBezier& rCurve )
208*cdf0e10cSrcweir         {
209*cdf0e10cSrcweir             writeSeparator();
210*cdf0e10cSrcweir             mrOutputStream << "cubicBezier(" << rCurve.getStartPoint().getX()
211*cdf0e10cSrcweir                            << "," << rCurve.getControlPointA().getX()
212*cdf0e10cSrcweir                            << "," << rCurve.getControlPointB().getX()
213*cdf0e10cSrcweir                            << "," << rCurve.getEndPoint().getX()
214*cdf0e10cSrcweir                            << ",t), "
215*cdf0e10cSrcweir                            << "cubicBezier(" << rCurve.getStartPoint().getY()
216*cdf0e10cSrcweir                            << "," << rCurve.getControlPointA().getY()
217*cdf0e10cSrcweir                            << "," << rCurve.getControlPointB().getY()
218*cdf0e10cSrcweir                            << "," << rCurve.getEndPoint().getY()
219*cdf0e10cSrcweir                            << ",t)";
220*cdf0e10cSrcweir         }
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir         void Plotter::writeSeparator()
223*cdf0e10cSrcweir         {
224*cdf0e10cSrcweir             if( mbFirstElement )
225*cdf0e10cSrcweir             {
226*cdf0e10cSrcweir                 mbFirstElement = false;
227*cdf0e10cSrcweir             }
228*cdf0e10cSrcweir             else
229*cdf0e10cSrcweir             {
230*cdf0e10cSrcweir                 mrOutputStream << ", ";
231*cdf0e10cSrcweir             }
232*cdf0e10cSrcweir         }
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir     }
235*cdf0e10cSrcweir }
236