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
StaticArc(double x,double y,double r_in,double start_in,double angle_in)21 StaticArc::StaticArc( double x, double y, double r_in, double start_in, double angle_in )
22 : p( x, y )
23 {
24 type = StaticArcObj;
25 this->r = r_in;
26 this->start = start_in;
27 this->angle = angle_in;
28 }
StaticArc(const Vec2 & v,const Real & r_in,const Real & start_in,const Real & angle_in)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 }
~StaticArc()35 StaticArc::~StaticArc() { }
36
HitFromBallTwice(int outer_hit,Ball * b,const Vec2 & dv,Real md,Real * time_out)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
IsOnArc(const Vec2 & d)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
CollideWithBall(Ball * b)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
Info()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
OuterHitFromBall(Ball * b,const Vec2 & dv)101 Real StaticArc::OuterHitFromBall( Ball *b, const Vec2 &dv ) {
102 Real otime;
103
104 switch( HitFromBallTwice( 1, b, dv, R()+b->R(), &otime ) ) {
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 (otime>-EPS) return otime;
113 else return NO_HIT;
114 }
115 }
116
InnerHitFromBall(Ball * b,const Vec2 & dv)117 Real StaticArc::InnerHitFromBall( Ball *b, const Vec2 &dv ) {
118 Real itime;
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(), &itime )) {
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 (itime>-EPS) return itime;
131 else return NO_HIT;
132 }
133 }
134
135 //
136 // class OuterArc
137 //
~OuterArc()138 OuterArc::~OuterArc() {}
139
Info()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
HitFromBall(Ball * b)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 //
~InnerArc()155 InnerArc::~InnerArc() {}
156
Info()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
HitFromBall(Ball * b)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 //
~ArcWall()172 ArcWall::~ArcWall() {}
173
Info()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
HitFromBall(Ball * b)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 //
Info()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
~StaticBall()204 StaticBall::~StaticBall() {}
205