home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / flying-6.11 / vec2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-30  |  2.8 KB  |  125 lines

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