moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kig / objects / angle_type.cc
blob8ceda52541cb8f34b41c35d1b30b16dfa1168800
1 // Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
2 // Copyright (C) 2004 Pino Toscano <toscano.pino@tiscali.it>
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 // 02111-1307, USA.
19 #include "angle_type.h"
21 #include "bogus_imp.h"
22 #include "editanglesize.h"
23 #include "other_imp.h"
24 #include "point_imp.h"
25 #include "../misc/calcpaths.h"
26 #include "../misc/common.h"
27 #include "../misc/goniometry.h"
28 #include "../kig/kig_commands.h"
29 #include "../kig/kig_part.h"
30 #include "../kig/kig_view.h"
32 #include <functional>
33 #include <algorithm>
34 #include <cmath>
36 #include <qstringlist.h>
38 static const char* constructanglethroughpoint =
39 I18N_NOOP( "Construct an angle through this point" );
41 static const ArgsParser::spec argsspecAngle[] =
43 { PointImp::stype(), constructanglethroughpoint,
44 I18N_NOOP( "Select a point that the first half-line of the angle should go through..." ), true },
45 { PointImp::stype(), I18N_NOOP( "Construct an angle at this point" ),
46 I18N_NOOP( "Select the point to construct the angle in..." ), true },
47 { PointImp::stype(), constructanglethroughpoint,
48 I18N_NOOP( "Select a point that the second half-line of the angle should go through..." ), true }
51 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( AngleType )
53 AngleType::AngleType()
54 : ArgsParserObjectType( "Angle", argsspecAngle, 3 )
58 AngleType::~AngleType()
62 const AngleType* AngleType::instance()
64 static const AngleType t;
65 return &t;
68 ObjectImp* AngleType::calc( const Args& parents, const KigDocument& ) const
70 if ( ! margsparser.checkArgs( parents, 2 ) ) return new InvalidImp;
72 std::vector<Coordinate> points;
73 for ( uint i = 0; i < parents.size(); ++i )
74 points.push_back(
75 static_cast<const PointImp*>( parents[i] )->coordinate() );
77 Coordinate lvect = points[0] - points[1];
78 Coordinate rvect;
79 if ( points.size() == 3 )
80 rvect = points[2] - points[1];
81 else
83 rvect = lvect.orthogonal();
86 double startangle = atan2( lvect.y, lvect.x );
87 double endangle = atan2( rvect.y, rvect.x );
88 double anglelength = endangle - startangle;
89 if ( anglelength < 0 ) anglelength += 2* M_PI;
90 if ( startangle < 0 ) startangle += 2*M_PI;
92 return new AngleImp( points[1], startangle, anglelength );
95 const ObjectImpType* AngleType::resultId() const
97 return AngleImp::stype();
100 QStringList AngleType::specialActions() const
102 QStringList ret;
103 ret << i18n( "Set Si&ze" );
104 return ret;
107 void AngleType::executeAction(
108 int i, ObjectHolder&, ObjectTypeCalcer& t,
109 KigPart& d, KigWidget& w, NormalMode& ) const
111 assert( i == 0 );
112 // pretend to use this var..
113 (void) i;
115 std::vector<ObjectCalcer*> parents = t.parents();
117 assert( margsparser.checkArgs( parents ) );
119 Coordinate a = static_cast<const PointImp*>( parents[0]->imp() )->coordinate();
120 Coordinate b = static_cast<const PointImp*>( parents[1]->imp() )->coordinate();
121 Coordinate c = static_cast<const PointImp*>( parents[2]->imp() )->coordinate();
123 Coordinate lvect = a - b;
124 Coordinate rvect = c - b;
126 double startangle = atan2( lvect.y, lvect.x );
127 double endangle = atan2( rvect.y, rvect.x );
128 double anglelength = endangle - startangle;
129 if ( anglelength < 0 ) anglelength += 2* M_PI;
130 if ( startangle < 0 ) startangle += 2*M_PI;
132 int anglelengthdeg = static_cast<int>( Goniometry::convert( anglelength, Goniometry::Rad, Goniometry::Deg ) );
134 double newsize = 0;
135 EditAngleSize* e = new EditAngleSize( &w, anglelengthdeg, Goniometry::Deg );
136 if( !e->exec() )
137 return;
138 newsize = Goniometry::convert( e->angle(), e->system(), Goniometry::Rad );
140 double newcangle = startangle + newsize;
141 Coordinate cdir( cos( newcangle ), sin( newcangle ) );
142 Coordinate nc = b + cdir.normalize( rvect.length() );
144 MonitorDataObjects mon( getAllParents( parents ) );
145 parents[2]->move( nc, d.document() );
146 KigCommand* kc = new KigCommand( d, i18n( "Resize Angle" ) );
147 mon.finish( kc );
148 d.history()->addCommand( kc );
151 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( HalfAngleType )
153 HalfAngleType::HalfAngleType()
154 : ArgsParserObjectType( "HalfAngle", argsspecAngle, 3 )
158 HalfAngleType::~HalfAngleType()
162 const HalfAngleType* HalfAngleType::instance()
164 static const HalfAngleType t;
165 return &t;
168 ObjectImp* HalfAngleType::calc( const Args& parents, const KigDocument& ) const
170 if ( ! margsparser.checkArgs( parents, 2 ) ) return new InvalidImp;
172 std::vector<Coordinate> points;
173 for ( uint i = 0; i < parents.size(); ++i )
174 points.push_back(
175 static_cast<const PointImp*>( parents[i] )->coordinate() );
177 Coordinate lvect = points[0] - points[1];
178 Coordinate rvect;
179 if ( points.size() == 3 )
180 rvect = points[2] - points[1];
181 else
183 rvect = lvect.orthogonal();
186 double startangle = atan2( lvect.y, lvect.x );
187 double endangle = atan2( rvect.y, rvect.x );
188 double anglelength = endangle - startangle;
189 if ( anglelength < 0 ) anglelength += 2 * M_PI;
190 if ( startangle < 0 ) startangle += 2 * M_PI;
192 if ( anglelength > M_PI )
194 startangle += anglelength;
195 anglelength = 2 * M_PI - anglelength;
196 if ( startangle > 2 * M_PI ) startangle -= 2 * M_PI;
197 if ( anglelength < 0 ) anglelength += 2 * M_PI;
200 return new AngleImp( points[1], startangle, anglelength );
203 const ObjectImpType* HalfAngleType::resultId() const
205 return AngleImp::stype();