1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basegfx.hxx"
30 #include <osl/diagnose.h>
32 #include <basegfx/curve/b2dcubicbezier.hxx>
34 #include <basegfx/tools/debugplotter.hxx>
35 #include <boost/bind.hpp>
42 void outputHeader( const ::rtl::OString
& rTitle
,
43 ::std::ostream
* pStm
)
45 // output gnuplot setup
48 *pStm
<< "#!/usr/bin/gnuplot -persist" << ::std::endl
<<
50 "# automatically generated by basegfx, don't change!" << ::std::endl
<<
52 "# --- " << (const sal_Char
*)rTitle
<< " ---" << ::std::endl
<<
54 "set parametric" << ::std::endl
<<
55 "# set terminal postscript eps enhanced color " << ::std::endl
<<
56 "# set output \"plot.eps\"" << ::std::endl
<<
57 // This function plots a cubic bezier curve. P,q,r,s
58 // are the control point elements of the corresponding
59 // output coordinate component (i.e. x components for
60 // the x plot, and y components for the y plot)
61 "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
<<
62 // This function plots the derivative of a cubic
63 // bezier curve. P,q,r,s are the control point
64 // components of the _original_ curve
65 "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
<<
66 // Plot a line's component of a line between a and b
67 // (where a and b should be the corresponding
68 // components of the line's start and end point,
70 "line(p,q,r) = p*(1-t)+q*t" << ::std::endl
<<
71 // Plot a line's x component of a line in implicit
72 // form ax + by + c = 0
73 "implicitLineX(a,b,c,t) = a*-c + t*-b" << ::std::endl
<<
74 // Plot a line's y component of a line in implicit
75 // form ax + by + c = 0
76 "implicitLineY(a,b,c,t) = b*-c + t*a" << ::std::endl
<<
77 "pointmarkx(c,t) = c-0.03*t" << ::std::endl
<< // hack for displaying single points in parametric form
78 "pointmarky(c,t) = c+0.03*t" << ::std::endl
<< // hack for displaying single points in parametric form
79 "# end of setup" << ::std::endl
;
83 OSL_TRACE( "#!/usr/bin/gnuplot -persist\n",
85 "# automatically generated by basegfx, don't change!\n",
90 // This function plots a cubic bezier curve. P,q,r,s
91 // are the control point elements of the corresponding
92 // output coordinate component (i.e. x components for
93 // the x plot, and y components for the y plot)
94 "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",
95 // This function plots the derivative of a cubic
96 // bezier curve. P,q,r,s are the control point
97 // components of the _original_ curve
98 "cubicBezDerivative(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2\n",
99 // Plot a line's component of a line between a and b
100 // (where a and b should be the corresponding
101 // components of the line's start and end point,
103 "line(p,q,r) = p*(1-t)+q*t\n",
104 // Plot a line's x component of a line in implicit
105 // form ax + by + c = 0
106 "implicitLineX(a,b,c,t) = a*-c + t*-b\n",
107 // Plot a line's y component of a line in implicit
108 // form ax + by + c = 0
109 "implicitLineY(a,b,c,t) = b*-c + t*a\n",
110 "pointmarkx(c,t) = c-0.03*t\n", // hack for displaying single points in parametric form
111 "pointmarky(c,t) = c+0.03*t\n", // hack for displaying single points in parametric form
113 (const sal_Char
*)rTitle
);
120 Writer( ::std::ostream
* pStm
) :
125 void outputPoint( const ::std::pair
< B2DPoint
, ::rtl::OString
>& rElem
)
128 *mpStream
<< " " << rElem
.first
.getX() << "\t" << rElem
.first
.getY() << ::std::endl
;
130 OSL_TRACE( " %f\t%f\n", rElem
.first
.getX(), rElem
.first
.getY() );
133 void outputVector( const ::std::pair
< B2DVector
, ::rtl::OString
>& rElem
)
136 *mpStream
<< " " << rElem
.first
.getX() << "\t" << rElem
.first
.getY() << ::std::endl
<< ::std::endl
;
138 OSL_TRACE( " %f\t%f\n\n", rElem
.first
.getX(), rElem
.first
.getY() );
141 void outputRect( const ::std::pair
< B2DRange
, ::rtl::OString
>& rElem
)
143 const double nX0( rElem
.first
.getMinX() );
144 const double nY0( rElem
.first
.getMinY() );
145 const double nX1( rElem
.first
.getMaxX() );
146 const double nY1( rElem
.first
.getMaxY() );
150 << nX0
<< "\t" << nY0
<< "\t"
151 << nX1
<< "\t" << nY0
<< "\t"
152 << nX1
<< "\t" << nY1
<< "\t"
153 << nX0
<< "\t" << nY1
<< "\t"
154 << nX0
<< "\t" << nY0
<< ::std::endl
<< ::std::endl
;
157 OSL_TRACE( " %f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n\n",
166 ::std::ostream
* mpStream
;
170 DebugPlotter::DebugPlotter( const sal_Char
* pTitle
) :
180 DebugPlotter::DebugPlotter( const sal_Char
* pTitle
,
181 ::std::ostream
& rOutputStream
) :
187 mpOutputStream(&rOutputStream
)
191 DebugPlotter::~DebugPlotter()
193 const bool bHavePoints( !maPoints
.empty() );
194 const bool bHaveVectors( !maVectors
.empty() );
195 const bool bHaveRanges( !maRanges
.empty() );
196 const bool bHavePolygons( !maPolygons
.empty() );
203 outputHeader( maTitle
, mpOutputStream
);
205 print( "\n\n# parametric primitive output\n"
206 "plot [t=0:1] \\\n" );
208 // output plot declarations for used entities
209 bool bNeedColon( false );
212 print( " '-' using ($1):($2) title \"Points\" with points" );
220 print( " '-' using ($1):($2) title \"Vectors\" with lp" );
228 print( " '-' using ($1):($2) title \"Ranges\" with lines" );
233 const ::std::size_t nSize( maPolygons
.size() );
234 for( ::std::size_t i
=0; i
<nSize
; ++i
)
236 if( maPolygons
.at(i
).first
.areControlPointsUsed() )
238 const B2DPolygon
& rCurrPoly( maPolygons
.at(i
).first
);
240 const sal_uInt32
nCount( rCurrPoly
.count() );
241 for( sal_uInt32 k
=0; k
<nCount
; ++k
)
246 const B2DPoint
& rP0( rCurrPoly
.getB2DPoint(k
) );
247 const B2DPoint
& rP1( rCurrPoly
.getNextControlPoint(k
) );
248 const B2DPoint
& rP2( rCurrPoly
.getPrevControlPoint((k
+ 1) % nCount
) );
249 const B2DPoint
& rP3( k
+1<nCount
? rCurrPoly
.getB2DPoint(k
+1) : rCurrPoly
.getB2DPoint(k
) );
252 *mpOutputStream
<< " cubicBezier("
256 << rP3
.getX() << ",t), \\\n cubicBezier("
260 << rP3
.getY() << ",t)";
262 OSL_TRACE( " cubicBezier(%f,%f,%f,%f,t), \\\n"
263 " cubicBezier(%f,%f,%f,%f,t)",
282 *mpOutputStream
<< " '-' using ($1):($2) title \"Polygon "
283 << (const sal_Char
*)maPolygons
.at(i
).second
<< "\" with lp";
285 OSL_TRACE( " '-' using ($1):($2) title \"Polygon %s\" with lp",
286 (const sal_Char
*)maPolygons
.at(i
).second
);
295 Writer
aWriter( mpOutputStream
);
297 ::std::for_each( maPoints
.begin(),
299 ::boost::bind( &Writer::outputPoint
,
300 ::boost::ref( aWriter
),
307 Writer
aWriter( mpOutputStream
);
309 ::std::for_each( maVectors
.begin(),
311 ::boost::bind( &Writer::outputVector
,
312 ::boost::ref( aWriter
),
319 Writer
aWriter( mpOutputStream
);
321 ::std::for_each( maRanges
.begin(),
323 ::boost::bind( &Writer::outputRect
,
324 ::boost::ref( aWriter
),
331 const ::std::size_t nSize( maPolygons
.size() );
332 for( ::std::size_t i
=0; i
<nSize
; ++i
)
334 if( !maPolygons
.at(i
).first
.areControlPointsUsed() )
336 const B2DPolygon
& rCurrPoly( maPolygons
.at(i
).first
);
338 const sal_uInt32
nCount( rCurrPoly
.count() );
339 for( sal_uInt32 k
=0; k
<nCount
; ++k
)
341 const B2DPoint
& rP( rCurrPoly
.getB2DPoint(k
) );
344 *mpOutputStream
<< " " << rP
.getX() << "," << rP
.getY();
358 void DebugPlotter::plot( const B2DPoint
& rPoint
,
359 const sal_Char
* pTitle
)
361 maPoints
.push_back( ::std::make_pair( rPoint
,
362 ::rtl::OString( pTitle
) ) );
365 void DebugPlotter::plot( const B2DVector
& rVec
,
366 const sal_Char
* pTitle
)
368 maVectors
.push_back( ::std::make_pair( rVec
,
369 ::rtl::OString( pTitle
) ) );
372 void DebugPlotter::plot( const B2DCubicBezier
& rBezier
,
373 const sal_Char
* pTitle
)
376 aPoly
.append(rBezier
.getStartPoint());
377 aPoly
.appendBezierSegment(rBezier
.getControlPointA(), rBezier
.getControlPointB(), rBezier
.getEndPoint());
378 maPolygons
.push_back( ::std::make_pair( aPoly
,
379 ::rtl::OString( pTitle
) ) );
382 void DebugPlotter::plot( const B2DRange
& rRange
,
383 const sal_Char
* pTitle
)
385 maRanges
.push_back( ::std::make_pair( rRange
,
386 ::rtl::OString( pTitle
) ) );
389 void DebugPlotter::plot( const B2DPolygon
& rPoly
,
390 const sal_Char
* pTitle
)
392 maPolygons
.push_back( ::std::make_pair( rPoly
,
393 ::rtl::OString( pTitle
) ) );
396 void DebugPlotter::plot( const B2DPolyPolygon
& rPoly
,
397 const sal_Char
* pTitle
)
399 const ::rtl::OString
aTitle( pTitle
);
400 const sal_uInt32
nCount( rPoly
.count() );
401 for( sal_uInt32 i
=0; i
<nCount
; ++i
)
402 maPolygons
.push_back( ::std::make_pair( rPoly
.getB2DPolygon( i
),
406 void DebugPlotter::print( const sal_Char
* pStr
)
409 *mpOutputStream
<< pStr
;