Skip to content

Instantly share code, notes, and snippets.

@totegamma
Created October 17, 2016 23:35
Show Gist options
  • Save totegamma/b2f310eaf8b205c3990230c88c23c49e to your computer and use it in GitHub Desktop.
Save totegamma/b2f310eaf8b205c3990230c88c23c49e to your computer and use it in GitHub Desktop.
boid
#include <GLUT/glut.h>
#include <stdio.h>
#include <random>
#include <math.h>
#include <iostream>
#include <time.h>
#include "header.h"
using namespace std;
#define ID_DRAW_BOID 1
int main(int argc, char *argv[]){
srand((unsigned int)time(NULL));
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
glutInitWindowSize(800,800);
glutCreateWindow(argv[0]);
glutDisplayFunc(display);
buildDisplayList();
glutTimerFunc(20, timer, 0);
glutMainLoop();
return 0;
}
//初期化
bird::bird(){
position.x = rand()%200/100.0 - 1;
position.y = rand()%200/100.0 - 1;
direction = rand()%int(M_PI*200)/100.0 - M_PI;
speed = rand()%100/100.0;
color.r = rand()%100/100.0;
color.g = rand()%100/100.0;
color.b = rand()%100/100.0;
}
//移動
void bird::move(){
double rule1birdCount = 0;
double rule2birdCount = 0;
double rule3birdCount = 0;
double rule1centerX = 0;
double rule1centerY = 0;
double rule2centerX = 0;
double rule2centerY = 0;
double rule3speed = 0;
double rule3direction = 0;
for(int i = 0; i < _NumberOfBird_; i ++){
if(this == &birdList[i]) continue;
double distance = sqrt( pow(position.x - birdList[i].position.x, 2) + pow(position.y - birdList[i].position.y, 2));
if(distance < _rule1Distance_){
rule1birdCount ++;
rule1centerX += birdList[i].position.x;
rule1centerY += birdList[i].position.y;
}
if(distance < _rule2Distance_){
rule2birdCount ++;
rule2centerX += birdList[i].position.x;
rule2centerY += birdList[i].position.y;
}
if(distance < _rule3Distance_){
rule3birdCount ++;
rule3speed += birdList[i].speed;
rule3direction += birdList[i].direction;
}
}
if(rule1birdCount != 0){
double centerXave = rule1centerX/rule1birdCount;
double centerYave = rule1centerY/rule1birdCount;
direction = atan2(centerYave - position.y, centerXave - position.x) * _rule1Effect_ + direction * (1 - _rule1Effect_);
}
if(rule2birdCount != 0){
double centerXave = rule2centerX/rule2birdCount;
double centerYave = rule2centerY/rule2birdCount;
direction = atan2(position.y - centerYave, position.x - centerXave) * _rule2Effect_ + direction * (1 - _rule2Effect_);
}
if(rule3birdCount != 0){
double newSpeed = rule3speed / rule3birdCount;
double newDirection = rule3direction / rule3birdCount;
speed = newSpeed * _rule3Effect_ + speed * (1-_rule3Effect_);
direction = newDirection * _rule3Effect_ + direction * (1-_rule3Effect_);
}
/*
if(position.x > 0.9) direction = direction + M_PI * 0.1;
if(position.x < -0.9) direction = direction + M_PI * 0.1;
if(position.y > 0.9) direction = direction + M_PI * 0.1;
if(position.y < -0.9) direction = direction + M_PI * 0.1;
if(position.x > 1) position.x = 1;
if(position.x < -1) position.x = -1;
if(position.y > 1) position.y = 1;
if(position.y < -1) position.y = -1;
*/
if(position.x > 1) position.x -= 2;
if(position.x < -1) position.x -= -2;
if(position.y > 1) position.y -= 2;
if(position.y < -1) position.y -= -2;
position.x += cos(direction)*speed/100;
position.y += sin(direction)*speed/100;
}
void display(void){
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
for(int j=0;j<_NumberOfBird_;j++){
glPushMatrix();
glColor3d(birdList[j].color.r,birdList[j].color.g,birdList[j].color.b);
glTranslated(birdList[j].position.x,birdList[j].position.y,0);
glCallList(ID_DRAW_BOID);
glPopMatrix();
}
glutSwapBuffers();
}
void timer(int value){ //一定時間ごとに呼び出し,移動用
//鳥を動かす
for(int i = 0; i < _NumberOfBird_ ; i++){
birdList[i].move();
}
glutPostRedisplay();
glutTimerFunc(10,timer,0);
}
void buildDisplayList(){ //boidとしての円
glNewList(1,GL_COMPILE);
glBegin(GL_POLYGON);
for(int i=0;i<360;i++){
double x = cos(i*M_PI/180.0);
double y = sin(i*M_PI/180.0);
glVertex2d(x*0.01,y*0.01);
}
glEnd();
glEndList();
}
const int _NumberOfBird_ = 100;
const double _rule1Distance_ = 0.3;
const double _rule1Effect_ = 0.02;
const double _rule2Distance_ = 0.02;
const double _rule2Effect_ = 0.7;
const double _rule3Distance_ = 0.1;
const double _rule3Effect_ = 0.09;
int main(int argc, char *argv[]);
class bird{
public:
//鳥のプロパティ
struct S_position{
double x; //-1.0 to 1.0
double y; //-1.0 to 1.0
} position;
double direction; //0.0 to 360.0
double speed; //0.0 to 1.0
struct S_color{
double r; //0.0 to 1.0
double g; //0.0 to 1.0
double b; //0.0 to 1.0
} color;
//初期化
bird();
//移動
void move();
};
//画面上の鳥をひとまとめに管理する
bird birdList[_NumberOfBird_];
void display(void);
void timer(int value);
void buildDisplayList();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment