235 lines
8.6 KiB
C++
235 lines
8.6 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org 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 version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#include "testtools.hxx"
|
|
|
|
#include <basegfx/point/b2dpoint.hxx>
|
|
#include <basegfx/vector/b2dvector.hxx>
|
|
#include <basegfx/range/b2drange.hxx>
|
|
#include <basegfx/curve/b2dcubicbezier.hxx>
|
|
#include <basegfx/polygon/b2dpolygon.hxx>
|
|
#include <basegfx/polygon/b2dpolypolygon.hxx>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
namespace basegfx
|
|
{
|
|
namespace testtools
|
|
{
|
|
Plotter::Plotter( ::std::ostream& rOutputStream ) :
|
|
mrOutputStream(rOutputStream),
|
|
maPoints(),
|
|
mbFirstElement( true )
|
|
{
|
|
// output gnuplot setup. We switch gnuplot to parametric
|
|
// mode, therefore every plot has at least _two_
|
|
// functions: one for the x and one for the y value, both
|
|
// depending on t.
|
|
mrOutputStream << "#!/usr/bin/gnuplot -persist" << ::std::endl
|
|
<< "#" << ::std::endl
|
|
<< "# automatically generated by basegfx::testtools::Plotter, don't change!" << ::std::endl
|
|
<< "#" << ::std::endl
|
|
<< "set parametric" << ::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 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
|
|
|
|
// 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(a,b,t) = a*(1-t) + b*t" << ::std::endl << ::std::endl
|
|
<< "# end of setup" << ::std::endl << ::std::endl
|
|
|
|
// Start the actual plot line
|
|
<< "plot [t=0:1] ";
|
|
}
|
|
|
|
namespace
|
|
{
|
|
class PointWriter
|
|
{
|
|
public:
|
|
PointWriter( ::std::ostream& rOutputStream ) :
|
|
mrOutputStream( rOutputStream )
|
|
{
|
|
}
|
|
|
|
void operator()( const B2DPoint& rPoint ) const
|
|
{
|
|
mrOutputStream << rPoint.getX() << "\t" << rPoint.getY() << ::std::endl;
|
|
mrOutputStream << "e" << ::std::endl;
|
|
}
|
|
|
|
private:
|
|
::std::ostream& mrOutputStream;
|
|
};
|
|
}
|
|
|
|
Plotter::~Plotter()
|
|
{
|
|
// End the plot line
|
|
mrOutputStream << ::std::endl;
|
|
|
|
// write stored data points. Cannot write before, since
|
|
// this is an inline dataset, which must be after the plot <...>
|
|
// line
|
|
::std::for_each( maPoints.begin(), maPoints.end(), PointWriter(mrOutputStream) );
|
|
}
|
|
|
|
void Plotter::plot( const B2DPolygon& rPoly )
|
|
{
|
|
const sal_uInt32 pointCount( rPoly.count() );
|
|
|
|
if( pointCount < 1 )
|
|
return;
|
|
|
|
if( pointCount == 1 )
|
|
{
|
|
plot( rPoly.getB2DPoint(0) );
|
|
return;
|
|
}
|
|
|
|
sal_uInt32 i;
|
|
for( i=0; i<pointCount-1; ++i )
|
|
{
|
|
if(rPoly.isNextControlPointUsed(i) || rPoly.isPrevControlPointUsed(i + 1))
|
|
{
|
|
const B2DCubicBezier aBezierPlot(
|
|
rPoly.getB2DPoint(i), rPoly.getNextControlPoint(i),
|
|
rPoly.getPrevControlPoint(i + 1), rPoly.getB2DPoint(i + 1));
|
|
|
|
plot(aBezierPlot);
|
|
}
|
|
else
|
|
{
|
|
plot( rPoly.getB2DPoint(i), rPoly.getB2DPoint(i+1) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void Plotter::plot( const B2DPolyPolygon& rPolyPoly )
|
|
{
|
|
const sal_uInt32 nPolyCount( rPolyPoly.count() );
|
|
|
|
sal_uInt32 i;
|
|
for( i=0; i<nPolyCount; ++i )
|
|
{
|
|
plot( rPolyPoly.getB2DPolygon(i) );
|
|
}
|
|
}
|
|
|
|
void Plotter::plot( const B2DPoint& rPoint )
|
|
{
|
|
maPoints.push_back( rPoint );
|
|
writeSeparator();
|
|
mrOutputStream << "'-' using ($1):($2) title \"Point " << maPoints.size() << "\" with points";
|
|
}
|
|
|
|
void Plotter::plot( const B2DRange& rRect )
|
|
{
|
|
// TODO: do that also as a data file plot. maPoints must
|
|
// then become polymorph, but WTF.
|
|
|
|
// decompose into four lines
|
|
plot( B2DPoint(rRect.getMinX(),
|
|
rRect.getMinY()),
|
|
B2DPoint(rRect.getMaxX(),
|
|
rRect.getMinY()) );
|
|
plot( B2DPoint(rRect.getMaxX(),
|
|
rRect.getMinY()),
|
|
B2DPoint(rRect.getMaxX(),
|
|
rRect.getMaxY()) );
|
|
plot( B2DPoint(rRect.getMaxX(),
|
|
rRect.getMaxY()),
|
|
B2DPoint(rRect.getMinX(),
|
|
rRect.getMaxY()) );
|
|
plot( B2DPoint(rRect.getMinX(),
|
|
rRect.getMaxY()),
|
|
B2DPoint(rRect.getMinX(),
|
|
rRect.getMinY()) );
|
|
}
|
|
|
|
void Plotter::plot( const B2DPoint& rStartPoint, const B2DPoint& rEndPoint )
|
|
{
|
|
writeSeparator();
|
|
mrOutputStream << "line(" << rStartPoint.getX()
|
|
<< "," << rEndPoint.getX()
|
|
<< ",t), "
|
|
<< "line(" << rStartPoint.getY()
|
|
<< "," << rEndPoint.getY()
|
|
<< ",t)";
|
|
}
|
|
|
|
void Plotter::plot( const B2DCubicBezier& rCurve )
|
|
{
|
|
writeSeparator();
|
|
mrOutputStream << "cubicBezier(" << rCurve.getStartPoint().getX()
|
|
<< "," << rCurve.getControlPointA().getX()
|
|
<< "," << rCurve.getControlPointB().getX()
|
|
<< "," << rCurve.getEndPoint().getX()
|
|
<< ",t), "
|
|
<< "cubicBezier(" << rCurve.getStartPoint().getY()
|
|
<< "," << rCurve.getControlPointA().getY()
|
|
<< "," << rCurve.getControlPointB().getY()
|
|
<< "," << rCurve.getEndPoint().getY()
|
|
<< ",t)";
|
|
}
|
|
|
|
void Plotter::writeSeparator()
|
|
{
|
|
if( mbFirstElement )
|
|
{
|
|
mbFirstElement = false;
|
|
}
|
|
else
|
|
{
|
|
mrOutputStream << ", ";
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|