diff options
Diffstat (limited to 'kig/objects/arc_type.cc')
-rw-r--r-- | kig/objects/arc_type.cc | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/kig/objects/arc_type.cc b/kig/objects/arc_type.cc new file mode 100644 index 00000000..f6c660f2 --- /dev/null +++ b/kig/objects/arc_type.cc @@ -0,0 +1,199 @@ +// Copyright (C) 2003-2004 Dominique Devriese <devriese@kde.org> + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301, USA. + +#include "arc_type.h" + +#include "bogus_imp.h" +#include "other_imp.h" +#include "point_imp.h" +#include "line_imp.h" +#include "locus_imp.h" + +#include "../misc/common.h" +#include "../misc/calcpaths.h" +#include "../misc/goniometry.h" +#include "../kig/kig_part.h" +#include "../kig/kig_view.h" +#include "../kig/kig_commands.h" + +#include <functional> +#include <algorithm> +#include <cmath> + +using std::find; + +#include <qstringlist.h> + +static const char constructarcstartingstat[] = I18N_NOOP( "Construct an arc starting at this point" ); + +static const ArgsParser::spec argsspecArcBTP[] = +{ + { PointImp::stype(), constructarcstartingstat, + I18N_NOOP( "Select the start point of the new arc..." ), true }, + { PointImp::stype(), I18N_NOOP( "Construct an arc through this point" ), + I18N_NOOP( "Select a point for the new arc to go through..." ), true }, + { PointImp::stype(), I18N_NOOP( "Construct an arc ending at this point" ), + I18N_NOOP( "Select the end point of the new arc..." ), true } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcBTPType ) + +ArcBTPType::ArcBTPType() + : ArgsParserObjectType( "ArcBTP", argsspecArcBTP, 3 ) +{ +} + +ArcBTPType::~ArcBTPType() +{ +} + +const ArcBTPType* ArcBTPType::instance() +{ + static const ArcBTPType t; + return &t; +} + +ObjectImp* ArcBTPType::calc( const Args& args, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( args, 2 ) ) + return new InvalidImp; + + const Coordinate a = + static_cast<const PointImp*>( args[0] )->coordinate(); + const Coordinate b = + static_cast<const PointImp*>( args[1] )->coordinate(); + Coordinate center; + double angle = 0.; + double startangle = 0.; + if ( args.size() == 3 ) + { + Coordinate c = static_cast<const PointImp*>( args[2] )->coordinate(); + center = calcCenter( a, b, c ); + if ( ! center.valid() ) return new InvalidImp; + Coordinate ad = a - center; + Coordinate bd = b - center; + Coordinate cd = c - center; + double anglea = atan2( ad.y, ad.x ); + double angleb = atan2( bd.y, bd.x ); + double anglec = atan2( cd.y, cd.x ); + + // anglea should be smaller than anglec + if ( anglea > anglec ) + { + double t = anglea; + anglea = anglec; + anglec = t; + }; + if ( angleb > anglec || angleb < anglea ) + { + startangle = anglec; + angle = 2 * M_PI + anglea - startangle; + } + else + { + startangle = anglea; + angle = anglec - anglea; + }; + } + else + { + // find a center and angles that look natural.. + center = (b+a)/2 + .6*(b-a).orthogonal(); + Coordinate bd = b - center; + Coordinate ad = a - center; + startangle = atan2( ad.y, ad.x ); + double halfangle = atan2( bd.y, bd.x ) - startangle; + if ( halfangle < - M_PI ) halfangle += 2*M_PI; + angle = 2 * halfangle; + }; + + double radius = ( a - center ).length(); + return new ArcImp( center, radius, startangle, angle ); +} + +const ObjectImpType* ArcBTPType::impRequirement( const ObjectImp*, const Args& ) const +{ + return PointImp::stype(); +} + +bool ArcBTPType::inherits( int type ) const +{ + return Parent::inherits( type ); +} + +const ObjectImpType* ArcBTPType::resultId() const +{ + return ArcImp::stype(); +} + +static const ArgsParser::spec argsspecArcBCPA[] = +{ + { PointImp::stype(), I18N_NOOP( "Construct an arc with this center" ), + I18N_NOOP( "Select the center of the new arc..." ), true }, + { PointImp::stype(), constructarcstartingstat, + I18N_NOOP( "Select the start point of the new arc..." ), true }, + { AngleImp::stype(), I18N_NOOP( "Construct an arc with this angle" ), + I18N_NOOP( "Select the angle of the new arc..." ), true } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcBCPAType ) + +ArcBCPAType::ArcBCPAType() + : ArgsParserObjectType( "ArcBCPA", argsspecArcBCPA, 3 ) +{ +} + +ArcBCPAType::~ArcBCPAType() +{ +} + +const ArcBCPAType* ArcBCPAType::instance() +{ + static const ArcBCPAType t; + return &t; +} + +ObjectImp* ArcBCPAType::calc( const Args& args, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( args ) ) + return new InvalidImp; + + const Coordinate center = static_cast<const PointImp*>( args[0] )->coordinate(); + const Coordinate p = static_cast<const PointImp*>( args[1] )->coordinate(); + const AngleImp* a = static_cast<const AngleImp*>( args[2] ); + const double angle = a->angle(); + const Coordinate dir = p - center; + const double startangle = atan2( dir.y, dir.x ); + const double radius = center.distance( p ); + + return new ArcImp( center, radius, startangle, angle ); +} + +const ObjectImpType* ArcBCPAType::impRequirement( const ObjectImp*, const Args& ) const +{ + return PointImp::stype(); +} + +bool ArcBCPAType::inherits( int type ) const +{ + return Parent::inherits( type ); +} + +const ObjectImpType* ArcBCPAType::resultId() const +{ + return ArcImp::stype(); +} |