|
|
|
// Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
|
|
|
|
// Copyright (C) 2004 Pino Toscano <toscano.pino@tiscali.it>
|
|
|
|
|
|
|
|
// 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 "angle_type.h"
|
|
|
|
|
|
|
|
#include "bogus_imp.h"
|
|
|
|
#include "other_imp.h"
|
|
|
|
#include "point_imp.h"
|
|
|
|
#include "../misc/calcpaths.h"
|
|
|
|
#include "../misc/common.h"
|
|
|
|
#include "../misc/goniometry.h"
|
|
|
|
#include "../misc/kiginputdialog.h"
|
|
|
|
#include "../kig/kig_commands.h"
|
|
|
|
#include "../kig/kig_part.h"
|
|
|
|
#include "../kig/kig_view.h"
|
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
|
|
|
|
static const char* constructanglethroughpoint =
|
|
|
|
I18N_NOOP( "Construct an angle through this point" );
|
|
|
|
|
|
|
|
static const ArgsParser::spec argsspecAngle[] =
|
|
|
|
{
|
|
|
|
{ PointImp::stype(), constructanglethroughpoint,
|
|
|
|
I18N_NOOP( "Select a point that the first half-line of the angle should go through..." ), true },
|
|
|
|
{ PointImp::stype(), I18N_NOOP( "Construct an angle at this point" ),
|
|
|
|
I18N_NOOP( "Select the point to construct the angle in..." ), true },
|
|
|
|
{ PointImp::stype(), constructanglethroughpoint,
|
|
|
|
I18N_NOOP( "Select a point that the second half-line of the angle should go through..." ), true }
|
|
|
|
};
|
|
|
|
|
|
|
|
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( AngleType )
|
|
|
|
|
|
|
|
AngleType::AngleType()
|
|
|
|
: ArgsParserObjectType( "Angle", argsspecAngle, 3 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
AngleType::~AngleType()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const AngleType* AngleType::instance()
|
|
|
|
{
|
|
|
|
static const AngleType t;
|
|
|
|
return &t;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectImp* AngleType::calc( const Args& parents, const KigDocument& ) const
|
|
|
|
{
|
|
|
|
if ( ! margsparser.checkArgs( parents, 2 ) ) return new InvalidImp;
|
|
|
|
|
|
|
|
std::vector<Coordinate> points;
|
|
|
|
for ( uint i = 0; i < parents.size(); ++i )
|
|
|
|
points.push_back(
|
|
|
|
static_cast<const PointImp*>( parents[i] )->coordinate() );
|
|
|
|
|
|
|
|
Coordinate lvect = points[0] - points[1];
|
|
|
|
Coordinate rvect;
|
|
|
|
if ( points.size() == 3 )
|
|
|
|
rvect = points[2] - points[1];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rvect = lvect.orthogonal();
|
|
|
|
}
|
|
|
|
|
|
|
|
double startangle = atan2( lvect.y, lvect.x );
|
|
|
|
double endangle = atan2( rvect.y, rvect.x );
|
|
|
|
double anglelength = endangle - startangle;
|
|
|
|
if ( anglelength < 0 ) anglelength += 2* M_PI;
|
|
|
|
if ( startangle < 0 ) startangle += 2*M_PI;
|
|
|
|
|
|
|
|
return new AngleImp( points[1], startangle, anglelength );
|
|
|
|
}
|
|
|
|
|
|
|
|
const ObjectImpType* AngleType::resultId() const
|
|
|
|
{
|
|
|
|
return AngleImp::stype();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList AngleType::specialActions() const
|
|
|
|
{
|
|
|
|
TQStringList ret;
|
|
|
|
ret << i18n( "Set Si&ze" );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AngleType::executeAction(
|
|
|
|
int i, ObjectHolder&, ObjectTypeCalcer& t,
|
|
|
|
KigPart& d, KigWidget& w, NormalMode& ) const
|
|
|
|
{
|
|
|
|
assert( i == 0 );
|
|
|
|
// pretend to use this var..
|
|
|
|
(void) i;
|
|
|
|
|
|
|
|
std::vector<ObjectCalcer*> parents = t.parents();
|
|
|
|
|
|
|
|
assert( margsparser.checkArgs( parents ) );
|
|
|
|
|
|
|
|
Coordinate a = static_cast<const PointImp*>( parents[0]->imp() )->coordinate();
|
|
|
|
Coordinate b = static_cast<const PointImp*>( parents[1]->imp() )->coordinate();
|
|
|
|
Coordinate c = static_cast<const PointImp*>( parents[2]->imp() )->coordinate();
|
|
|
|
|
|
|
|
Coordinate lvect = a - b;
|
|
|
|
Coordinate rvect = c - b;
|
|
|
|
|
|
|
|
double startangle = atan2( lvect.y, lvect.x );
|
|
|
|
double endangle = atan2( rvect.y, rvect.x );
|
|
|
|
double anglelength = endangle - startangle;
|
|
|
|
if ( anglelength < 0 ) anglelength += 2* M_PI;
|
|
|
|
if ( startangle < 0 ) startangle += 2*M_PI;
|
|
|
|
|
|
|
|
Goniometry go( anglelength, Goniometry::Rad );
|
|
|
|
go.convertTo( Goniometry::Deg );
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
Goniometry newsize = KigInputDialog::getAngle( &w, &ok, go );
|
|
|
|
if ( !ok )
|
|
|
|
return;
|
|
|
|
newsize.convertTo( Goniometry::Rad );
|
|
|
|
|
|
|
|
double newcangle = startangle + newsize.value();
|
|
|
|
Coordinate cdir( cos( newcangle ), sin( newcangle ) );
|
|
|
|
Coordinate nc = b + cdir.normalize( rvect.length() );
|
|
|
|
|
|
|
|
MonitorDataObjects mon( getAllParents( parents ) );
|
|
|
|
parents[2]->move( nc, d.document() );
|
|
|
|
KigCommand* kc = new KigCommand( d, i18n( "Resize Angle" ) );
|
|
|
|
mon.finish( kc );
|
|
|
|
d.history()->addCommand( kc );
|
|
|
|
}
|
|
|
|
|
|
|
|
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( HalfAngleType )
|
|
|
|
|
|
|
|
HalfAngleType::HalfAngleType()
|
|
|
|
: ArgsParserObjectType( "HalfAngle", argsspecAngle, 3 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
HalfAngleType::~HalfAngleType()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const HalfAngleType* HalfAngleType::instance()
|
|
|
|
{
|
|
|
|
static const HalfAngleType t;
|
|
|
|
return &t;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectImp* HalfAngleType::calc( const Args& parents, const KigDocument& ) const
|
|
|
|
{
|
|
|
|
if ( ! margsparser.checkArgs( parents, 2 ) ) return new InvalidImp;
|
|
|
|
|
|
|
|
std::vector<Coordinate> points;
|
|
|
|
for ( uint i = 0; i < parents.size(); ++i )
|
|
|
|
points.push_back(
|
|
|
|
static_cast<const PointImp*>( parents[i] )->coordinate() );
|
|
|
|
|
|
|
|
Coordinate lvect = points[0] - points[1];
|
|
|
|
Coordinate rvect;
|
|
|
|
if ( points.size() == 3 )
|
|
|
|
rvect = points[2] - points[1];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rvect = lvect.orthogonal();
|
|
|
|
}
|
|
|
|
|
|
|
|
double startangle = atan2( lvect.y, lvect.x );
|
|
|
|
double endangle = atan2( rvect.y, rvect.x );
|
|
|
|
double anglelength = endangle - startangle;
|
|
|
|
if ( anglelength < 0 ) anglelength += 2 * M_PI;
|
|
|
|
if ( startangle < 0 ) startangle += 2 * M_PI;
|
|
|
|
|
|
|
|
if ( anglelength > M_PI )
|
|
|
|
{
|
|
|
|
startangle += anglelength;
|
|
|
|
anglelength = 2 * M_PI - anglelength;
|
|
|
|
if ( startangle > 2 * M_PI ) startangle -= 2 * M_PI;
|
|
|
|
if ( anglelength < 0 ) anglelength += 2 * M_PI;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new AngleImp( points[1], startangle, anglelength );
|
|
|
|
}
|
|
|
|
|
|
|
|
const ObjectImpType* HalfAngleType::resultId() const
|
|
|
|
{
|
|
|
|
return AngleImp::stype();
|
|
|
|
}
|
|
|
|
|