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

  1. #ifndef _global_h
  2. #    include "global.h"
  3. #endif
  4.  
  5. #ifndef _arcs_h
  6. #    include "arcs.h"
  7. #endif
  8. #ifndef _ball_h
  9. #    include "ball.h"
  10. #endif
  11. #ifndef _game_h
  12. #    include "game.h"
  13. #endif
  14.  
  15. //
  16. // ============================================================================
  17. // class StaticArc
  18. // ============================================================================
  19. //
  20.  
  21. StaticArc::StaticArc( double x, double y, double r, double start, double angle )
  22. : p( x, y )
  23. {
  24.     type            = StaticArcObj;
  25.     this->r     = r;
  26.     this->start = start;
  27.     this->angle = angle;
  28. }
  29. StaticArc::StaticArc( const Vec2 &v, const Real &r_in,
  30.                                         const Real &start_in, const Real &angle_in )
  31. : p( v ), r(r_in), start(start_in), angle(angle_in)
  32. {
  33.     type            = StaticArcObj;
  34. }
  35. StaticArc::~StaticArc() { }
  36.  
  37. int StaticArc::HitFromBallTwice( int outer_hit, Ball *b, const Vec2 &dv,
  38.                                             Real md, Real *time_out )
  39. {
  40.     Vec2    d  = P() - b->P();                // Abstandsvektor
  41.  
  42. #if (ABORT_CALC_BALL)
  43. //
  44. // Abstand mit maximal Geschwindigkeitsbetrag vergleichen
  45. //
  46.         if ( (d.Norm()-md)/sqrt(sq)>b->collision_time-current_time+EPS)
  47.                                                                                         return 2;
  48. #endif
  49.  
  50.     Real    m  = (d.X()*dv.X()+d.Y()*dv.Y());
  51.             if (outer_hit&&(m<-EPS))        return 1;
  52.  
  53.     Real    sq = dv.SqrNorm();
  54.             if (sq<EPS)                            return 1;
  55.  
  56.             m /= sq;
  57.     Real    f  = (md*md-d.SqrNorm())/sq + (m*m);
  58.             if (f<=0.0)                            return 1;
  59.             f = sqrt(f);
  60.  
  61.     Real    f1 =  f+m;
  62.     Real    f2 = -f+m;
  63.  
  64.             if (f1<f2) {    *time_out = (outer_hit)?f1:f2;    }
  65.             else {            *time_out = (outer_hit)?f2:f1;    }
  66.  
  67.             return 0;
  68. }
  69.  
  70. int StaticArc::IsOnArc( const Vec2 &d )
  71. {
  72. Real    a = P().AngleDeg(d);
  73.  
  74.         a-=start;
  75.         if ( angle>=0.0 ) {
  76.             if (a<0.0)        a+=360.0;
  77.             return ( (a>=0.0)&&(a<=angle) )?1:0;
  78.         }
  79.         else {
  80.             if (a>0.0)        a-=360.0;
  81.             return ( (a<=0.0)&&(a>=angle) )?1:0;
  82.         }
  83. }
  84.  
  85. void StaticArc::CollideWithBall( Ball *b ) {
  86. Vec2    x, y;
  87. Vec2    dist=P()-b->P();
  88.  
  89.     g->HitWall(b);
  90.     b->V().Split( dist, &x, &y );            // Ball b wird direkt zurⁿckgesto▀en
  91.     b->SetV( y-x );
  92. }
  93.  
  94. void StaticArc::Info() {
  95.     printf( "%02d: StaticArc: %08lx: P()=(%4.1f,%4.1f), R()=%3.1f, %f-%f\n",
  96.                 id, (unsigned long)this,
  97.                 (double)PX(), (double)PY(), (double)R(),
  98.                 (double)start, (double)angle );
  99. }
  100.  
  101. Real StaticArc::OuterHitFromBall( Ball *b, const Vec2 &dv ) {
  102. Real    time;
  103.  
  104.     switch( HitFromBallTwice( 1, b, dv, R()+b->R(), &time ) ) {
  105.     case 1:        return NO_HIT;
  106. #if (ABORT_CALC_BALL)
  107.     case 2:
  108.                 DBG2(AbortCalc,"    OuterHit from %d to %d aborted.\n", b->Object::id, id );
  109.                 return NOT_REACHABLE;
  110. #endif
  111.     default:
  112.         if (time>-EPS)    return time;
  113.         else                return NO_HIT;
  114.     }
  115. }
  116.  
  117. Real StaticArc::InnerHitFromBall( Ball *b, const Vec2 &dv ) {
  118. Real    time;
  119.  
  120.     if (b->R()>r)        return NO_HIT;    // Ball zu gro▀ fⁿr inneren Treffer
  121.  
  122.     switch (HitFromBallTwice( 0, b, dv, R()-b->R(), &time )) {
  123.     case 1:        return NO_HIT;
  124. #if (ABORT_CALC_BALL)
  125.     case 2:
  126.                 DBG2(AbortCalc,"    InnerHit from %d to %d aborted.\n", b->Object::id, id );
  127.                 return NOT_REACHABLE;
  128. #endif
  129.     default:
  130.         if (time>-EPS)    return time;
  131.         else                return NO_HIT;
  132.     }
  133. }
  134.  
  135. //
  136. // class OuterArc
  137. //
  138. OuterArc::~OuterArc()        {}
  139.  
  140. void OuterArc::Info() {
  141.     printf( "%02d: OuterArc:   %08lx: P()=(%4.1f,%4.1f), R()=%3.1f, %f-%f\n",
  142.                 id, (unsigned long)this,
  143.                 (double)PX(), (double)PY(), (double)R(),
  144.                 (double)start, (double)angle );
  145. }
  146.  
  147. Real OuterArc::HitFromBall( Ball *b ) {
  148.     if (b->IsIdle())        return MAX_TIME;
  149.     return OuterHitFromBall(b,b->V());
  150. }
  151.  
  152. //
  153. // class InnerArc
  154. //
  155. InnerArc::~InnerArc()    {}
  156.  
  157. void InnerArc::Info() {
  158.     printf( "%02d: InnerArc:   %08lx: P()=(%4.1f,%4.1f), R()=%3.1f, %f-%f\n",
  159.                 id, (unsigned long)this,
  160.                 (double)PX(), (double)PY(), (double)R(),
  161.                 (double)start, (double)angle );
  162. }
  163.  
  164. Real InnerArc::HitFromBall( Ball *b ) {
  165.     if (b->IsIdle())        return MAX_TIME;
  166.     return InnerHitFromBall(b,b->V());
  167. }
  168.  
  169. //
  170. // class ArcWall
  171. //
  172. ArcWall::~ArcWall()    {}
  173.  
  174. void ArcWall::Info() {
  175.     printf( "%02d: ArcWall:    %08lx: P()=(%4.1f,%4.1f), R()=%3.1f, %f-%f\n",
  176.                 id, (unsigned long)this,
  177.                 (double)PX(), (double)PY(), (double)R(),
  178.                 (double)start, (double)angle );
  179. }
  180.  
  181. Real ArcWall::HitFromBall( Ball *b ) {
  182. Real    itime, otime;
  183.  
  184.     if (b->IsIdle())        return MAX_TIME;
  185.  
  186.     itime = InnerHitFromBall(b,b->V());
  187.     if ( (itime<NO_HIT)&&(!IsOnArc(b->P()+itime*b->V())))    itime = NO_HIT;
  188.     otime = OuterHitFromBall(b,b->V());
  189.     if ( (otime<NO_HIT)&&(!IsOnArc(b->P()+otime*b->V())))    otime = NO_HIT;
  190.     return( (itime<otime)?itime:otime );
  191. }
  192.  
  193. //
  194. // ============================================================================
  195. // class StaticBall, unbewegliche Kugel (unendlicher Masse)
  196. // ============================================================================
  197. //
  198. void StaticBall::Info() {
  199.     printf( "%02d: StaticBall: %08lx: P()=(%4.1f,%4.1f), R()=%3.1f\n",
  200.                 id, (unsigned long)this,
  201.                 (double)PX(), (double)PY(), (double)R() );
  202. }
  203.  
  204. StaticBall::~StaticBall()    {}
  205.