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
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"
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
;
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
)
75 static_cast<const PointImp
*>( parents
[i
] )->coordinate() );
77 Coordinate lvect
= points
[0] - points
[1];
79 if ( points
.size() == 3 )
80 rvect
= points
[2] - points
[1];
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
103 ret
<< i18n( "Set Si&ze" );
107 void AngleType::executeAction(
108 int i
, ObjectHolder
&, ObjectTypeCalcer
& t
,
109 KigPart
& d
, KigWidget
& w
, NormalMode
& ) const
112 // pretend to use this var..
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
) );
135 EditAngleSize
* e
= new EditAngleSize( &w
, anglelengthdeg
, Goniometry::Deg
);
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" ) );
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
;
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
)
175 static_cast<const PointImp
*>( parents
[i
] )->coordinate() );
177 Coordinate lvect
= points
[0] - points
[1];
179 if ( points
.size() == 3 )
180 rvect
= points
[2] - points
[1];
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();