• Skip to content
  • Skip to link menu
KDE 4.2 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 #include <math.h>
00038 
00039 using std::find;
00040 
00041 #include <qstringlist.h>
00042 
00043 /*
00044  * arc by three points
00045  */
00046 
00047 static const char constructarcstartingstat[] = I18N_NOOP( "Construct an arc starting at this point" );
00048 
00049 static const ArgsParser::spec argsspecArcBTP[] =
00050 {
00051   { PointImp::stype(), constructarcstartingstat,
00052     I18N_NOOP( "Select the start point of the new arc..." ), true },
00053   { PointImp::stype(), I18N_NOOP( "Construct an arc through this point" ),
00054     I18N_NOOP( "Select a point for the new arc to go through..." ), true },
00055   { PointImp::stype(), I18N_NOOP( "Construct an arc ending at this point" ),
00056     I18N_NOOP( "Select the end point of the new arc..." ), true }
00057 };
00058 
00059 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcBTPType )
00060 
00061 ArcBTPType::ArcBTPType()
00062   : ArgsParserObjectType( "ArcBTP", argsspecArcBTP, 3 )
00063 {
00064 }
00065 
00066 ArcBTPType::~ArcBTPType()
00067 {
00068 }
00069 
00070 const ArcBTPType* ArcBTPType::instance()
00071 {
00072   static const ArcBTPType t;
00073   return &t;
00074 }
00075 
00076 ObjectImp* ArcBTPType::calc( const Args& args, const KigDocument& ) const
00077 {
00078   if ( ! margsparser.checkArgs( args, 2 ) )
00079     return new InvalidImp;
00080 
00081   const Coordinate a =
00082     static_cast<const PointImp*>( args[0] )->coordinate();
00083   const Coordinate b =
00084     static_cast<const PointImp*>( args[1] )->coordinate();
00085   Coordinate center;
00086   double angle = 0.;
00087   double startangle = 0.;
00088   if ( args.size() == 3 )
00089   {
00090     Coordinate c = static_cast<const PointImp*>( args[2] )->coordinate();
00091     center = calcCenter( a, b, c );
00092     if ( ! center.valid() )
00093     {
00094       if ( fabs( a.x - c.x ) > fabs( a.y - c.y ) )
00095       {
00096         if ( ( b.x - a.x)*(c.x - b.x) > 1e-12 ) return new SegmentImp(a, c);
00097       } else
00098       {
00099         if ( ( b.y - a.y)*(c.y - b.y) > 1e-12 ) return new SegmentImp(a, c);
00100       }
00101       return new InvalidImp;
00102     }
00103     Coordinate ad = a - center;
00104     Coordinate bd = b - center;
00105     Coordinate cd = c - center;
00106     double anglea = atan2( ad.y, ad.x );
00107     double angleb = atan2( bd.y, bd.x );
00108     double anglec = atan2( cd.y, cd.x );
00109 
00110     // anglea should be smaller than anglec
00111     if ( anglea > anglec )
00112     {
00113       double t = anglea;
00114       anglea = anglec;
00115       anglec = t;
00116     };
00117     if ( angleb > anglec || angleb < anglea )
00118     {
00119       startangle = anglec;
00120       angle = 2 * M_PI + anglea - startangle;
00121     }
00122     else
00123     {
00124       startangle = anglea;
00125       angle = anglec - anglea;
00126     };
00127   }
00128   else
00129   {
00130     // find a center and angles that look natural..
00131     center = (b+a)/2 + .6*(b-a).orthogonal();
00132     Coordinate bd = b - center;
00133     Coordinate ad = a - center;
00134     startangle = atan2( ad.y, ad.x );
00135     double halfangle = atan2( bd.y, bd.x ) - startangle;
00136     if ( halfangle < - M_PI ) halfangle += 2*M_PI;
00137     angle = 2 * halfangle;
00138   };
00139 
00140   double radius = ( a - center ).length();
00141   return new ArcImp( center, radius, startangle, angle );
00142 }
00143 
00144 const ObjectImpType* ArcBTPType::impRequirement( const ObjectImp*, const Args& ) const
00145 {
00146   return PointImp::stype();
00147 }
00148 
00149 bool ArcBTPType::inherits( int type ) const
00150 {
00151   return Parent::inherits( type );
00152 }
00153 
00154 const ObjectImpType* ArcBTPType::resultId() const
00155 {
00156   return ArcImp::stype();
00157 }
00158 
00159 /*
00160  * arc by center, starting point and angle
00161  */
00162 
00163 static const ArgsParser::spec argsspecArcBCPA[] =
00164 {
00165   { PointImp::stype(), I18N_NOOP( "Construct an arc with this center" ),
00166     I18N_NOOP( "Select the center of the new arc..." ), true },
00167   { PointImp::stype(), constructarcstartingstat,
00168     I18N_NOOP( "Select the start point of the new arc..." ), true },
00169   { AngleImp::stype(), I18N_NOOP( "Construct an arc with this angle" ),
00170     I18N_NOOP( "Select the angle of the new arc..." ), true }
00171 };
00172 
00173 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcBCPAType )
00174 
00175 ArcBCPAType::ArcBCPAType()
00176   : ArgsParserObjectType( "ArcBCPA", argsspecArcBCPA, 3 )
00177 {
00178 }
00179 
00180 ArcBCPAType::~ArcBCPAType()
00181 {
00182 }
00183 
00184 const ArcBCPAType* ArcBCPAType::instance()
00185 {
00186   static const ArcBCPAType t;
00187   return &t;
00188 }
00189 
00190 ObjectImp* ArcBCPAType::calc( const Args& args, const KigDocument& ) const
00191 {
00192   if ( ! margsparser.checkArgs( args ) )
00193     return new InvalidImp;
00194 
00195   const Coordinate center = static_cast<const PointImp*>( args[0] )->coordinate();
00196   const Coordinate p = static_cast<const PointImp*>( args[1] )->coordinate();
00197   const AngleImp* a = static_cast<const AngleImp*>( args[2] );
00198   const double angle = a->angle();
00199   const Coordinate dir = p - center;
00200   const double startangle = atan2( dir.y, dir.x );
00201   const double radius = center.distance( p );
00202 
00203   return new ArcImp( center, radius, startangle, angle );
00204 }
00205 
00206 const ObjectImpType* ArcBCPAType::impRequirement( const ObjectImp*, const Args& ) const
00207 {
00208   return PointImp::stype();
00209 }
00210 
00211 bool ArcBCPAType::inherits( int type ) const
00212 {
00213   return Parent::inherits( type );
00214 }
00215 
00216 const ObjectImpType* ArcBCPAType::resultId() const
00217 {
00218   return ArcImp::stype();
00219 }
00220 
00221 /*
00222  * arc of conic by three points and center
00223  */
00224 
00225 static const char constructconicarcstartingstat[] = I18N_NOOP( "Construct a conic arc starting at this point" );
00226 static const char selectconicarcstartingstat[] = I18N_NOOP( "Select the start point of the new conic arc..." );
00227 static const char constructconicarcthrustat[] = I18N_NOOP( "Construct a conic arc through this point" );
00228 static const char selectconicarcthrustat[] = I18N_NOOP( "Select a point for the new conic arc to go through..." );
00229 static const char constructconicarcendingstat[] = I18N_NOOP( "Construct a conic arc ending at this point" );
00230 static const char selectconicarcendingstat[] = I18N_NOOP( "Select the end point of the new conic arc..." );
00231 
00232 static const ArgsParser::spec argsspecConicArcBCTP[] =
00233 {
00234   { PointImp::stype(), I18N_NOOP( "Construct an conic arc with this center" ),
00235     I18N_NOOP( "Select the center of the new conic arc..." ), false },
00236   { PointImp::stype(), constructconicarcstartingstat,
00237     selectconicarcstartingstat, true },
00238   { PointImp::stype(), constructconicarcthrustat,
00239     selectconicarcthrustat, true },
00240   { PointImp::stype(), constructconicarcendingstat,
00241     selectconicarcendingstat, true }
00242 };
00243 
00244 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConicArcBCTPType )
00245 
00246 ConicArcBCTPType::ConicArcBCTPType()
00247   : ArgsParserObjectType( "ConicArcBCTP", argsspecConicArcBCTP, 4 )
00248 {
00249 }
00250 
00251 ConicArcBCTPType::~ConicArcBCTPType()
00252 {
00253 }
00254 
00255 const ConicArcBCTPType* ConicArcBCTPType::instance()
00256 {
00257   static const ConicArcBCTPType t;
00258   return &t;
00259 }
00260 
00261 ObjectImp* ConicArcBCTPType::calc( const Args& args, const KigDocument& ) const
00262 {
00263   if ( ! margsparser.checkArgs( args, 2 ) )
00264     return new InvalidImp;
00265 
00266   const Coordinate center =
00267     static_cast<const PointImp*>( args[0] )->coordinate();
00268   const Coordinate a =
00269     static_cast<const PointImp*>( args[1] )->coordinate();
00270   const Coordinate d = 2*center - a;
00271   Coordinate b = center + (a-center).orthogonal();
00272   Coordinate e = 2*center - b;
00273   if ( args.size() >= 3 )
00274   {
00275     b = static_cast<const PointImp*>( args[2] )->coordinate();
00276     e = 2*center - b;
00277   }
00278   bool have_c = false;
00279   Coordinate c;
00280   if ( args.size() == 4 )
00281   {
00282     c = static_cast<const PointImp*>( args[3] )->coordinate();
00283     const Coordinate e = 2*center - c;
00284     have_c = true;
00285   }
00286 
00287   std::vector<Coordinate> points;
00288   points.push_back( a );
00289   points.push_back( b );
00290   if (have_c) points.push_back( c );
00291   points.push_back( d );
00292   points.push_back( e );
00293   ConicCartesianData cart =
00294     calcConicThroughPoints( points, zerotilt, circleifzt, ysymmetry );
00295   if ( ! d.valid() )
00296     return new InvalidImp;
00297 
00298   ConicArcImp *me = new ConicArcImp( cart, 0.0, 2*M_PI );
00299   double angle = 0.;
00300   double startangle = 0.;
00301   double anglea = 2*M_PI*me->getParam( a );
00302   double angleb = anglea + M_PI/2;
00303   angleb = 2*M_PI*me->getParam( b );
00304   double anglec = 2*angleb - anglea;
00305   if ( have_c ) anglec = 2*M_PI*me->getParam( c );
00306 
00307   // anglea should be smaller than anglec
00308   if ( anglea > anglec )
00309   {
00310     double t = anglea;
00311     anglea = anglec;
00312     anglec = t;
00313   };
00314   if ( angleb > anglec || angleb < anglea )
00315   {
00316     startangle = anglec;
00317     angle = 2 * M_PI + anglea - startangle;
00318   }
00319   else
00320   {
00321     startangle = anglea;
00322     angle = anglec - anglea;
00323   };
00324 
00325   me->setStartAngle( startangle );
00326   me->setAngle( angle );
00327   return me;
00328 }
00329 
00330 const ObjectImpType* ConicArcBCTPType::resultId() const
00331 {
00332   return ConicArcImp::stype();
00333 }
00334 
00335 /*
00336  * arc of conic by five points
00337  */
00338 
00339 static const ArgsParser::spec argsspecConicArcB5P[] =
00340 {
00341   { PointImp::stype(), constructconicarcstartingstat,
00342     selectconicarcstartingstat, true },
00343   { PointImp::stype(), constructconicarcthrustat,
00344     selectconicarcthrustat, true },
00345   { PointImp::stype(), constructconicarcthrustat,
00346     selectconicarcthrustat, true },
00347   { PointImp::stype(), constructconicarcthrustat,
00348     selectconicarcthrustat, true },
00349   { PointImp::stype(), constructconicarcendingstat,
00350     selectconicarcendingstat, true }
00351 };
00352 
00353 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConicArcB5PType )
00354 
00355 ConicArcB5PType::ConicArcB5PType()
00356   : ArgsParserObjectType( "ConicArcB5P", argsspecConicArcB5P, 5 )
00357 {
00358 }
00359 
00360 ConicArcB5PType::~ConicArcB5PType()
00361 {
00362 }
00363 
00364 const ConicArcB5PType* ConicArcB5PType::instance()
00365 {
00366   static const ConicArcB5PType t;
00367   return &t;
00368 }
00369 
00370 ObjectImp* ConicArcB5PType::calc( const Args& args, const KigDocument& ) const
00371 {
00372   if ( ! margsparser.checkArgs( args, 2 ) )
00373     return new InvalidImp;
00374 
00375   const Coordinate a =
00376     static_cast<const PointImp*>( args[0] )->coordinate();
00377   const Coordinate b =
00378     static_cast<const PointImp*>( args[1] )->coordinate();
00379 
00380   Coordinate c, d, e;
00381   bool have_c = false;
00382   bool have_d = false;
00383   bool have_e = false;
00384   if ( args.size() >= 3 )
00385   {
00386     c = static_cast<const PointImp*>( args[2] )->coordinate();
00387     have_c = true;
00388   }
00389   if ( args.size() >= 4 )
00390   {
00391     d = static_cast<const PointImp*>( args[3] )->coordinate();
00392     have_d = true;
00393   }
00394   if ( args.size() >= 5 )
00395   {
00396     e = static_cast<const PointImp*>( args[4] )->coordinate();
00397     have_e = true;
00398   }
00399 
00400   std::vector<Coordinate> points;
00401   points.push_back( a );
00402   points.push_back( b );
00403   if (have_c) points.push_back( c );
00404   if (have_d) points.push_back( d );
00405   if (have_e) points.push_back( e );
00406   ConicCartesianData cart =
00407     calcConicThroughPoints( points, zerotilt, circleifzt, ysymmetry );
00408   if ( ! d.valid() )
00409     return new InvalidImp;
00410 
00411   ConicArcImp *me = new ConicArcImp( cart, 0.0, 2*M_PI );
00412   double angle = 0.;
00413   double startangle = 0.;
00414   double anglea = 2*M_PI*me->getParam( a );
00415   double angleb = anglea + M_PI/2;
00416   angleb = 2*M_PI*me->getParam( b );
00417   if ( have_c ) angleb = 2*M_PI*me->getParam( c );
00418   double anglec = 2*angleb - anglea;
00419   if ( have_e ) anglec = 2*M_PI*me->getParam( e );
00420 
00421   // anglea should be smaller than anglec
00422   if ( anglea > anglec )
00423   {
00424     double t = anglea;
00425     anglea = anglec;
00426     anglec = t;
00427   };
00428   if ( angleb > anglec || angleb < anglea )
00429   {
00430     startangle = anglec;
00431     angle = 2 * M_PI + anglea - startangle;
00432   }
00433   else
00434   {
00435     startangle = anglea;
00436     angle = anglec - anglea;
00437   };
00438 
00439   me->setStartAngle( startangle );
00440   me->setAngle( angle );
00441   return me;
00442 }
00443 
00444 const ObjectImpType* ConicArcB5PType::resultId() const
00445 {
00446   return ConicArcImp::stype();
00447 }
00448 

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
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  •   docs
  •   src
  • parley
  •   stepcore
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