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

kig

conic_imp.cc

Go to the documentation of this file.
00001 // Copyright (C)  2003  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 "conic_imp.h"
00019 
00020 #include "bogus_imp.h"
00021 #include "point_imp.h"
00022 
00023 #include "../misc/kigpainter.h"
00024 #include "../misc/common.h"
00025 #include "../misc/coordinate_system.h"
00026 
00027 #include "../kig/kig_document.h"
00028 #include "../kig/kig_view.h"
00029 
00030 #include <klocale.h>
00031 
00032 ObjectImp* ConicImp::transform( const Transformation& t ) const
00033 {
00034   bool valid = true;
00035   ConicCartesianData d = calcConicTransformation( cartesianData(), t, valid );
00036   if ( ! valid ) return new InvalidImp;
00037   else return new ConicImpCart( d );
00038 }
00039 
00040 void ConicImp::draw( KigPainter& p ) const
00041 {
00042   p.drawCurve( this );
00043 }
00044 
00045 bool ConicImp::valid() const
00046 {
00047   return true;
00048 }
00049 
00050 bool ConicImp::contains( const Coordinate& o, int width, const KigWidget& w ) const
00051 {
00052   return internalContainsPoint( o, w.screenInfo().normalMiss( width ) );
00053 }
00054 
00055 bool ConicImp::inRect( const Rect&, int, const KigWidget& ) const
00056 {
00057   // TODO
00058   return false;
00059 }
00060 
00061 int ConicImp::numberOfProperties() const
00062 {
00063   return Parent::numberOfProperties() + 6;
00064 }
00065 
00066 const QByteArrayList ConicImp::propertiesInternalNames() const
00067 {
00068   QByteArrayList l = Parent::propertiesInternalNames();
00069   l << "type";
00070   l << "center";
00071   l << "first-focus";
00072   l << "second-focus";
00073   l << "cartesian-equation";
00074   l << "polar-equation";
00075   assert( l.size() == ConicImp::numberOfProperties() );
00076   return l;
00077 }
00078 
00079 const QByteArrayList ConicImp::properties() const
00080 {
00081   QByteArrayList l = Parent::properties();
00082   l << I18N_NOOP( "Conic Type" );
00083   l << I18N_NOOP( "Center" );
00084   l << I18N_NOOP( "First Focus" );
00085   l << I18N_NOOP( "Second Focus" );
00086   l << I18N_NOOP( "Cartesian Equation" );
00087   l << I18N_NOOP( "Polar Equation" );
00088   assert( l.size() == ConicImp::numberOfProperties() );
00089   return l;
00090 }
00091 
00092 const ObjectImpType* ConicImp::impRequirementForProperty( int which ) const
00093 {
00094   if ( which < Parent::numberOfProperties() )
00095     return Parent::impRequirementForProperty( which );
00096   else return ConicImp::stype();
00097 }
00098 
00099 const char* ConicImp::iconForProperty( int which ) const
00100 {
00101   int pnum = 0;
00102   if ( which < Parent::numberOfProperties() )
00103     return Parent::iconForProperty( which );
00104   if ( which == Parent::numberOfProperties() + pnum++ )
00105     return "kig_text"; // conic type string
00106   else if ( which == Parent::numberOfProperties() + pnum++ )
00107     return ""; // center
00108   else if ( which == Parent::numberOfProperties() + pnum++ )
00109     return ""; // focus1
00110   else if ( which == Parent::numberOfProperties() + pnum++ )
00111     return ""; // focus2
00112   else if ( which == Parent::numberOfProperties() + pnum++ )
00113     return "kig_text"; // cartesian equation string
00114   else if ( which == Parent::numberOfProperties() + pnum++ )
00115     return "kig_text"; // polar equation string
00116   else assert( false );
00117   return "";
00118 }
00119 
00120 ObjectImp* ConicImp::property( int which, const KigDocument& w ) const
00121 {
00122   int pnum = 0;
00123 
00124   if ( which < Parent::numberOfProperties() )
00125     return Parent::property( which, w );
00126   if ( which == Parent::numberOfProperties() + pnum++ )
00127     return new StringImp( conicTypeString() );
00128   else if ( which == Parent::numberOfProperties() + pnum++ )
00129     return new PointImp( coniccenter() );
00130   else if ( which == Parent::numberOfProperties() + pnum++ )
00131     return new PointImp( focus1() );
00132   else if ( which == Parent::numberOfProperties() + pnum++ )
00133     return new PointImp( focus2() );
00134   else if ( which == Parent::numberOfProperties() + pnum++ )
00135     return new StringImp( cartesianEquationString( w ) );
00136   else if ( which == Parent::numberOfProperties() + pnum++ )
00137     return new StringImp( polarEquationString( w ) );
00138   else assert( false );
00139   return new InvalidImp;
00140 }
00141 
00142 double ConicImp::getParam( const Coordinate& p, const KigDocument& ) const
00143 {
00144   return getParam( p );
00145 }
00146 
00147 double ConicImp::getParam( const Coordinate& p ) const
00148 {
00149   const ConicPolarData d = polarData();
00150   Coordinate tmp = p - d.focus1;
00151   double l = tmp.length();
00152   double theta = atan2(tmp.y, tmp.x);
00153   double costheta = cos(theta);
00154   double sintheta = sin(theta);
00155   double ecosthetamtheta0 = costheta*d.ecostheta0 + sintheta*d.esintheta0;
00156   double esinthetamtheta0 = sintheta*d.ecostheta0 - costheta*d.esintheta0;
00157   double oneplus = 1.0 + d.ecostheta0*d.ecostheta0 + d.esintheta0*d.esintheta0;
00158   double fact = esinthetamtheta0*(1.0 - ecosthetamtheta0)/(oneplus - 2*ecosthetamtheta0);
00159 // fact is sin(a)*cos(a) where a is the angle between the ray from the first
00160 // focus and the normal to the conic.  We need it in order to adjust the
00161 // angle according to the projection onto the conic of our point
00162   double rho1 = d.pdimen / (1 - ecosthetamtheta0);
00163   double rho2 = - d.pdimen / (1 + ecosthetamtheta0);
00164   if (fabs(rho1 - l) < fabs(rho2 - l))
00165   {
00166     theta += (rho1 - l)*fact/rho1;
00167     return fmod(theta / ( 2 * M_PI ) + 1, 1);
00168   } else {
00169     theta += (rho2 - l)*fact/rho2;
00170     return fmod(theta / ( 2 * M_PI ) + 0.5, 1);
00171   }
00172 }
00173 
00174 const Coordinate ConicImp::getPoint( double p, const KigDocument& ) const
00175 {
00176   return getPoint( p );
00177 }
00178 
00179 const Coordinate ConicImp::getPoint( double p ) const
00180 {
00181   const ConicPolarData d = polarData();
00182 
00183   double costheta = cos(p * 2 * M_PI);
00184   double sintheta = sin(p * 2 * M_PI);
00185   double rho = d.pdimen / (1 - costheta* d.ecostheta0 - sintheta* d.esintheta0);
00186   return d.focus1 + Coordinate (costheta, sintheta) * rho;
00187 }
00188 
00189 int ConicImp::conicType() const
00190 {
00191   const ConicPolarData d = polarData();
00192   double ec = d.ecostheta0;
00193   double es = d.esintheta0;
00194   double esquare = ec*ec + es*es;
00195   const double parabolamiss = 1e-3;  // don't know what a good value could be
00196 
00197   if (esquare < 1.0 - parabolamiss) return 1;
00198   if (esquare > 1.0 + parabolamiss) return -1;
00199 
00200   return 0;
00201 }
00202 
00203 QString ConicImp::conicTypeString() const
00204 {
00205   switch (conicType())
00206   {
00207   case 1:
00208     return i18n("Ellipse");
00209   case -1:
00210     return i18n("Hyperbola");
00211   case 0:
00212     return i18n("Parabola");
00213   default:
00214     assert( false );
00215     return "";
00216   }
00217 }
00218 
00219 QString ConicImp::cartesianEquationString( const KigDocument& ) const
00220 {
00221   ConicCartesianData data = cartesianData();
00222   EquationString ret = EquationString( "" );
00223   bool needsign = false;
00224   if ( isVerticalParabola( data ) )
00225   {
00226     double f = - 1.0/data.coeffs[4];
00227     ret.addTerm( - f*data.coeffs[4], ret.y(), needsign );
00228     ret.append( " = " );
00229     needsign = false;
00230     ret.addTerm( f*data.coeffs[0], ret.x2(), needsign );
00231     ret.addTerm( f*data.coeffs[1], ret.y2(), needsign );
00232     ret.addTerm( f*data.coeffs[2], ret.xy(), needsign );
00233     ret.addTerm( f*data.coeffs[3], ret.x(), needsign );
00234     ret.addTerm( f*data.coeffs[5], "", needsign );
00235     return ret;
00236   }
00237   ret.addTerm( data.coeffs[0], ret.x2(), needsign );
00238   ret.addTerm( data.coeffs[1], ret.y2(), needsign );
00239   ret.addTerm( data.coeffs[2], ret.xy(), needsign );
00240   ret.addTerm( data.coeffs[3], ret.x(), needsign );
00241   ret.addTerm( data.coeffs[4], ret.y(), needsign );
00242   ret.addTerm( data.coeffs[5], "", needsign );
00243   ret.append( " = 0" );
00244   return ret;
00245 
00246 //  QString ret = i18n( "%1 x² + %2 y² + %3 xy + %4 x + %5 y + %6 = 0" );
00247 //  ConicCartesianData data = cartesianData();
00248 //  ret = ret.arg( data.coeffs[0], 0, 'g', 3 );
00249 //  ret = ret.arg( data.coeffs[1], 0, 'g', 3 );
00250 //  ret = ret.arg( data.coeffs[2], 0, 'g', 3 );
00251 //  ret = ret.arg( data.coeffs[3], 0, 'g', 3 );
00252 //  ret = ret.arg( data.coeffs[4], 0, 'g', 3 );
00253 //  ret = ret.arg( data.coeffs[5], 0, 'g', 3 );
00254 //  return ret;
00255 }
00256 
00257 QString ConicImp::polarEquationString( const KigDocument& w ) const
00258 {
00259 //  QString ret = i18n( "rho = %1/(1 + %2 cos theta + %3 sin theta)\n    [centered at %4]" );
00260   const ConicPolarData data = polarData();
00261 
00262   EquationString ret = EquationString( i18n( "rho" ) );
00263   ret.append( " = " );
00264   if ( data.pdimen < 0 ) ret.append( "- " );
00265   bool needsign = false;
00266   ret.addTerm( fabs( data.pdimen ), "", needsign );
00267   ret.append( "/(1" );
00268   needsign = true;
00269   ret.addTerm( -data.ecostheta0, i18n( "cos theta" ), needsign );
00270   ret.addTerm( -data.esintheta0, i18n( "sin theta" ), needsign );
00271   ret.append( ")\n" );
00272   ret.append( ki18n( "[centered at %1]" )
00273                    .subs( w.coordinateSystem().fromScreen( data.focus1, w ) )
00274 //                   .subs( data.pdimen, 0, 'g', 3 );
00275 //                   .subs( -data.ecostheta0, 0, 'g', 3 );
00276 //                   .subs( -data.esintheta0, 0, 'g', 3 );
00277                    .toString() );
00278 
00279   ret.prettify();
00280   return ret;
00281 }
00282 
00283 const ConicCartesianData ConicImp::cartesianData() const
00284 {
00285   return ConicCartesianData( polarData() );
00286 }
00287 
00288 Coordinate ConicImp::focus1() const
00289 {
00290   return polarData().focus1;
00291 }
00292 
00293 Coordinate ConicImp::coniccenter() const
00294 {
00295   const ConicPolarData d = polarData();
00296   double ec = d.ecostheta0;
00297   double es = d.esintheta0;
00298 
00299   double fact = d.pdimen/(1 - ec*ec - es*es);
00300 
00301   return d.focus1 + fact*Coordinate(ec, es);
00302 }
00303 
00304 Coordinate ConicImp::focus2() const
00305 {
00306   const ConicPolarData d = polarData();
00307   double ec = d.ecostheta0;
00308   double es = d.esintheta0;
00309 
00310   double fact = 2*d.pdimen/(1 - ec*ec - es*es);
00311 
00312   return d.focus1 + fact*Coordinate(ec, es);
00313 }
00314 
00315 const ConicPolarData ConicImpCart::polarData() const
00316 {
00317   return mpolardata;
00318 }
00319 
00320 const ConicCartesianData ConicImpCart::cartesianData() const
00321 {
00322   return mcartdata;
00323 }
00324 
00325 ConicImpCart::ConicImpCart( const ConicCartesianData& data )
00326   : ConicImp(), mcartdata( data ), mpolardata( data )
00327 {
00328   //assert( data.valid() );
00329 }
00330 
00331 ConicImpPolar::ConicImpPolar( const ConicPolarData& data )
00332   : ConicImp(), mdata( data )
00333 {
00334 }
00335 
00336 ConicImpPolar::~ConicImpPolar()
00337 {
00338 }
00339 
00340 const ConicPolarData ConicImpPolar::polarData() const
00341 {
00342   return mdata;
00343 }
00344 
00345 ConicImpCart* ConicImpCart::copy() const
00346 {
00347   return new ConicImpCart( mcartdata );
00348 }
00349 
00350 ConicImpPolar* ConicImpPolar::copy() const
00351 {
00352   return new ConicImpPolar( mdata );
00353 }
00354 
00355 ConicImp::ConicImp()
00356 {
00357 }
00358 
00359 ConicImp::~ConicImp()
00360 {
00361 }
00362 
00363 ConicImpCart::~ConicImpCart()
00364 {
00365 }
00366 
00367 void ConicImp::visit( ObjectImpVisitor* vtor ) const
00368 {
00369   vtor->visit( this );
00370 }
00371 
00372 bool ConicImp::equals( const ObjectImp& rhs ) const
00373 {
00374   return rhs.inherits( ConicImp::stype() ) &&
00375     static_cast<const ConicImp&>( rhs ).polarData() == polarData();
00376 }
00377 
00378 const ObjectImpType* ConicImp::stype()
00379 {
00380   static const ObjectImpType t(
00381     Parent::stype(), "conic",
00382     I18N_NOOP( "conic" ),
00383     I18N_NOOP( "Select this conic" ),
00384     I18N_NOOP( "Select conic %1" ),
00385     I18N_NOOP( "Remove a Conic" ),
00386     I18N_NOOP( "Add a Conic" ),
00387     I18N_NOOP( "Move a Conic" ),
00388     I18N_NOOP( "Attach to this conic" ),
00389     I18N_NOOP( "Show a Conic" ),
00390     I18N_NOOP( "Hide a Conic" )
00391     );
00392   return &t;
00393 }
00394 
00395 const ObjectImpType* ConicImp::type() const
00396 {
00397   return ConicImp::stype();
00398 }
00399 
00400 bool ConicImp::containsPoint( const Coordinate& p, const KigDocument& ) const
00401 {
00402   const ConicPolarData d = polarData();
00403 
00404 // the threshold is relative to the size of the conic (mp)
00405   return internalContainsPoint( p, test_threshold*d.pdimen );
00406 }
00407 
00408 bool ConicImp::internalContainsPoint( const Coordinate& p, double threshold ) const
00409 {
00410   const ConicPolarData d = polarData();
00411 
00412   Coordinate focus1 = d.focus1;
00413   double ecostheta0 = d.ecostheta0;
00414   double esintheta0 = d.esintheta0;
00415   double pdimen = d.pdimen;
00416 
00417   Coordinate pos = p - focus1;
00418   double len = pos.length();
00419   double costheta = pos.x / len;
00420   double sintheta = pos.y / len;
00421 
00422   double ecosthetamtheta0 = costheta*ecostheta0 + sintheta*esintheta0;
00423   double rho = pdimen / (1.0 - ecosthetamtheta0);
00424 
00425   double oneplus = 1.0 + ecostheta0*ecostheta0 + esintheta0*esintheta0;
00426 
00427 // fact is the cosine of the angle between the ray from the first focus
00428 // and the normal to the conic, so that we compute the real distance
00429 
00430   double fact = (1.0 - ecosthetamtheta0)/sqrt(oneplus - 2*ecosthetamtheta0);
00431   if ( fabs((len - rho)*fact) <= threshold ) return true;
00432   rho = - pdimen / ( 1.0 + ecosthetamtheta0 );
00433   fact = (1.0 + ecosthetamtheta0)/sqrt(oneplus + 2*ecosthetamtheta0);
00434   return fabs(( len - rho )*fact) <= threshold;
00435 }
00436 
00437 bool ConicImp::isPropertyDefinedOnOrThroughThisImp( int which ) const
00438 {
00439   if ( which < Parent::numberOfProperties() )
00440     return Parent::isPropertyDefinedOnOrThroughThisImp( which );
00441   return false;
00442 }
00443 
00444 bool ConicImp::isVerticalParabola( ConicCartesianData& data ) const
00445 {
00446   return (
00447            fabs( data.coeffs[1] ) < 1e-12 &&     // y^2
00448            fabs( data.coeffs[2] ) < 1e-12 &&     // xy
00449            fabs( data.coeffs[4] ) > 1e-5 );      // y
00450 }
00451 
00452 Rect ConicImp::surroundingRect() const
00453 {
00454   // it's prolly possible to calculate this ( in the case that the
00455   // conic is limited in size ), but for now we don't.
00456 
00457   return Rect::invalidRect();
00458 }
00459 
00460 /* An arc of a conic is identified by a startangle and a size (angle);
00461  * both angles are measured with respect to the first focus of the conic
00462  * (the one used for the conic polar equation
00463  */
00464 
00465 ConicArcImp::ConicArcImp( const ConicCartesianData& data,
00466                   const double startangle, const double angle )
00467   : ConicImpCart( data ), msa( startangle ), ma( angle )
00468 {
00469 }
00470 
00471 ConicArcImp::~ConicArcImp()
00472 {
00473 }
00474 
00475 ConicArcImp* ConicArcImp::copy() const
00476 {
00477   return new ConicArcImp( mcartdata, msa, ma );
00478 }
00479 
00480 ObjectImp* ConicArcImp::transform( const Transformation& t ) const
00481 {
00482   bool valid = true;
00483   ConicCartesianData d = calcConicTransformation( cartesianData(), t, valid );
00484   if ( ! valid ) return new InvalidImp;
00485   ConicArcImp* result = new ConicArcImp( d, 0.0, 2*M_PI );
00486 
00487   Coordinate a = t.apply( getPoint ( 0. ) );
00488   Coordinate b = t.apply( getPoint( 0.5 ) );
00489   Coordinate c = t.apply( getPoint( 1. ) );
00490   double anglea = 2*M_PI*result->getParam( a );
00491   double angleb = 2*M_PI*result->getParam( b );
00492   double anglec = 2*M_PI*result->getParam( c );
00493   double startangle = 0.;
00494   double angle = 2*M_PI;
00495   // anglea should be smaller than anglec
00496   if ( anglea > anglec )
00497   {
00498     double t = anglea;
00499     anglea = anglec;
00500     anglec = t;
00501   };
00502   if ( angleb > anglec || angleb < anglea )
00503   {
00504     startangle = anglec;
00505     angle = 2 * M_PI + anglea - startangle;
00506   }
00507   else
00508   {
00509     startangle = anglea;
00510     angle = anglec - anglea;
00511   };
00512 
00513   result->setStartAngle( startangle );
00514   result->setAngle( angle );
00515   return result;
00516 }
00517 
00518 bool ConicArcImp::contains( const Coordinate& o, int width, const KigWidget& w ) const
00519 {
00520   return internalContainsPoint( o, w.screenInfo().normalMiss( width ),
00521      w.document() );
00522 }
00523 
00524 int ConicArcImp::numberOfProperties() const
00525 {
00526   return Parent::numberOfProperties() + 3;
00527 }
00528 
00529 const QByteArrayList ConicArcImp::properties() const
00530 {
00531   QByteArrayList ret = Parent::properties();
00532   ret << I18N_NOOP( "Supporting Conic" );
00533   ret << I18N_NOOP( "First End Point" );
00534   ret << I18N_NOOP( "Second End Point" );
00535   assert( ret.size() == ConicArcImp::numberOfProperties() );
00536   return ret;
00537 }
00538 
00539 const QByteArrayList ConicArcImp::propertiesInternalNames() const
00540 {
00541   QByteArrayList ret = Parent::propertiesInternalNames();
00542   ret << "support";
00543   ret << "end-point-A";
00544   ret << "end-point-B";
00545   return ret;
00546 }
00547 
00548 const char* ConicArcImp::iconForProperty( int which ) const
00549 {
00550   int numprop = 0;
00551   if ( which < Parent::numberOfProperties() )
00552     return Parent::iconForProperty( which );
00553   else if ( which == Parent::numberOfProperties() + numprop++ )
00554     return "";
00555   else if ( which == Parent::numberOfProperties() + numprop++ )
00556     return "";
00557   else if ( which == Parent::numberOfProperties() + numprop++ )
00558     return "";
00559   else assert( false );
00560   return "";
00561 }
00562 
00563 ObjectImp* ConicArcImp::property( int which, const KigDocument& d ) const
00564 {
00565   int numprop = 0;
00566   if ( which < Parent::numberOfProperties() )
00567     return Parent::property( which, d );
00568   else if ( which == Parent::numberOfProperties() + numprop++ )
00569     return new ConicImpCart( cartesianData() );
00570   else if ( which == Parent::numberOfProperties() + numprop++ )
00571     return new PointImp( firstEndPoint());
00572   else if ( which == Parent::numberOfProperties() + numprop++ )
00573     return new PointImp( secondEndPoint());
00574   else return new InvalidImp;
00575   return new InvalidImp;
00576 }
00577 
00578 bool ConicArcImp::isPropertyDefinedOnOrThroughThisImp( int which ) const
00579 {
00580   int pnum = 0;
00581 
00582   if ( which < Parent::numberOfProperties() )
00583     return Parent::isPropertyDefinedOnOrThroughThisImp( which );
00584   else if ( which == Parent::numberOfProperties() + pnum++ )
00585     return false;  // support
00586   else if ( which == Parent::numberOfProperties() + pnum++ )
00587     return true;   // first end-point
00588   else if ( which == Parent::numberOfProperties() + pnum++ )
00589     return true;   // second end-point
00590   else return false;
00591   return false;
00592 }
00593 
00594 Coordinate ConicArcImp::firstEndPoint() const
00595 {
00596   return getPoint( 0. );
00597 }
00598 
00599 Coordinate ConicArcImp::secondEndPoint() const
00600 {
00601   return getPoint( 1. );
00602 }
00603 
00604 const ObjectImpType* ConicArcImp::stype()
00605 {
00606   static const ObjectImpType t(
00607     Parent::stype(), "conic arc",
00608     I18N_NOOP( "conic arc" ),
00609     I18N_NOOP( "Select this conic arc" ),
00610     I18N_NOOP( "Select conic arc %1" ),
00611     I18N_NOOP( "Remove a Conic Arc" ),
00612     I18N_NOOP( "Add a Conic Arc" ),
00613     I18N_NOOP( "Move a Conic Arc" ),
00614     I18N_NOOP( "Attach to this conic arc" ),
00615     I18N_NOOP( "Show a Conic Arc" ),
00616     I18N_NOOP( "Hide a Conic Arc" )
00617     );
00618   return &t;
00619 }
00620 
00621 const ObjectImpType* ConicArcImp::type() const
00622 {
00623   return ConicArcImp::stype();
00624 }
00625 
00626 bool ConicArcImp::containsPoint( const Coordinate& p, const KigDocument& doc) const
00627 {
00628   const ConicPolarData d = polarData();
00629 
00630 // the threshold is relative to the size of the conic (mp)
00631   return internalContainsPoint( p, test_threshold*d.pdimen, doc );
00632 }
00633 
00634 bool ConicArcImp::internalContainsPoint( const Coordinate& p, double threshold,
00635     const KigDocument& doc ) const
00636 {
00637   // this is directly stolen from locus code...
00638   double param = getParam( p, doc );
00639   Coordinate p1 = getPoint( param, doc );
00640   double dist = (p1 - p).length();
00641   return fabs( dist ) <= threshold;
00642 }
00643 
00644 double ConicArcImp::getParam( const Coordinate& p, const KigDocument& ) const
00645 {
00646   return getParam( p );
00647 }
00648 
00649 double ConicArcImp::getParam( const Coordinate& p ) const
00650 {
00651   double thetarel = 2 * M_PI * ConicImpCart::getParam( p ) - msa;
00652   while ( thetarel < 0 ) thetarel += 2 * M_PI;
00653   if ( thetarel <= ma ) return ( thetarel / ma );
00654 
00655   double antipodo = ( 2 * M_PI + ma )/2;
00656   if ( thetarel < antipodo ) return (1.0);
00657   return (0.0);
00658 }
00659 
00660 const Coordinate ConicArcImp::getPoint( double p, const KigDocument& ) const
00661 {
00662   return getPoint( p );
00663 }
00664 
00665 const Coordinate ConicArcImp::getPoint( double p ) const
00666 {
00667   double pwide = ( p * ma + msa )/ (2*M_PI);
00668   return ConicImpCart::getPoint( pwide );
00669 }
00670 

kig

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