HOG2
Airplane.cpp
Go to the documentation of this file.
1 //
2 // Airplane.cpp
3 // hog2 glut
4 //
5 // Created by Nathan Sturtevant on 5/4/16.
6 // Copyright © 2016 University of Denver. All rights reserved.
7 //
8 
9 #include <stdio.h>
10 #include "Airplane.h"
11 
12 bool operator==(const airplaneState &s1, const airplaneState &s2)
13 {
14  return (s1.x == s2.x && s1.y == s2.y && s1.height == s2.height && s1.speed == s2.speed && s1.heading == s2.heading);
15 }
16 
17 
19 {
20  srandom(time(0));
21  ground.resize((width+1)*(length+1));
22  groundNormals.resize((width+1)*(length+1));
23  int value = random()%255;
24  int offset = 5;
25  int steps = 5;
26 
27  // initial strip
28  for (int x = 0; x <= width; x++)
29  {
30  SetGround(x, 0, std::max(std::min(255, value), 0));
31  value += offset;
32  steps--;
33  if (steps == 0)
34  {
35  offset = (random()%70)-35;
36  steps = random()%10;
37  }
38  }
39 
40  for (int y = 1; y <= length; y++)
41  {
42  value = GetGround(0, y-1);
43  offset = (random()%70)-35;
44  if (y > 1)
45  offset = GetGround(0, y-2)-GetGround(0, y-1);
46  steps = random()%10;
47 
48  for (int x = 0; x <= width; x++)
49  {
50  SetGround(x, y, std::max(std::min(255, value), 0));
51  value += offset;
52  steps--;
53  if (steps == 0)
54  {
55  offset = (random()%70)-35;
56  steps = random()%10;
57  }
58  if (abs(value-GetGround(x, y-1)) > 35)
59  value = value/2 + GetGround(x, y-1)/2;
60  }
61  }
62  // smooth
63  std::vector<int> tmp((width+1)*(length+1));
64  int maxVal = 0;
65  for (int y = 0; y < length; y++)
66  {
67  for (int x = 0; x <= width; x++)
68  {
69  int sum = 0;
70  int cnt = 0;
71  for (int dx = -1; dx <= 1; dx++)
72  {
73  for (int dy = -1; dy <= 1; dy++)
74  {
75  if (Valid(x+dx, y+dy))
76  {
77  sum += GetGround(x+dx, y+dy);
78  cnt++;
79  }
80  }
81  }
82  tmp[x+y*(length+1)] = sum/cnt;
83  maxVal = std::max(sum/cnt, maxVal);
84  }
85  }
86  // extend
87  for (int y = 0; y < length; y++)
88  {
89  for (int x = 0; x <= width; x++)
90  {
91  SetGround(x, y, (255*tmp[x+y*(length+1)])/maxVal);
92  }
93  }
94 
95 
96  // build normals
97  for (int y = 0; y < length; y++)
98  {
99  for (int x = 0; x <= width; x++)
100  {
101  if (x < width)
102  {
103  recVec a = GetCoordinate(x, y, std::max((int)GetGround(x, y), 20));
104  recVec b = GetCoordinate(x, y+1, std::max((int)GetGround(x, y+1), 20));
105  recVec d = GetCoordinate(x+1, y, std::max((int)GetGround(x+1, y), 20));
106  recVec n = (a-b).GetNormal(a-d);
107  GetNormal(x, y) += n;
108  GetNormal(x, y+1) += n;
109  GetNormal(x+1, y) += n;
110  }
111  if (x > 0)
112  {
113  recVec a = GetCoordinate(x, y, std::max((int)GetGround(x, y), 20));
114  recVec b = GetCoordinate(x-1, y+1, std::max((int)GetGround(x-1, y+1), 20));
115  recVec d = GetCoordinate(x, y+1, std::max((int)GetGround(x, y+1), 20));
116  recVec n = (a-b).GetNormal(a-d);
117  GetNormal(x, y) += n;
118  GetNormal(x-1, y+1) += n;
119  GetNormal(x, y+1) += n;
120  }
121  }
122  }
123  for (int y = 0; y <= length; y++)
124  {
125  for (int x = 0; x <= width; x++)
126  {
127  GetNormal(x, y).normalise();
128  }
129  }
130 
131 
132 
133  //SetGround(x, y, (random()%60)-30+255*(sin(0.01*cos(x*y+y^2+3))+sin(0.04*sin(x+y))+2.0)/4.0);
134  //SetGround(x, y, random()%255);
135 
136 // for (int y = 0; y <= length; y++)
137 // {
138 // for (int x = 0; x <= width; x++)
139 // {
140 // if (x < width && y < length)
141 // SetGround(x, y, (GetGround(x, y)+GetGround(x+1, y)+GetGround(x, y+1))/3.0);
142 // else if (x > 0 && y > 0)
143 // SetGround(x, y, (GetGround(x, y)+GetGround(x-1, y)+GetGround(x, y-1))/3.0);
144 // else if (x > 0)
145 // SetGround(x, y, (GetGround(x, y)+GetGround(x-1, y))/2.0);
146 // else if (y > 0)
147 // SetGround(x, y, (GetGround(x, y)+GetGround(x, y-1))/2.0);
148 // }
149 // }
150 
151  // set 0,0 width,width length,0 length,width
152 // SetGround(0, 0, random()%256);
153 // SetGround(width, 0, random()%256);
154 // SetGround(0, length, random()%256);
155 // SetGround(width, length, random()%256);
156 // RecurseGround(0, 0, width+1, length+1);
157 }
158 
159 void AirplaneEnvironment::SetGround(int x, int y, uint8_t val)
160 {
161  ground[x + y*(length+1)] = val;
162 }
163 
164 uint8_t AirplaneEnvironment::GetGround(int x, int y) const
165 {
166  return ground[x + y*(length+1)];
167 }
168 
169 bool AirplaneEnvironment::Valid(int x, int y)
170 {
171  return x >= 0 && x <= width && y >= 0 && y <= length;
172 }
173 
174 
176 {
177  return groundNormals[x + y*(length+1)];
178 }
179 
181 {
182  return groundNormals[x + y*(length+1)];
183 }
184 
185 void AirplaneEnvironment::RecurseGround(int x1, int y1, int x2, int y2)
186 {
187  if (x1 >= x2-1 || y1 >= y2-1)
188  return;
189  int middlex = (x1+x2)/2;
190  int middley = (y1+y2)/2;
191  SetGround(middlex, y1, GetGround(x1, y1)/2+GetGround(x2, y1)/2+random()%(x2/2-x1/2)-(x2-x1)/4);
192  SetGround(middlex, middley, GetGround(x1, y1)/2+GetGround(x2, y2)/2+random()%(x2/2-x1/2)-(x2-x1)/4);
193  SetGround(middlex, y2, GetGround(x1, y2)/2+GetGround(x2, y2)/2+random()%(x2/2-x1/2)-(x2-x1)/4);
194  SetGround(x1, middley, GetGround(x1, y1)/2+GetGround(x1, y2)/2+random()%(y2/2-y1/2)-(y2-y1)/4);
195  SetGround(x2, middley, GetGround(x2, y1)/2+GetGround(x2, y2)/2+random()%(y2/2-y1/2)-(y2-y1)/4);
196  RecurseGround(x1, y1, middlex, middley);
197  RecurseGround(middlex, y1, x2, middley);
198  RecurseGround(x1, middley, middlex, y2);
199  RecurseGround(middlex, middley, x2, y2);
200 }
201 
202 
203 void AirplaneEnvironment::GetSuccessors(const airplaneState &nodeID, std::vector<airplaneState> &neighbors) const
204 {
205  GetActions(nodeID, internalActions);
206  for (auto &act : internalActions)
207  {
208  airplaneState s;
209  GetNextState(nodeID, act, s);
210  neighbors.push_back(s);
211  }
212 }
213 
214 void AirplaneEnvironment::GetActions(const airplaneState &nodeID, std::vector<airplaneAction> &actions) const
215 {
216  // 45, 90, 0, shift
217  // speed:
218  // faster, slower
219  // height:
220  // up / down
221  actions.resize(0);
222 
223  actions.push_back(airplaneAction(0, 0, 0));
224  // increase height
225  if (nodeID.height > 1)
226  actions.push_back(airplaneAction(0, 0, -1));
227  if (nodeID.height < 20)
228  actions.push_back(airplaneAction(0, 0, +1));
229 
230  // each type of turn
231  actions.push_back(airplaneAction(k45, 0, 0));
232  actions.push_back(airplaneAction(-k45, 0, 0));
233  actions.push_back(airplaneAction(k90, 0, 0));
234  actions.push_back(airplaneAction(-k90, 0, 0));
235  actions.push_back(airplaneAction(kShift, 0, 0));
236  actions.push_back(airplaneAction(-kShift, 0, 0));
237 }
238 
240 {
241  int offset[8][2] =
242  {
243  { 0, -1},
244  { 1, -1},
245  { 1, 0},
246  { 1, 1},
247  { 0, 1},
248  {-1, 1},
249  {-1, 0},
250  {-1, -1}};
251  if (dir.height != 0)
252  {
253  s.height += dir.height;
254  s.x += offset[s.heading][0];
255  s.y += offset[s.heading][1];
256  }
257  else if (dir.turn == k45 || dir.turn == -k45)
258  {
259  s.heading = (s.heading+8+dir.turn)%8;
260  s.x += offset[s.heading][0];
261  s.y += offset[s.heading][1];
262  }
263  else if (dir.turn == 0) // continue in same direction
264  {
265  s.x += offset[s.heading][0];
266  s.y += offset[s.heading][1];
267  }
268  else if (dir.turn == k90 || dir.turn == -k90)
269  {
270  s.x += offset[s.heading][0];
271  s.y += offset[s.heading][1];
272  s.heading = (s.heading+8+dir.turn)%8;
273  s.x += offset[s.heading][0];
274  s.y += offset[s.heading][1];
275  }
276 
277 }
278 
280 {
281  // not available
282  assert(false);
283 }
284 
286 {
287  news = currents;
288  ApplyAction(news, dir);
289 }
290 
291 
292 
293 double AirplaneEnvironment::HCost(const airplaneState &node1, const airplaneState &node2) const
294 {
295  return 1;
296 }
297 
298 double AirplaneEnvironment::GCost(const airplaneState &node1, const airplaneState &node2) const
299 {
300  return 1;
301 }
302 
303 double AirplaneEnvironment::GCost(const airplaneState &node1, const airplaneAction &act) const
304 {
305  return 1;
306 }
307 
308 
310 {
311  return false;
312 }
313 
315 {
316  return 0;
317 }
318 
320 {
321  return 0;
322 }
323 
324 recVec AirplaneEnvironment::GetCoordinate(int x, int y, int z) const
325 {
326  return {(x-width/2.0)/(width/2.0), (y-width/2.0)/(width/2.0), -4.0*z/(255.0*80)};
327 }
328 
330 {
331  glEnable(GL_LIGHTING);
332  for (int y = 0; y < length; y++)
333  {
334  glBegin(GL_TRIANGLE_STRIP);
335  for (int x = 0; x <= width; x++)
336  {
337  rgbColor c;
338 
339  recVec a = GetCoordinate(x, y, std::max((int)GetGround(x, y), 20));
340  recVec b = GetCoordinate(x, y+1, std::max((int)GetGround(x, y+1), 20));
341 
342  //DoNormal(b-a, d-a);
343 
344  if (GetGround(x, y) <= 20)
345  {
346  glColor3f(0, 0, 1);
347  }
348  else {
349  c = Colors::GetColor(GetGround(x, y), 0, 255, 5);
350  glColor3f(c.r, c.g, c.b);
351  }
352  recVec tmp = GetNormal(x, y);
353  glNormal3f(tmp.x, tmp.y, tmp.z);
354  glVertex3f(a.x, a.y, a.z);
355 
356  if (GetGround(x, y+1) < 20)
357  {
358  glColor3f(0, 0, 1);
359  }
360  else {
361  c = Colors::GetColor(GetGround(x, y+1), 0, 255, 5);
362  glColor3f(c.r, c.g, c.b);
363  }
364  tmp = GetNormal(x, y+1);
365  glNormal3f(tmp.x, tmp.y, tmp.z);
366  glVertex3f(b.x, b.y, b.z);
367  }
368  glEnd(); // ground up to 5k feet (1 mile = 4 out of 20)
369  }
370  glDisable(GL_LIGHTING);
371  glColor3f(1.0, 1.0, 1.0);
372  DrawBoxFrame(0, 0, 0.75, 1.0);
373 }
374 
376 {
377  {
378  GLfloat r, g, b, t;
379  GetColor(r, g, b, t);
380  glColor3f(r, g, b);
381  }
382  // x & y range from 20*4 = 0 to 80 = -1 to +1
383  // z ranges from 0 to 20 which is 0...
384  GLfloat x = (l.x-40.0)/40.0;
385  GLfloat y = (l.y-40.0)/40.0;
386  GLfloat z = -l.height/80.0;
387  glEnable(GL_LIGHTING);
388  glPushMatrix();
389  glTranslatef(x, y, z);
390  glRotatef(360*l.heading/8.0, 0, 0, 1);
391  DrawCylinder(0, 0, 0, 0, 0.01/5.0, 0.01);
392  glPopMatrix();
393 
394  //DrawCylinder(l.x, l.y, l.height, 0, 0.001, 0.01);
395 }
396 
397 void AirplaneEnvironment::OpenGLDraw(const airplaneState& o, const airplaneState &n, float perc) const
398 {
399  {
400  GLfloat r, g, b, t;
401  GetColor(r, g, b, t);
402  glColor3f(r, g, b);
403  }
404 
405  GLfloat x1 = (o.x-40.0)/40.0;
406  GLfloat y1 = (o.y-40.0)/40.0;
407  GLfloat z1 = -o.height/80.0;
408  GLfloat h1 = 360*o.heading/8.0;
409 
410  GLfloat x2 = (n.x-40.0)/40.0;
411  GLfloat y2 = (n.y-40.0)/40.0;
412  GLfloat z2 = -n.height/80.0;
413  GLfloat h2 = 360*n.heading/8.0;
414  if (o.heading < 2 && n.heading >= 6)
415  h2 -= 360;
416  if (o.heading >= 6 && n.heading < 2)
417  h1 -= 360;
418  glEnable(GL_LIGHTING);
419  glPushMatrix();
420  glTranslatef((1-perc)*x1+perc*x2, (1-perc)*y1+perc*y2, (1-perc)*z1+perc*z2);
421  glRotatef((1-perc)*h1+perc*h2, 0, 0, 1);
422  DrawCylinder(0, 0, 0, 0, 0.01/5.0, 0.01);
423  glPopMatrix();
424 }
425 
427 {
428 
429 }
430 
432 {
433 
434 }
AirplaneEnvironment::Valid
bool Valid(int x, int y)
Definition: Airplane.cpp:169
Colors::GetColor
rgbColor GetColor(float v, float vmin, float vmax, int type)
Given min/max values, get a color from a color schema.
Definition: Colors.cpp:24
rgbColor::b
float b
Definition: Colors.h:71
AirplaneEnvironment::GoalTest
bool GoalTest(const airplaneState &node, const airplaneState &goal) const
Definition: Airplane.cpp:309
rgbColor
A color; r/g/b are between 0...1.
Definition: Colors.h:17
AirplaneEnvironment::GLDrawLine
void GLDrawLine(const airplaneState &a, const airplaneState &b) const
Definition: Airplane.cpp:431
recVec
A generic vector (essentially the same as a point, but offers normalization)
Definition: GLUtil.h:78
AirplaneEnvironment::AirplaneEnvironment
AirplaneEnvironment()
Definition: Airplane.cpp:18
min
double min(double a, double b)
Definition: FPUtil.h:35
recVec::z
GLdouble z
Definition: GLUtil.h:98
AirplaneEnvironment::RecurseGround
void RecurseGround(int x1, int y1, int x2, int y2)
Definition: Airplane.cpp:185
airplaneAction::turn
int8_t turn
Definition: Airplane.h:31
AirplaneEnvironment::GetNormal
recVec & GetNormal(int x, int y)
Definition: Airplane.cpp:175
airplaneAction
Definition: Airplane.h:27
DrawCylinder
void DrawCylinder(GLfloat xx, GLfloat yy, GLfloat zz, GLfloat innerRad, GLfloat outerRad, GLfloat height)
Definition: GLUtil.cpp:309
d
mcData d[]
Definition: MotionCaptureMovement.cpp:21
k45
const uint8_t k45
Definition: Airplane.h:23
AirplaneEnvironment::GetStateHash
uint64_t GetStateHash(const airplaneState &node) const
Definition: Airplane.cpp:314
AirplaneEnvironment::ApplyAction
virtual void ApplyAction(airplaneState &s, airplaneAction dir) const
Definition: Airplane.cpp:239
rgbColor::g
float g
Definition: Colors.h:71
AirplaneEnvironment::internalActions
std::vector< airplaneAction > internalActions
Definition: Airplane.h:97
AirplaneEnvironment::GetSuccessors
void GetSuccessors(const airplaneState &nodeID, std::vector< airplaneState > &neighbors) const
Definition: Airplane.cpp:203
DrawBoxFrame
void DrawBoxFrame(GLfloat xx, GLfloat yy, GLfloat zz, GLfloat rad)
Definition: GLUtil.cpp:252
operator==
bool operator==(const airplaneState &s1, const airplaneState &s2)
Definition: Airplane.cpp:12
AirplaneEnvironment::GetNextState
virtual void GetNextState(const airplaneState &currents, airplaneAction dir, airplaneState &news) const
Definition: Airplane.cpp:285
airplaneState::y
uint8_t y
Definition: Airplane.h:41
airplaneState::x
uint8_t x
Definition: Airplane.h:40
airplaneState::speed
int speed
Definition: Airplane.h:43
airplaneAction::height
int8_t height
Definition: Airplane.h:33
AirplaneEnvironment::HCost
virtual double HCost(const airplaneState &node1, const airplaneState &node2) const
Heuristic value between two arbitrary nodes.
Definition: Airplane.cpp:293
AirplaneEnvironment::ground
std::vector< uint8_t > ground
Definition: Airplane.h:94
AirplaneEnvironment::SetGround
void SetGround(int x, int y, uint8_t val)
Definition: Airplane.cpp:159
AirplaneEnvironment::GetCoordinate
recVec GetCoordinate(int x, int y, int z) const
Definition: Airplane.cpp:324
SearchEnvironment< airplaneState, airplaneAction >::GetColor
virtual rgbColor GetColor() const
Definition: SearchEnvironment.h:105
airplaneState
Definition: Airplane.h:37
max
#define max(a, b)
Definition: MinimalSectorAbstraction.cpp:40
rgbColor::r
float r
Definition: Colors.h:71
AirplaneEnvironment::UndoAction
virtual void UndoAction(airplaneState &s, airplaneAction dir) const
Definition: Airplane.cpp:279
AirplaneEnvironment::GetActions
void GetActions(const airplaneState &nodeID, std::vector< airplaneAction > &actions) const
Definition: Airplane.cpp:214
k90
const uint8_t k90
Definition: Airplane.h:24
AirplaneEnvironment::GetGround
uint8_t GetGround(int x, int y) const
Definition: Airplane.cpp:164
AirplaneEnvironment::OpenGLDraw
virtual void OpenGLDraw() const
Definition: Airplane.cpp:329
airplaneState::height
uint8_t height
Definition: Airplane.h:42
AirplaneEnvironment::GetActionHash
uint64_t GetActionHash(airplaneAction act) const
Definition: Airplane.cpp:319
AirplaneEnvironment::GCost
virtual double GCost(const airplaneState &node1, const airplaneState &node2) const
Definition: Airplane.cpp:298
Airplane.h
kShift
const uint8_t kShift
Definition: Airplane.h:25
recVec::y
GLdouble y
Definition: GLUtil.h:98
AirplaneEnvironment::length
const int length
Definition: Airplane.h:92
airplaneState::heading
int heading
Definition: Airplane.h:44
recVec::x
GLdouble x
Definition: GLUtil.h:98
recVec::normalise
void normalise()
Normalize a vector.
Definition: GLUtil.cpp:39
AirplaneEnvironment::width
const int width
Definition: Airplane.h:91
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
AirplaneEnvironment::groundNormals
std::vector< recVec > groundNormals
Definition: Airplane.h:95