456 lines
19 KiB
C++
Executable File
456 lines
19 KiB
C++
Executable File
/*************************************************************************
|
|
*
|
|
* $RCSfile: debugplotter.cxx,v $
|
|
*
|
|
* $Revision: 1.3 $
|
|
*
|
|
* last change: $Author: kz $ $Date: 2006-12-15 00:31:23 $
|
|
*
|
|
* The Contents of this file are made available subject to the terms of
|
|
* either of the following licenses
|
|
*
|
|
* - GNU Lesser General Public License Version 2.1
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
*
|
|
* Sun Microsystems Inc., October, 2000
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
*
|
|
* Sun Industry Standards Source License Version 1.1
|
|
* =================================================
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
* Source License Version 1.1 (the "License"); You may not use this file
|
|
* except in compliance with the License. You may obtain a copy of the
|
|
* License at http://www.openoffice.org/license.html.
|
|
*
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
* See the License for the specific provisions governing your rights and
|
|
* obligations concerning the Software.
|
|
*
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
*
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s): _______________________________________
|
|
*
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_basegfx.hxx"
|
|
|
|
#ifndef _OSL_DIAGNOSE_H_
|
|
#include <osl/diagnose.h>
|
|
#endif
|
|
|
|
#include <basegfx/curve/b2dcubicbezier.hxx>
|
|
|
|
#include <basegfx/tools/debugplotter.hxx>
|
|
#include <boost/bind.hpp>
|
|
|
|
|
|
namespace basegfx
|
|
{
|
|
namespace
|
|
{
|
|
void outputHeader( const ::rtl::OString& rTitle,
|
|
::std::ostream* pStm )
|
|
{
|
|
// output gnuplot setup
|
|
if( pStm )
|
|
{
|
|
*pStm << "#!/usr/bin/gnuplot -persist" << ::std::endl <<
|
|
"#" << ::std::endl <<
|
|
"# automatically generated by basegfx, don't change!" << ::std::endl <<
|
|
"#" << ::std::endl <<
|
|
"# --- " << (const sal_Char*)rTitle << " ---" << ::std::endl <<
|
|
"#" << ::std::endl <<
|
|
"set parametric" << ::std::endl <<
|
|
"# set terminal postscript eps enhanced color " << ::std::endl <<
|
|
"# set output \"plot.eps\"" << ::std::endl <<
|
|
// This function plots a cubic bezier curve. P,q,r,s
|
|
// are the control point elements of the corresponding
|
|
// output coordinate component (i.e. x components for
|
|
// the x plot, and y components for the y plot)
|
|
"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 <<
|
|
// This function plots the derivative of a cubic
|
|
// bezier curve. P,q,r,s are the control point
|
|
// components of the _original_ curve
|
|
"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 <<
|
|
// Plot a line's component of a line between a and b
|
|
// (where a and b should be the corresponding
|
|
// components of the line's start and end point,
|
|
// respectively)
|
|
"line(p,q,r) = p*(1-t)+q*t" << ::std::endl <<
|
|
// Plot a line's x component of a line in implicit
|
|
// form ax + by + c = 0
|
|
"implicitLineX(a,b,c,t) = a*-c + t*-b" << ::std::endl <<
|
|
// Plot a line's y component of a line in implicit
|
|
// form ax + by + c = 0
|
|
"implicitLineY(a,b,c,t) = b*-c + t*a" << ::std::endl <<
|
|
"pointmarkx(c,t) = c-0.03*t" << ::std::endl << // hack for displaying single points in parametric form
|
|
"pointmarky(c,t) = c+0.03*t" << ::std::endl << // hack for displaying single points in parametric form
|
|
"# end of setup" << ::std::endl;
|
|
}
|
|
else
|
|
{
|
|
OSL_TRACE( "#!/usr/bin/gnuplot -persist\n",
|
|
"#\n",
|
|
"# automatically generated by basegfx, don't change!\n",
|
|
"#\n",
|
|
"# --- %s ---\n",
|
|
"#\n",
|
|
"set parametric\n",
|
|
// This function plots a cubic bezier curve. P,q,r,s
|
|
// are the control point elements of the corresponding
|
|
// output coordinate component (i.e. x components for
|
|
// the x plot, and y components for the y plot)
|
|
"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",
|
|
// This function plots the derivative of a cubic
|
|
// bezier curve. P,q,r,s are the control point
|
|
// components of the _original_ curve
|
|
"cubicBezDerivative(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2\n",
|
|
// Plot a line's component of a line between a and b
|
|
// (where a and b should be the corresponding
|
|
// components of the line's start and end point,
|
|
// respectively)
|
|
"line(p,q,r) = p*(1-t)+q*t\n",
|
|
// Plot a line's x component of a line in implicit
|
|
// form ax + by + c = 0
|
|
"implicitLineX(a,b,c,t) = a*-c + t*-b\n",
|
|
// Plot a line's y component of a line in implicit
|
|
// form ax + by + c = 0
|
|
"implicitLineY(a,b,c,t) = b*-c + t*a\n",
|
|
"pointmarkx(c,t) = c-0.03*t\n", // hack for displaying single points in parametric form
|
|
"pointmarky(c,t) = c+0.03*t\n", // hack for displaying single points in parametric form
|
|
"# end of setup\n",
|
|
(const sal_Char*)rTitle );
|
|
}
|
|
}
|
|
|
|
class Writer
|
|
{
|
|
public:
|
|
Writer( ::std::ostream* pStm ) :
|
|
mpStream( pStm )
|
|
{
|
|
}
|
|
|
|
void outputPoint( const ::std::pair< B2DPoint, ::rtl::OString >& rElem )
|
|
{
|
|
if( mpStream )
|
|
*mpStream << " " << rElem.first.getX() << "\t" << rElem.first.getY() << ::std::endl;
|
|
else
|
|
OSL_TRACE( " %f\t%f\n", rElem.first.getX(), rElem.first.getY() );
|
|
}
|
|
|
|
void outputVector( const ::std::pair< B2DVector, ::rtl::OString >& rElem )
|
|
{
|
|
if( mpStream )
|
|
*mpStream << " " << rElem.first.getX() << "\t" << rElem.first.getY() << ::std::endl << ::std::endl;
|
|
else
|
|
OSL_TRACE( " %f\t%f\n\n", rElem.first.getX(), rElem.first.getY() );
|
|
}
|
|
|
|
void outputRect( const ::std::pair< B2DRange, ::rtl::OString >& rElem )
|
|
{
|
|
const double nX0( rElem.first.getMinX() );
|
|
const double nY0( rElem.first.getMinY() );
|
|
const double nX1( rElem.first.getMaxX() );
|
|
const double nY1( rElem.first.getMaxY() );
|
|
|
|
if( mpStream )
|
|
*mpStream << " "
|
|
<< nX0 << "\t" << nY0 << "\t"
|
|
<< nX1 << "\t" << nY0 << "\t"
|
|
<< nX1 << "\t" << nY1 << "\t"
|
|
<< nX0 << "\t" << nY1 << "\t"
|
|
<< nX0 << "\t" << nY0 << ::std::endl << ::std::endl;
|
|
|
|
else
|
|
OSL_TRACE( " %f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n\n",
|
|
nX0, nY0,
|
|
nX1, nY0,
|
|
nX1, nY1,
|
|
nX0, nY1,
|
|
nX0, nY0 );
|
|
}
|
|
|
|
private:
|
|
::std::ostream* mpStream;
|
|
};
|
|
}
|
|
|
|
DebugPlotter::DebugPlotter( const sal_Char* pTitle ) :
|
|
maTitle( pTitle ),
|
|
maPoints(),
|
|
maVectors(),
|
|
maRanges(),
|
|
maPolygons(),
|
|
mpOutputStream(NULL)
|
|
{
|
|
}
|
|
|
|
DebugPlotter::DebugPlotter( const sal_Char* pTitle,
|
|
::std::ostream& rOutputStream ) :
|
|
maTitle( pTitle ),
|
|
maPoints(),
|
|
maVectors(),
|
|
maRanges(),
|
|
maPolygons(),
|
|
mpOutputStream(&rOutputStream)
|
|
{
|
|
}
|
|
|
|
DebugPlotter::~DebugPlotter()
|
|
{
|
|
const bool bHavePoints( !maPoints.empty() );
|
|
const bool bHaveVectors( !maVectors.empty() );
|
|
const bool bHaveRanges( !maRanges.empty() );
|
|
const bool bHavePolygons( !maPolygons.empty() );
|
|
|
|
if( bHavePoints ||
|
|
bHaveVectors ||
|
|
bHaveRanges ||
|
|
bHavePolygons )
|
|
{
|
|
outputHeader( maTitle, mpOutputStream );
|
|
|
|
print( "\n\n# parametric primitive output\n"
|
|
"plot [t=0:1] \\\n" );
|
|
|
|
// output plot declarations for used entities
|
|
bool bNeedColon( false );
|
|
if( bHavePoints )
|
|
{
|
|
print( " '-' using ($1):($2) title \"Points\" with points" );
|
|
bNeedColon = true;
|
|
}
|
|
if( bHaveVectors )
|
|
{
|
|
if( bNeedColon )
|
|
print( ", \\\n" );
|
|
|
|
print( " '-' using ($1):($2) title \"Vectors\" with lp" );
|
|
bNeedColon = true;
|
|
}
|
|
if( bHaveRanges )
|
|
{
|
|
if( bNeedColon )
|
|
print( ", \\\n" );
|
|
|
|
print( " '-' using ($1):($2) title \"Ranges\" with lines" );
|
|
bNeedColon = true;
|
|
}
|
|
if( bHavePolygons )
|
|
{
|
|
const ::std::size_t nSize( maPolygons.size() );
|
|
for( ::std::size_t i=0; i<nSize; ++i )
|
|
{
|
|
if( maPolygons.at(i).first.areControlVectorsUsed() )
|
|
{
|
|
const B2DPolygon& rCurrPoly( maPolygons.at(i).first );
|
|
|
|
const sal_uInt32 nCount( rCurrPoly.count() );
|
|
for( sal_uInt32 k=0; k<nCount; ++k )
|
|
{
|
|
if( bNeedColon )
|
|
print( ", \\\n" );
|
|
|
|
const B2DPoint& rP0( rCurrPoly.getB2DPoint(k) );
|
|
const B2DPoint& rP1( rCurrPoly.getControlPointA(k) );
|
|
const B2DPoint& rP2( rCurrPoly.getControlPointB(k) );
|
|
const B2DPoint& rP3( k+1<nCount ? rCurrPoly.getB2DPoint(k+1) : rCurrPoly.getB2DPoint(k) );
|
|
|
|
if( mpOutputStream )
|
|
*mpOutputStream << " cubicBezier("
|
|
<< rP0.getX() << ","
|
|
<< rP1.getX() << ","
|
|
<< rP2.getX() << ","
|
|
<< rP3.getX() << ",t), \\\n cubicBezier("
|
|
<< rP0.getY() << ","
|
|
<< rP1.getY() << ","
|
|
<< rP2.getY() << ","
|
|
<< rP3.getY() << ",t)";
|
|
else
|
|
OSL_TRACE( " cubicBezier(%f,%f,%f,%f,t), \\\n"
|
|
" cubicBezier(%f,%f,%f,%f,t)",
|
|
rP0.getX(),
|
|
rP1.getX(),
|
|
rP2.getX(),
|
|
rP3.getX(),
|
|
rP0.getY(),
|
|
rP1.getY(),
|
|
rP2.getY(),
|
|
rP3.getY() );
|
|
|
|
bNeedColon = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( bNeedColon )
|
|
print( ", \\\n" );
|
|
|
|
if( mpOutputStream )
|
|
*mpOutputStream << " '-' using ($1):($2) title \"Polygon "
|
|
<< (const sal_Char*)maPolygons.at(i).second << "\" with lp";
|
|
else
|
|
OSL_TRACE( " '-' using ($1):($2) title \"Polygon %s\" with lp",
|
|
(const sal_Char*)maPolygons.at(i).second );
|
|
|
|
bNeedColon = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( bHavePoints )
|
|
{
|
|
Writer aWriter( mpOutputStream );
|
|
|
|
::std::for_each( maPoints.begin(),
|
|
maPoints.end(),
|
|
::boost::bind( &Writer::outputPoint,
|
|
::boost::ref( aWriter ),
|
|
_1 ) );
|
|
print( "e\n" );
|
|
}
|
|
|
|
if( bHaveVectors )
|
|
{
|
|
Writer aWriter( mpOutputStream );
|
|
|
|
::std::for_each( maVectors.begin(),
|
|
maVectors.end(),
|
|
::boost::bind( &Writer::outputVector,
|
|
::boost::ref( aWriter ),
|
|
_1 ) );
|
|
print( "e\n" );
|
|
}
|
|
|
|
if( bHaveRanges )
|
|
{
|
|
Writer aWriter( mpOutputStream );
|
|
|
|
::std::for_each( maRanges.begin(),
|
|
maRanges.end(),
|
|
::boost::bind( &Writer::outputRect,
|
|
::boost::ref( aWriter ),
|
|
_1 ) );
|
|
print( "e\n" );
|
|
}
|
|
|
|
if( bHavePolygons )
|
|
{
|
|
const ::std::size_t nSize( maPolygons.size() );
|
|
for( ::std::size_t i=0; i<nSize; ++i )
|
|
{
|
|
if( !maPolygons.at(i).first.areControlVectorsUsed() )
|
|
{
|
|
const B2DPolygon& rCurrPoly( maPolygons.at(i).first );
|
|
|
|
const sal_uInt32 nCount( rCurrPoly.count() );
|
|
for( sal_uInt32 k=0; k<nCount; ++k )
|
|
{
|
|
const B2DPoint& rP( rCurrPoly.getB2DPoint(k) );
|
|
|
|
if( mpOutputStream )
|
|
*mpOutputStream << " " << rP.getX() << "," << rP.getY();
|
|
else
|
|
OSL_TRACE( " %f,%f",
|
|
rP.getX(),
|
|
rP.getX() );
|
|
}
|
|
|
|
print( "\ne\n" );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DebugPlotter::plot( const B2DPoint& rPoint,
|
|
const sal_Char* pTitle )
|
|
{
|
|
maPoints.push_back( ::std::make_pair( rPoint,
|
|
::rtl::OString( pTitle ) ) );
|
|
}
|
|
|
|
void DebugPlotter::plot( const B2DVector& rVec,
|
|
const sal_Char* pTitle )
|
|
{
|
|
maVectors.push_back( ::std::make_pair( rVec,
|
|
::rtl::OString( pTitle ) ) );
|
|
}
|
|
|
|
void DebugPlotter::plot( const B2DCubicBezier& rBezier,
|
|
const sal_Char* pTitle )
|
|
{
|
|
B2DPolygon aPoly;
|
|
aPoly.append( rBezier.getStartPoint() );
|
|
aPoly.setControlPointA( 0,
|
|
rBezier.getControlPointA() );
|
|
aPoly.setControlPointB( 0,
|
|
rBezier.getControlPointB() );
|
|
aPoly.append( rBezier.getEndPoint() );
|
|
|
|
maPolygons.push_back( ::std::make_pair( aPoly,
|
|
::rtl::OString( pTitle ) ) );
|
|
}
|
|
|
|
void DebugPlotter::plot( const B2DRange& rRange,
|
|
const sal_Char* pTitle )
|
|
{
|
|
maRanges.push_back( ::std::make_pair( rRange,
|
|
::rtl::OString( pTitle ) ) );
|
|
}
|
|
|
|
void DebugPlotter::plot( const B2DPolygon& rPoly,
|
|
const sal_Char* pTitle )
|
|
{
|
|
maPolygons.push_back( ::std::make_pair( rPoly,
|
|
::rtl::OString( pTitle ) ) );
|
|
}
|
|
|
|
void DebugPlotter::plot( const B2DPolyPolygon& rPoly,
|
|
const sal_Char* pTitle )
|
|
{
|
|
const ::rtl::OString aTitle( pTitle );
|
|
const sal_uInt32 nCount( rPoly.count() );
|
|
for( sal_uInt32 i=0; i<nCount; ++i )
|
|
maPolygons.push_back( ::std::make_pair( rPoly.getB2DPolygon( i ),
|
|
aTitle ) );
|
|
}
|
|
|
|
void DebugPlotter::print( const sal_Char* pStr )
|
|
{
|
|
if( mpOutputStream )
|
|
*mpOutputStream << pStr;
|
|
else
|
|
OSL_TRACE( pStr );
|
|
}
|
|
}
|