• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdeedu
  • Sitemap
  • Contact Us
 

kig

arc_type.cc

Go to the documentation of this file.
00001 // Copyright (C)  2003-2004  Dominique Devriese <devriese@kde.org>
00002 
00003 // This program is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU General Public License
00005 // as published by the Free Software Foundation; either version 2
00006 // of the License, or (at your option) any later version.
00007 
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00016 // 02110-1301, USA.
00017 
00018 #include "arc_type.h"
00019 
00020 #include "bogus_imp.h"
00021 #include "other_imp.h"
00022 #include "point_imp.h"
00023 #include "conic_imp.h"
00024 #include "line_imp.h"
00025 #include "locus_imp.h"
00026 
00027 #include "../misc/common.h"
00028 #include "../misc/calcpaths.h"
00029 #include "../misc/goniometry.h"
00030 #include "../kig/kig_part.h"
00031 #include "../kig/kig_view.h"
00032 #include "../kig/kig_commands.h"
00033 
00034 #include <functional>
00035 #include <algorithm>
00036 #include <cmath>
00037 
00038 using std::find;
00039 
00040 #include <qstringlist.h>
00041 
00042 /*
00043  * arc by three points
00044  */
00045 
00046 static const char constructarcstartingstat[] = I18N_NOOP( "Construct an arc starting at this point" );
00047 
00048 static const ArgsParser::spec argsspecArcBTP[] =
00049 {
00050   { PointImp::stype(), constructarcstartingstat,
00051     I18N_NOOP( "Select the start point of the new arc..." ), true },
00052   { PointImp::stype(), I18N_NOOP( "Construct an arc through this point" ),
00053     I18N_NOOP( "Select a point for the new arc to go through..." ), true },
00054   { PointImp::stype(), I18N_NOOP( "Construct an arc ending at this point" ),
00055     I18N_NOOP( "Select the end point of the new arc..." ), true }
00056 };
00057 
00058 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcBTPType )
00059 
00060 ArcBTPType::ArcBTPType()
00061   : ArgsParserObjectType( "ArcBTP", argsspecArcBTP, 3 )
00062 {
00063 }
00064 
00065 ArcBTPType::~ArcBTPType()
00066 {
00067 }
00068 
00069 const ArcBTPType* ArcBTPType::instance()
00070 {
00071   static const ArcBTPType t;
00072   return &t;
00073 }
00074 
00075 ObjectImp* ArcBTPType::calc( const Args& args, const KigDocument& ) const
00076 {
00077   if ( ! margsparser.checkArgs( args, 2 ) )
00078     return new InvalidImp;
00079 
00080   const Coordinate a =
00081     static_cast<const PointImp*>( args[0] )->coordinate();
00082   const Coordinate b =
00083     static_cast<const PointImp*>( args[1] )->coordinate();
00084   Coordinate center;
00085   double angle = 0.;
00086   double startangle = 0.;
00087   if ( args.size() == 3 )
00088   {
00089     Coordinate c = static_cast<const PointImp*>( args[2] )->coordinate();
00090     center = calcCenter( a, b, c );
00091     if ( ! center.valid() )
00092     {
00093       if ( fabs( a.x - c.x ) > fabs( a.y - c.y ) )
00094       {
00095         if ( ( b.x - a.x)*(c.x - b.x) > 1e-12 ) return new SegmentImp(a, c);
00096       } else
00097       {
00098         if ( ( b.y - a.y)*(c.y - b.y) > 1e-12 ) return new SegmentImp(a, c);
00099       }
00100       return new InvalidImp;
00101     }
00102     Coordinate ad = a - center;
00103     Coordinate bd = b - center;
00104     Coordinate cd = c - center;
00105     double anglea = atan2( ad.y, ad.x );
00106     double angleb = atan2( bd.y, bd.x );
00107     double anglec = atan2( cd.y, cd.x );
00108 
00109     // anglea should be smaller than anglec
00110     if ( anglea > anglec )
00111     {
00112       double t = anglea;
00113       anglea = anglec;
00114       anglec = t;
00115     };
00116     if ( angleb > anglec || angleb < anglea )
00117     {
00118       startangle = anglec;
00119       angle = 2 * M_PI + anglea - startangle;
00120     }
00121     else
00122     {
00123       startangle = anglea;
00124       angle = anglec - anglea;
00125     };
00126   }
00127   else
00128   {
00129     // find a center and angles that look natural..
00130     center = (b+a)/2 + .6*(b-a).orthogonal();
00131     Coordinate bd = b - center;
00132     Coordinate ad = a - center;
00133     startangle = atan2( ad.y, ad.x );
00134     double halfangle = atan2( bd.y, bd.x ) - startangle;
00135     if ( halfangle < - M_PI ) halfangle += 2*M_PI;
00136     angle = 2 * halfangle;
00137   };
00138 
00139   double radius = ( a - center ).length();
00140   return new ArcImp( center, radius, startangle, angle );
00141 }
00142 
00143 const ObjectImpType* ArcBTPType::impRequirement( const ObjectImp*, const Args& ) const
00144 {
00145   return PointImp::stype();
00146 }
00147 
00148 bool ArcBTPType::inherits( int type ) const
00149 {
00150   return Parent::inherits( type );
00151 }
00152 
00153 const ObjectImpType* ArcBTPType::resultId() const
00154 {
00155   return ArcImp::stype();
00156 }
00157 
00158 /*
00159  * arc by center, starting point and angle
00160  */
00161 
00162 static const ArgsParser::spec argsspecArcBCPA[] =
00163 {
00164   { PointImp::stype(), I18N_NOOP( "Construct an arc with this center" ),
00165     I18N_NOOP( "Select the center of the new arc..." ), true },
00166   { PointImp::stype(), constructarcstartingstat,
00167     I18N_NOOP( "Select the start point of the new arc..." ), true },
00168   { AngleImp::stype(), I18N_NOOP( "Construct an arc with this angle" ),
00169     I18N_NOOP( "Select the angle of the new arc..." ), true }
00170 };
00171 
00172 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcBCPAType )
00173 
00174 ArcBCPAType::ArcBCPAType()
00175   : ArgsParserObjectType( "ArcBCPA", argsspecArcBCPA, 3 )
00176 {
00177 }
00178 
00179 ArcBCPAType::~ArcBCPAType()
00180 {
00181 }
00182 
00183 const ArcBCPAType* ArcBCPAType::instance()
00184 {
00185   static const ArcBCPAType t;
00186   return &t;
00187 }
00188 
00189 ObjectImp* ArcBCPAType::calc( const Args& args, const KigDocument& ) const
00190 {
00191   if ( ! margsparser.checkArgs( args ) )
00192     return new InvalidImp;
00193 
00194   const Coordinate center = static_cast<const PointImp*>( args[0] )->coordinate();
00195   const Coordinate p = static_cast<const PointImp*>( args[1] )->coordinate();
00196   const AngleImp* a = static_cast<const AngleImp*>( args[2] );
00197   const double angle = a->angle();
00198   const Coordinate dir = p - center;
00199   const double startangle = atan2( dir.y, dir.x );
00200   const double radius = center.distance( p );
00201 
00202   return new ArcImp( center, radius, startangle, angle );
00203 }
00204 
00205 const ObjectImpType* ArcBCPAType::impRequirement( const ObjectImp*, const Args& ) const
00206 {
00207   return PointImp::stype();
00208 }
00209 
00210 bool ArcBCPAType::inherits( int type ) const
00211 {
00212   return Parent::inherits( type );
00213 }
00214 
00215 const ObjectImpType* ArcBCPAType::resultId() const
00216 {
00217   return ArcImp::stype();
00218 }
00219 
00220 /*
00221  * arc of conic by three points and center
00222  */
00223 
00224 static const char constructconicarcstartingstat[] = I18N_NOOP( "Construct a conic arc starting at this point" );
00225 static const char selectconicarcstartingstat[] = I18N_NOOP( "Select the start point of the new conic arc..." );
00226 static const char constructconicarcthrustat[] = I18N_NOOP( "Construct a conic arc through this point" );
00227 static const char selectconicarcthrustat[] = I18N_NOOP( "Select a point for the new conic arc to go through..." );
00228 static const char constructconicarcendingstat[] = I18N_NOOP( "Construct a conic arc ending at this point" );
00229 static const char selectconicarcendingstat[] = I18N_NOOP( "Select the end point of the new conic arc..." );
00230 
00231 static const ArgsParser::spec argsspecConicArcBCTP[] =
00232 {
00233   { PointImp::stype(), I18N_NOOP( "Construct an conic arc with this center" ),
00234     I18N_NOOP( "Select the center of the new conic arc..." ), false },
00235   { PointImp::stype(), constructconicarcstartingstat,
00236     selectconicarcstartingstat, true },
00237   { PointImp::stype(), constructconicarcthrustat,
00238     selectconicarcthrustat, true },
00239   { PointImp::stype(), constructconicarcendingstat,
00240     selectconicarcendingstat, true }
00241 };
00242 
00243 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConicArcBCTPType )
00244 
00245 ConicArcBCTPType::ConicArcBCTPType()
00246   : ArgsParserObjectType( "ConicArcBCTP", argsspecConicArcBCTP, 4 )
00247 {
00248 }
00249 
00250 ConicArcBCTPType::~ConicArcBCTPType()
00251 {
00252 }
00253 
00254 const ConicArcBCTPType* ConicArcBCTPType::instance()
00255 {
00256   static const ConicArcBCTPType t;
00257   return &t;
00258 }
00259 
00260 ObjectImp* ConicArcBCTPType::calc( const Args& args, const KigDocument& ) const
00261 {
00262   if ( ! margsparser.checkArgs( args, 2 ) )
00263     return new InvalidImp;
00264 
00265   const Coordinate center =
00266     static_cast<const PointImp*>( args[0] )->coordinate();
00267   const Coordinate a =
00268     static_cast<const PointImp*>( args[1] )->coordinate();
00269   const Coordinate d = 2*center - a;
00270   Coordinate b = center + (a-center).orthogonal();
00271   Coordinate e = 2*center - b;
00272   if ( args.size() >= 3 )
00273   {
00274     b = static_cast<const PointImp*>( args[2] )->coordinate();
00275     e = 2*center - b;
00276   }
00277   bool have_c = false;
00278   Coordinate c;
00279   if ( args.size() == 4 )
00280   {
00281     c = static_cast<const PointImp*>( args[3] )->coordinate();
00282     const Coordinate e = 2*center - c;
00283     have_c = true;
00284   }
00285 
00286   std::vector<Coordinate> points;
00287   points.push_back( a );
00288   points.push_back( b );
00289   if (have_c) points.push_back( c );
00290   points.push_back( d );
00291   points.push_back( e );
00292   ConicCartesianData cart =
00293     calcConicThroughPoints( points, zerotilt, circleifzt, ysymmetry );
00294   if ( ! d.valid() )
00295     return new InvalidImp;
00296 
00297   ConicArcImp *me = new ConicArcImp( cart, 0.0, 2*M_PI );
00298   double angle = 0.;
00299   double startangle = 0.;
00300   double anglea = 2*M_PI*me->getParam( a );
00301   double angleb = anglea + M_PI/2;
00302   angleb = 2*M_PI*me->getParam( b );
00303   double anglec = 2*angleb - anglea;
00304   if ( have_c ) anglec = 2*M_PI*me->getParam( c );
00305 
00306   // anglea should be smaller than anglec
00307   if ( anglea > anglec )
00308   {
00309     double t = anglea;
00310     anglea = anglec;
00311     anglec = t;
00312   };
00313   if ( angleb > anglec || angleb < anglea )
00314   {
00315     startangle = anglec;
00316     angle = 2 * M_PI + anglea - startangle;
00317   }
00318   else
00319   {
00320     startangle = anglea;
00321     angle = anglec - anglea;
00322   };
00323 
00324   me->setStartAngle( startangle );
00325   me->setAngle( angle );
00326   return me;
00327 }
00328 
00329 const ObjectImpType* ConicArcBCTPType::resultId() const
00330 {
00331   return ConicArcImp::stype();
00332 }
00333 
00334 /*
00335  * arc of conic by five points
00336  */
00337 
00338 static const ArgsParser::spec argsspecConicArcB5P[] =
00339 {
00340   { PointImp::stype(), constructconicarcstartingstat,
00341     selectconicarcstartingstat, true },
00342   { PointImp::stype(), constructconicarcthrustat,
00343     selectconicarcthrustat, true },
00344   { PointImp::stype(), constructconicarcthrustat,
00345     selectconicarcthrustat, true },
00346   { PointImp::stype(), constructconicarcthrustat,
00347     selectconicarcthrustat, true },
00348   { PointImp::stype(), constructconicarcendingstat,
00349     selectconicarcendingstat, true }
00350 };
00351 
00352 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConicArcB5PType )
00353 
00354 ConicArcB5PType::ConicArcB5PType()
00355   : ArgsParserObjectType( "ConicArcB5P", argsspecConicArcB5P, 5 )
00356 {
00357 }
00358 
00359 ConicArcB5PType::~ConicArcB5PType()
00360 {
00361 }
00362 
00363 const ConicArcB5PType* ConicArcB5PType::instance()
00364 {
00365   static const ConicArcB5PType t;
00366   return &t;
00367 }
00368 
00369 ObjectImp* ConicArcB5PType::calc( const Args& args, const KigDocument& ) const
00370 {
00371   if ( ! margsparser.checkArgs( args, 2 ) )
00372     return new InvalidImp;
00373 
00374   const Coordinate a =
00375     static_cast<const PointImp*>( args[0] )->coordinate();
00376   const Coordinate b =
00377     static_cast<const PointImp*>( args[1] )->coordinate();
00378 
00379   Coordinate c, d, e;
00380   bool have_c = false;
00381   bool have_d = false;
00382   bool have_e = false;
00383   if ( args.size() >= 3 )
00384   {
00385     c = static_cast<const PointImp*>( args[2] )->coordinate();
00386     have_c = true;
00387   }
00388   if ( args.size() >= 4 )
00389   {
00390     d = static_cast<const PointImp*>( args[3] )->coordinate();
00391     have_d = true;
00392   }
00393   if ( args.size() >= 5 )
00394   {
00395     e = static_cast<const PointImp*>( args[4] )->coordinate();
00396     have_e = true;
00397   }
00398 
00399   std::vector<Coordinate> points;
00400   points.push_back( a );
00401   points.push_back( b );
00402   if (have_c) points.push_back( c );
00403   if (have_d) points.push_back( d );
00404   if (have_e) points.push_back( e );
00405   ConicCartesianData cart =
00406     calcConicThroughPoints( points, zerotilt, circleifzt, ysymmetry );
00407   if ( ! d.valid() )
00408     return new InvalidImp;
00409 
00410   ConicArcImp *me = new ConicArcImp( cart, 0.0, 2*M_PI );
00411   double angle = 0.;
00412   double startangle = 0.;
00413   double anglea = 2*M_PI*me->getParam( a );
00414   double angleb = anglea + M_PI/2;
00415   angleb = 2*M_PI*me->getParam( b );
00416   if ( have_c ) angleb = 2*M_PI*me->getParam( c );
00417   double anglec = 2*angleb - anglea;
00418   if ( have_e ) anglec = 2*M_PI*me->getParam( e );
00419 
00420   // anglea should be smaller than anglec
00421   if ( anglea > anglec )
00422   {
00423     double t = anglea;
00424     anglea = anglec;
00425     anglec = t;
00426   };
00427   if ( angleb > anglec || angleb < anglea )
00428   {
00429     startangle = anglec;
00430     angle = 2 * M_PI + anglea - startangle;
00431   }
00432   else
00433   {
00434     startangle = anglea;
00435     angle = anglec - anglea;
00436   };
00437 
00438   me->setStartAngle( startangle );
00439   me->setAngle( angle );
00440   return me;
00441 }
00442 
00443 const ObjectImpType* ConicArcB5PType::resultId() const
00444 {
00445   return ConicArcImp::stype();
00446 }
00447 

kig

Skip menu "kig"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdeedu

Skip menu "kdeedu"
  • kalzium
  • kanagram
  • kig
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  •   docs
  •   src
  • parley
Generated for kdeedu by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal