📄 agent.cpp
字号:
//// pedsim - A microscopic pedestrian simulation system. // Copyright (c) 2003 - 2004 by Christian Gloor// // You can redistribute and/or modify this program under the terms of// the GNU General Public License. See copying.txt for details.//
//using namespace std;#include "main.h"#include "agent.h"#include "tree.h"#include "math.h"
extern AgentContainer agent;extern TreeContainer tree;const double h = 0.7;// ----------------------------------------------------// Name: constructor// Description: set intial values// Introduced: chgloor Monday, December 29, 2003 11:10:37// ----------------------------------------------------Tagent::Tagent() { static int staticid = 0; id = staticid++; x = 0; y = 0; vx = 0; vy = 0; // energy = 80+(1.0f*random())/(RAND_MAX/20); energy = 100; if ((id %50) == 0) { energy = 500; } enemynearest = (AgentIterator)NULL; enemydist = 999999; dead = false; color = .5f + .5f * rand() / RAND_MAX; direction = 0; sword = 0; swordini = 10.0f * rand() / RAND_MAX ;};// ----------------------------------------------------// Name: setPosition// Description: sets the position// Introduced: chgloor Tuesday, February 10, 2004 10:48:39// Return value: void// ----------------------------------------------------void Tagent::setPosition(double px, double py) { x = px, y = py; };// ----------------------------------------------------// Name: hit// Description: if an agent was hit by another agent // Introduced: chgloor Monday, December 29, 2003 14:06:36// ----------------------------------------------------void Tagent::hit() { energy = energy - h*0.5 ; if (energy < 0) { dead = true; }};// ----------------------------------------------------// Name: move// Description: does the ped dynamics stuff // Introduced: chgloor Monday, December 29, 2003 11:10:58// Return value: void// ----------------------------------------------------void Tagent::move(long systemtime) { double vmax = 3; // in m/s double ax = 0; // acceleration in x direction double ay = 0; if ((enemynearest != (AgentIterator)NULL) && (enemynearest->dead == true)) enemydist = 9999999; // AgentIterator enemynearest = (AgentIterator)NULL; // For more details on this next loop, // see: D. Helbing, I. Farkas, and T. Vicsek. // Simulating dynamical features of escape panic. // Nature, (407):487-490, 2000. for (AgentIterator iter = agent.begin(); iter!=agent.end(); iter++) { // iterate over all agents == O(N^2) :( double fx = 0; double fy = 0; if ((iter->id != id) && (dead == false)) { double distancex = x - iter->x; double distancey = y - iter->y; float dist2 = (distancex * distancex + distancey * distancey); // dist2 = distanz im quadrat if ((dist2 > 0.04) && (dist2 < 25)) { // 20cm- 5m distance const float Bp = 0.9; // 1.7139; // ped interaction range [laurent] in meters fx = (distancex-0)/(exp(dist2)/Bp); // this was originally "exp(dist-1)" fy = (distancey-0)/(exp(dist2)/Bp); } else { fx = 0; fy = 0; } if (iter->dead == true) { fx = fx*0.2; fy = fy*0.2; } ax += fx; // kummulieren ueber alle agenten ay += fy; if (iter->type != type) { // other type than myself if ((enemynearest == (AgentIterator)NULL) || ( rand() > (RAND_MAX/100) ) || (enemynearest->dead == true)) { if ((dist2 < enemydist) && (iter->dead == false)) { // the one we are fightig is dead ( ;) ) take the next one that is closest && still alive enemydist = dist2; enemynearest = iter; } } } } } // trees for (TreeIterator iter3 = tree.begin(); iter3!=tree.end(); iter3++) { // iterate over all trees == O(N^2) double fx = 0; double fy = 0; if (dead == false) { double distancex = x - iter3->x; double distancey = y - iter3->y; float dist2 = (distancex * distancex + distancey * distancey); // dist2 = distanz im quadrat if ((dist2 > 0.04) && (dist2 < 25)) { // 20cm- 5m distance const float Bp = 12; // 1.7139; // ped interaction range [laurent] in meters fx = (distancex-0)/(exp(dist2)/Bp); // this was originally "exp(dist-1)" fy = (distancey-0)/(exp(dist2)/Bp); } else { fx = 0; fy = 0; } ax += fx; // kummulieren ueber alle trees ay += fy; } } double eax = 0; double eay = 0; if (dead == false) { if (enemynearest != (AgentIterator)NULL) { double distancex = x - enemynearest->x; double distancey = y - enemynearest->y; float dist2 = (distancex * distancex + distancey * distancey); // dist2 = distanz im quadrat if (dist2 > 0) { eax = -0.1f * distancex / sqrt(dist2); eay = -0.1f * distancey / sqrt(dist2); direction = atan(1.0f*distancey/distancex); // cerr << direction << " - " << distancex << "/" << distancey << endl; } if (dist2 < 3*3) { // < 3m enemynearest->hit(); double sspeed = 0.005f * energy + 0.7; // 0.7 - 1.2 sword = 10 + 10.0f*(((int)(sspeed*systemtime + swordini)) % 10); } else { sword = -135; } } } double homeax = 0; if (type == 0) homeax = -0.01; if (type == 1) homeax = +0.01; vx = 0.80f*vx + h * homeax + h * ax + h * eax; // v = v0 + a vy = 0.80f*vy + h * ay + h * eay; //vmax = vmax -1 + 2*(energy/100); double speed = ( sqrt(vx*vx + vy*vy) / vmax ); if (speed > 1) { vx = vx / speed; vy = vy / speed; } if (energy < 100) { vx = vx * (0.5+(energy/200)); vy = vy * (0.5+(energy/200)); } // position update == actual move if (dead == false) { x = x + h * vx; // x = x0 + v*t y = y + h * vy; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -