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: debugplotter.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_basegfx.hxx"
33 #include <osl/diagnose.h>
35 #include <basegfx/curve/b2dcubicbezier.hxx>
37 #include <basegfx/tools/debugplotter.hxx>
38 #include <boost/bind.hpp>
45 void outputHeader( const ::rtl::OString
& rTitle
,
46 ::std::ostream
* pStm
)
48 // output gnuplot setup
51 *pStm
<< "#!/usr/bin/gnuplot -persist" << ::std::endl
<<
53 "# automatically generated by basegfx, don't change!" << ::std::endl
<<
55 "# --- " << (const sal_Char
*)rTitle
<< " ---" << ::std::endl
<<
57 "set parametric" << ::std::endl
<<
58 "# set terminal postscript eps enhanced color " << ::std::endl
<<
59 "# set output \"plot.eps\"" << ::std::endl
<<
60 // This function plots a cubic bezier curve. P,q,r,s
61 // are the control point elements of the corresponding
62 // output coordinate component (i.e. x components for
63 // the x plot, and y components for the y plot)
64 "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
<<
65 // This function plots the derivative of a cubic
66 // bezier curve. P,q,r,s are the control point
67 // components of the _original_ curve
68 "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
<<
69 // Plot a line's component of a line between a and b
70 // (where a and b should be the corresponding
71 // components of the line's start and end point,
73 "line(p,q,r) = p*(1-t)+q*t" << ::std::endl
<<
74 // Plot a line's x component of a line in implicit
75 // form ax + by + c = 0
76 "implicitLineX(a,b,c,t) = a*-c + t*-b" << ::std::endl
<<
77 // Plot a line's y component of a line in implicit
78 // form ax + by + c = 0
79 "implicitLineY(a,b,c,t) = b*-c + t*a" << ::std::endl
<<
80 "pointmarkx(c,t) = c-0.03*t" << ::std::endl
<< // hack for displaying single points in parametric form
81 "pointmarky(c,t) = c+0.03*t" << ::std::endl
<< // hack for displaying single points in parametric form
82 "# end of setup" << ::std::endl
;
86 OSL_TRACE( "#!/usr/bin/gnuplot -persist\n",
88 "# automatically generated by basegfx, don't change!\n",
93 // This function plots a cubic bezier curve. P,q,r,s
94 // are the control point elements of the corresponding
95 // output coordinate component (i.e. x components for
96 // the x plot, and y components for the y plot)
97 "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\n",
98 // This function plots the derivative of a cubic
99 // bezier curve. P,q,r,s are the control point
100 // components of the _original_ curve
101 "cubicBezDerivative(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2\n",
102 // Plot a line's component of a line between a and b
103 // (where a and b should be the corresponding
104 // components of the line's start and end point,
106 "line(p,q,r) = p*(1-t)+q*t\n",
107 // Plot a line's x component of a line in implicit
108 // form ax + by + c = 0
109 "implicitLineX(a,b,c,t) = a*-c + t*-b\n",
110 // Plot a line's y component of a line in implicit
111 // form ax + by + c = 0
112 "implicitLineY(a,b,c,t) = b*-c + t*a\n",
113 "pointmarkx(c,t) = c-0.03*t\n", // hack for displaying single points in parametric form
114 "pointmarky(c,t) = c+0.03*t\n", // hack for displaying single points in parametric form
116 (const sal_Char
*)rTitle
);
123 Writer( ::std::ostream
* pStm
) :
128 void outputPoint( const ::std::pair
< B2DPoint
, ::rtl::OString
>& rElem
)
131 *mpStream
<< " " << rElem
.first
.getX() << "\t" << rElem
.first
.getY() << ::std::endl
;
133 OSL_TRACE( " %f\t%f\n", rElem
.first
.getX(), rElem
.first
.getY() );
136 void outputVector( const ::std::pair
< B2DVector
, ::rtl::OString
>& rElem
)
139 *mpStream
<< " " << rElem
.first
.getX() << "\t" << rElem
.first
.getY() << ::std::endl
<< ::std::endl
;
141 OSL_TRACE( " %f\t%f\n\n", rElem
.first
.getX(), rElem
.first
.getY() );
144 void outputRect( const ::std::pair
< B2DRange
, ::rtl::OString
>& rElem
)
146 const double nX0( rElem
.first
.getMinX() );
147 const double nY0( rElem
.first
.getMinY() );
148 const double nX1( rElem
.first
.getMaxX() );
149 const double nY1( rElem
.first
.getMaxY() );
153 << nX0
<< "\t" << nY0
<< "\t"
154 << nX1
<< "\t" << nY0
<< "\t"
155 << nX1
<< "\t" << nY1
<< "\t"
156 << nX0
<< "\t" << nY1
<< "\t"
157 << nX0
<< "\t" << nY0
<< ::std::endl
<< ::std::endl
;
160 OSL_TRACE( " %f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n\n",
169 ::std::ostream
* mpStream
;
173 DebugPlotter::DebugPlotter( const sal_Char
* pTitle
) :
183 DebugPlotter::DebugPlotter( const sal_Char
* pTitle
,
184 ::std::ostream
& rOutputStream
) :
190 mpOutputStream(&rOutputStream
)
194 DebugPlotter::~DebugPlotter()
196 const bool bHavePoints( !maPoints
.empty() );
197 const bool bHaveVectors( !maVectors
.empty() );
198 const bool bHaveRanges( !maRanges
.empty() );
199 const bool bHavePolygons( !maPolygons
.empty() );
206 outputHeader( maTitle
, mpOutputStream
);
208 print( "\n\n# parametric primitive output\n"
209 "plot [t=0:1] \\\n" );
211 // output plot declarations for used entities
212 bool bNeedColon( false );
215 print( " '-' using ($1):($2) title \"Points\" with points" );
223 print( " '-' using ($1):($2) title \"Vectors\" with lp" );
231 print( " '-' using ($1):($2) title \"Ranges\" with lines" );
236 const ::std::size_t nSize( maPolygons
.size() );
237 for( ::std::size_t i
=0; i
<nSize
; ++i
)
239 if( maPolygons
.at(i
).first
.areControlPointsUsed() )
241 const B2DPolygon
& rCurrPoly( maPolygons
.at(i
).first
);
243 const sal_uInt32
nCount( rCurrPoly
.count() );
244 for( sal_uInt32 k
=0; k
<nCount
; ++k
)
249 const B2DPoint
& rP0( rCurrPoly
.getB2DPoint(k
) );
250 const B2DPoint
& rP1( rCurrPoly
.getNextControlPoint(k
) );
251 const B2DPoint
& rP2( rCurrPoly
.getPrevControlPoint((k
+ 1) % nCount
) );
252 const B2DPoint
& rP3( k
+1<nCount
? rCurrPoly
.getB2DPoint(k
+1) : rCurrPoly
.getB2DPoint(k
) );
255 *mpOutputStream
<< " cubicBezier("
259 << rP3
.getX() << ",t), \\\n cubicBezier("
263 << rP3
.getY() << ",t)";
265 OSL_TRACE( " cubicBezier(%f,%f,%f,%f,t), \\\n"
266 " cubicBezier(%f,%f,%f,%f,t)",
285 *mpOutputStream
<< " '-' using ($1):($2) title \"Polygon "
286 << (const sal_Char
*)maPolygons
.at(i
).second
<< "\" with lp";
288 OSL_TRACE( " '-' using ($1):($2) title \"Polygon %s\" with lp",
289 (const sal_Char
*)maPolygons
.at(i
).second
);
298 Writer
aWriter( mpOutputStream
);
300 ::std::for_each( maPoints
.begin(),
302 ::boost::bind( &Writer::outputPoint
,
303 ::boost::ref( aWriter
),
310 Writer
aWriter( mpOutputStream
);
312 ::std::for_each( maVectors
.begin(),
314 ::boost::bind( &Writer::outputVector
,
315 ::boost::ref( aWriter
),
322 Writer
aWriter( mpOutputStream
);
324 ::std::for_each( maRanges
.begin(),
326 ::boost::bind( &Writer::outputRect
,
327 ::boost::ref( aWriter
),
334 const ::std::size_t nSize( maPolygons
.size() );
335 for( ::std::size_t i
=0; i
<nSize
; ++i
)
337 if( !maPolygons
.at(i
).first
.areControlPointsUsed() )
339 const B2DPolygon
& rCurrPoly( maPolygons
.at(i
).first
);
341 const sal_uInt32
nCount( rCurrPoly
.count() );
342 for( sal_uInt32 k
=0; k
<nCount
; ++k
)
344 const B2DPoint
& rP( rCurrPoly
.getB2DPoint(k
) );
347 *mpOutputStream
<< " " << rP
.getX() << "," << rP
.getY();
361 void DebugPlotter::plot( const B2DPoint
& rPoint
,
362 const sal_Char
* pTitle
)
364 maPoints
.push_back( ::std::make_pair( rPoint
,
365 ::rtl::OString( pTitle
) ) );
368 void DebugPlotter::plot( const B2DVector
& rVec
,
369 const sal_Char
* pTitle
)
371 maVectors
.push_back( ::std::make_pair( rVec
,
372 ::rtl::OString( pTitle
) ) );
375 void DebugPlotter::plot( const B2DCubicBezier
& rBezier
,
376 const sal_Char
* pTitle
)
379 aPoly
.append(rBezier
.getStartPoint());
380 aPoly
.appendBezierSegment(rBezier
.getControlPointA(), rBezier
.getControlPointB(), rBezier
.getEndPoint());
381 maPolygons
.push_back( ::std::make_pair( aPoly
,
382 ::rtl::OString( pTitle
) ) );
385 void DebugPlotter::plot( const B2DRange
& rRange
,
386 const sal_Char
* pTitle
)
388 maRanges
.push_back( ::std::make_pair( rRange
,
389 ::rtl::OString( pTitle
) ) );
392 void DebugPlotter::plot( const B2DPolygon
& rPoly
,
393 const sal_Char
* pTitle
)
395 maPolygons
.push_back( ::std::make_pair( rPoly
,
396 ::rtl::OString( pTitle
) ) );
399 void DebugPlotter::plot( const B2DPolyPolygon
& rPoly
,
400 const sal_Char
* pTitle
)
402 const ::rtl::OString
aTitle( pTitle
);
403 const sal_uInt32
nCount( rPoly
.count() );
404 for( sal_uInt32 i
=0; i
<nCount
; ++i
)
405 maPolygons
.push_back( ::std::make_pair( rPoly
.getB2DPolygon( i
),
409 void DebugPlotter::print( const sal_Char
* pStr
)
412 *mpOutputStream
<< pStr
;