home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xjig / vec2.c < prev    next >
C/C++ Source or Header  |  1997-12-31  |  3KB  |  144 lines

  1. #ifndef _global_h
  2. #    include "global.h"
  3. #endif
  4.  
  5. #ifndef _mat2_h
  6. #       include "mat2.h"
  7. #endif
  8.  
  9. #ifndef _vec2_h
  10. #    include "vec2.h"
  11. #endif
  12.  
  13.  
  14. Vec2 Vec2Zero( RealZero, RealZero );
  15.  
  16. //
  17. // Aufsplittung des Vektors in 2 Vektoren parallel und vertikal zum
  18. // Richtungsvektor d. Dazu wird folgendes Gleichungssytem gel÷st:
  19. //
  20. //       vx        dx        -dy
  21. //      (  ) =    l *(  ) + u *(   )
  22. //     vy        dy         dx
  23. //
  24. //     V()  =   x     +   y
  25. //
  26. void Vec2::Split( const Vec2 &d, Vec2 *vx, Vec2 *vy ) const
  27. {
  28. Real    l,u;
  29.  
  30.     if (d.Y()!=RealZero) {
  31.         l  = (   Y() + (   X() * d.X() / d.Y() ) )
  32.             / ( d.Y() + ( d.X() * d.X() / d.Y() ) );
  33.         u  = ( l * d.X() - X() ) / d.Y();
  34.         *vx = Vec2( l*  d.X() , l*d.Y() );
  35.         *vy = Vec2( u*(-d.Y()), u*d.X() );
  36.     }
  37.     else {
  38.         if (d.X()!=RealZero) {
  39.             *vx = Vec2( X(), RealZero );        // parallel zur X-Achse
  40.             *vy = Vec2(RealZero, Y() );
  41.         }
  42.         else {
  43.             *vx = *this;                    // keine Richtung -> gesamter Vektor ist x
  44.             *vy = Vec2Zero;
  45.         }
  46.     }
  47. }
  48.  
  49. //
  50. // Analog zur kompletten Aufsplittung wird in der folgenden
  51. // Version von split nur der parallele Anteil zurⁿckgeliefert.
  52. //
  53. void Vec2::Split( const Vec2 &d, Vec2 *vx ) const
  54. {
  55. Real    l;
  56.  
  57.     if (d.Y()!=RealZero) {
  58.         l  = (   Y() + (   X() * d.X() / d.Y() ) )
  59.             / ( d.Y() + ( d.X() * d.X() / d.Y() ) );
  60.         *vx = Vec2( l*  d.X() , l*d.Y() );
  61.     }
  62.     else {
  63.         if (d.X()!=RealZero) {
  64.             *vx = Vec2( X(), RealZero );        // parallel zur X-Achse
  65.         }
  66.         else {
  67.             *vx = *this;                    // keine Richtung -> gesamter Vektor ist x
  68.         }
  69.     }
  70. }
  71.  
  72.  
  73. //
  74. // Berechnung des Winkels, den der angegebene Punkt zur aktuellen Korrdinate
  75. // hat. Ergebnis liegt zwischen 0 und 2*M_PI
  76. //
  77. Real Vec2::AngleRadial( const Vec2 &d ) const
  78. {
  79. Real    erg;
  80. Real    dx=d.X()-X();
  81. Real    dy=d.Y()-Y();
  82. Real    fdx=fabs(dx);
  83. Real    fdy=fabs(dy);
  84.  
  85.     if (fdx>fdy) {
  86.         if (fdx>1e-10)        erg = atan( -dy/dx );
  87.         else                    erg = (dy<0)?M_PI_2:3*M_PI_2;        // Fehler behoben ???
  88.  
  89.         if (dx<0)            erg+= M_PI;
  90.     }
  91.     else {
  92.         if (fdy>1e-10)        erg = atan( dx/dy );
  93.         else                    erg = (dx>0)?M_PI_2:3*M_PI_2;        // Fehler behoben ???
  94.  
  95.         if (dy<0)            erg+= M_PI;
  96.         erg-=M_PI_2;
  97.     }
  98.     if (erg<RealZero)        erg+= 2*M_PI;
  99.     return erg;
  100. }
  101.  
  102. Vec2 Vec2::TurnAngleRad( const Real &angle ) const
  103. {
  104.     if (!IsZero()) {
  105.             Real    len = Norm();
  106.             Real    ang = Vec2Zero.AngleRadial(*this) + angle;
  107.  
  108.             return Vec2( len*cos(ang), -len*sin(ang) );
  109.     }
  110.     else    return *this;
  111. }
  112.  
  113. //
  114. // L÷sung des Gleichungssystems:    p1+t1*d1 = p2+t2*d2
  115. // nach den beiden "Zeiten" t1 und t2
  116. //
  117. int Vec2::Solve(    const Vec2 &p1, const Vec2 &d1,
  118.                             const Vec2 &p2, const Vec2 &d2, Real *t1 )
  119. {
  120.         if (d1.X()!=RealZero) {
  121.             Real div = d2.Y()-d2.X()/d1.X()*d1.Y();
  122.             if (div==RealZero)        { *t1=RealZero; return 1; }        // parallel
  123.             *t1 = ( p1.Y()-p2.Y()+
  124.                     (p2.X()-p1.X())/d1.X()*d1.Y() )
  125.                     / div;
  126.         }
  127.         else {
  128.             Real div = d2.X()    /* -d2.Y()/d1.Y()*d1.X() */;
  129.             if (div==RealZero)        { *t1=RealZero; return 1; }        // parallel
  130.             *t1 = ( p1.X()-p2.X()
  131.                     /* + (p2.Y()-p1.Y())/d1.Y()*d1.X() */ )
  132.                     / div;
  133.         }
  134.         return 0;                                            // Ergebnis ok.
  135. }
  136.  
  137. #if (0)
  138. int Vec2::Project( const Vec2 &p1, const Vec2 &d1,
  139.                             const Vec2 &p2, Real *t1 )
  140. {
  141.     return Solve(p1,d1,p2,d1.TurnLeft(),t1);
  142. }
  143. #endif
  144.