Created
June 2, 2017 09:12
-
-
Save zhry110/2279d3b3ae175e381c9ec3918e19d295 to your computer and use it in GitHub Desktop.
Nbody
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="Encoding"> | |
<file url="file://$USER_HOME$/Downloads/Nbody.cpp" charset="GB2312" /> | |
</component> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" /> | |
<component name="JsFlowSettings"> | |
<service-enabled>false</service-enabled> | |
<exe-path /> | |
<annotation-enable>false</annotation-enable> | |
<other-services-enabled>false</other-services-enabled> | |
</component> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectModuleManager"> | |
<modules> | |
<module fileurl="file://$PROJECT_DIR$/.idea/nbody.iml" filepath="$PROJECT_DIR$/.idea/nbody.iml" /> | |
</modules> | |
</component> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<module classpath="CMake" type="CPP_MODULE" version="4" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.7) | |
project(nbody) | |
include_directories(usr/local/include | |
) | |
set(CMAKE_CXX_STANDARD 11) | |
set(SOURCE_FILES main.cpp Plant.cpp Plant.h NbodyNode.cpp NbodyNode.h Tree.cpp Tree.h) | |
SET(CMAKE_LIBRARY_PATH /usr/local/lib) | |
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -framework OpenGL -framework GLUT -lmpi") | |
SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS}) | |
add_executable(nbody ${SOURCE_FILES}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>NbodyNode.cpp</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<style type="text/css"> | |
.ln { color: #606366; font-weight: normal; font-style: normal; } | |
.s0 { color: rgb(128,128,128); } | |
.s1 { color: rgb(169,183,198); } | |
.s2 { color: rgb(187,181,41); } | |
.s3 { color: rgb(106,135,89); } | |
.s4 { color: rgb(204,120,50); font-weight: bold; } | |
.s5 { color: rgb(204,120,50); } | |
.s6 { color: rgb(104,151,187); } | |
</style> | |
</head> | |
<BODY BGCOLOR="#2b2b2b"> | |
<TABLE CELLSPACING=0 CELLPADDING=5 COLS=1 WIDTH="100%" BGCOLOR="#606060" > | |
<TR><TD><CENTER> | |
<FONT FACE="Arial, Helvetica" COLOR="#000000"> | |
NbodyNode.cpp</FONT> | |
</center></TD></TR></TABLE> | |
<pre> | |
<span class="s0">//</span><span class="s1"> | |
</span><span class="s0">// Created by ZHRY on 2017/6/1.</span><span class="s1"> | |
</span><span class="s0">//</span><span class="s1"> | |
</span><span class="s2">#include </span><span class="s3">"NbodyNode.h"</span><span class="s1"> | |
NbodyNode::NbodyNode(</span><span class="s4">int </span><span class="s1">w):width(w) { | |
_isPlant = </span><span class="s4">false</span><span class="s5">;</span><span class="s1"> | |
_body = </span><span class="s4">new </span><span class="s1">Plant()</span><span class="s5">;</span><span class="s1"> | |
} | |
NbodyNode::~NbodyNode() { | |
</span><span class="s4">if </span><span class="s1">(_body != </span><span class="s4">nullptr</span><span class="s1">) | |
</span><span class="s4">delete </span><span class="s1">_body</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">if </span><span class="s1">(_leftTop != </span><span class="s4">nullptr</span><span class="s1">) | |
</span><span class="s4">delete</span><span class="s1">(_leftTop)</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">if </span><span class="s1">(_rightTop != </span><span class="s4">nullptr</span><span class="s1">) | |
</span><span class="s4">delete</span><span class="s1">(_rightTop)</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">if </span><span class="s1">(_leftButtom != </span><span class="s4">nullptr</span><span class="s1">) | |
</span><span class="s4">delete</span><span class="s1">(_leftButtom)</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">if </span><span class="s1">(_rightButtom != </span><span class="s4">nullptr</span><span class="s1">) | |
</span><span class="s4">delete</span><span class="s1">(_rightButtom)</span><span class="s5">;</span><span class="s1"> | |
} | |
NbodyNode*& NbodyNode::leftTop() | |
{ | |
</span><span class="s4">return </span><span class="s1">_leftTop</span><span class="s5">;</span><span class="s1"> | |
} | |
NbodyNode*& NbodyNode::rightTop() | |
{ | |
</span><span class="s4">return </span><span class="s1">_rightTop</span><span class="s5">;</span><span class="s1"> | |
} | |
NbodyNode*& NbodyNode::leftButtom() | |
{ | |
</span><span class="s4">return </span><span class="s1">_leftButtom</span><span class="s5">;</span><span class="s1"> | |
} | |
NbodyNode*& NbodyNode::rightButtom() | |
{ | |
</span><span class="s4">return </span><span class="s1">_rightButtom</span><span class="s5">;</span><span class="s1"> | |
} | |
</span><span class="s4">bool</span><span class="s1">& NbodyNode::isPlant() | |
{ | |
</span><span class="s4">return </span><span class="s1">_isPlant</span><span class="s5">;</span><span class="s1"> | |
} | |
Plant& NbodyNode::body() | |
{ | |
</span><span class="s4">return </span><span class="s1">*_body</span><span class="s5">;</span><span class="s1"> | |
} | |
</span><span class="s4">bool </span><span class="s1">NbodyNode::buildTree(NbodyNode* tree</span><span class="s5">,</span><span class="s1">complex<</span><span class="s4">float</span><span class="s1">> start</span><span class="s5">,</span><span class="s1">complex<</span><span class="s4">float </span><span class="s1">> end</span><span class="s5">,</span><span class="s1">vector<Plant>& plants) { | |
</span><span class="s4">if </span><span class="s1">(tree == </span><span class="s4">nullptr</span><span class="s1">) | |
</span><span class="s4">return false</span><span class="s5">;</span><span class="s1"> | |
complex<</span><span class="s4">float</span><span class="s1">> check = end - start</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">if </span><span class="s1">(check.real() <= </span><span class="s6">0 </span><span class="s1">|| check.imag() <= </span><span class="s6">0</span><span class="s1">){ | |
printf(</span><span class="s3">"check failed</span><span class="s5">\n</span><span class="s3">"</span><span class="s1">)</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">return false</span><span class="s5">;</span><span class="s1"> | |
} | |
</span><span class="s4">if </span><span class="s1">(plants.size() == </span><span class="s6">1</span><span class="s1">) { | |
tree->body() = plants.front()</span><span class="s5">;</span><span class="s1"> | |
tree->isPlant() = </span><span class="s4">true</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">return true</span><span class="s5">;</span><span class="s1"> | |
} | |
vector<Plant> wrapers[</span><span class="s6">4</span><span class="s1">]</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">int </span><span class="s1">centerX = (start.real() + end.real()) / </span><span class="s6">2</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">int </span><span class="s1">centerY = (start.imag() + end.imag()) / </span><span class="s6">2</span><span class="s5">;</span><span class="s1"> | |
complex<</span><span class="s4">float</span><span class="s1">> center = complex<</span><span class="s4">float</span><span class="s1">>(centerX</span><span class="s5">, </span><span class="s1">centerY)</span><span class="s5">;</span><span class="s1"> | |
complex<</span><span class="s4">float</span><span class="s1">> sub = complex<</span><span class="s4">float</span><span class="s1">>()</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">for </span><span class="s1">(vector<Plant>::iterator i = plants.begin()</span><span class="s5">; </span><span class="s1">i != plants.end()</span><span class="s5">; </span><span class="s1">i++) { | |
sub = i->location() - center</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">if </span><span class="s1">(sub.real() <= </span><span class="s6">0 </span><span class="s1">&& sub.imag() <= </span><span class="s6">0</span><span class="s1">) { | |
wrapers[</span><span class="s6">0</span><span class="s1">].push_back(*i)</span><span class="s5">;</span><span class="s1"> | |
} </span><span class="s4">else if </span><span class="s1">(sub.real() < </span><span class="s6">0 </span><span class="s1">&& sub.imag() > </span><span class="s6">0</span><span class="s1">) { | |
wrapers[</span><span class="s6">2</span><span class="s1">].push_back(*i)</span><span class="s5">;</span><span class="s1"> | |
} </span><span class="s4">else if </span><span class="s1">(sub.real() > </span><span class="s6">0 </span><span class="s1">&& sub.imag() < </span><span class="s6">0</span><span class="s1">) { | |
wrapers[</span><span class="s6">1</span><span class="s1">].push_back(*i)</span><span class="s5">;</span><span class="s1"> | |
} </span><span class="s4">else if </span><span class="s1">(sub.real() >= </span><span class="s6">0 </span><span class="s1">&& sub.imag() >= </span><span class="s6">0</span><span class="s1">) { | |
wrapers[</span><span class="s6">3</span><span class="s1">].push_back(*i)</span><span class="s5">;</span><span class="s1"> | |
} | |
} | |
</span><span class="s4">int </span><span class="s1">width = tree->width / </span><span class="s6">4</span><span class="s5">;</span><span class="s1"> | |
tree->body() = Plant()</span><span class="s5">;</span><span class="s1"> | |
</span><span class="s4">if </span><span class="s1">(wrapers[</span><span class="s6">0</span><span class="s1">].size() > </span><span class="s6">0</span><span class="s1">) { | |
tree->leftTop() = </span><span class="s4">new </span><span class="s1">NbodyNode(width)</span><span class="s5">;</span><span class="s1"> | |
buildTree(tree->leftTop()</span><span class="s5">, </span><span class="s1">start</span><span class="s5">, </span><span class="s1">center</span><span class="s5">, </span><span class="s1">wrapers[</span><span class="s6">0</span><span class="s1">])</span><span class="s5">;</span><span class="s1"> | |
tree->body() = tree->body() + tree->leftTop()->body()</span><span class="s5">;</span><span class="s1"> | |
} | |
</span><span class="s4">if </span><span class="s1">(wrapers[</span><span class="s6">1</span><span class="s1">].size() > </span><span class="s6">0</span><span class="s1">) { | |
tree->rightTop() = </span><span class="s4">new </span><span class="s1">NbodyNode(width)</span><span class="s5">;</span><span class="s1"> | |
buildTree(tree->rightTop()</span><span class="s5">, </span><span class="s1">complex<</span><span class="s4">float</span><span class="s1">>(start.real() + centerX</span><span class="s5">, </span><span class="s1">start.imag())</span><span class="s5">,</span><span class="s1"> | |
complex<</span><span class="s4">float</span><span class="s1">>(end.real()</span><span class="s5">, </span><span class="s1">centerY)</span><span class="s5">, </span><span class="s1">wrapers[</span><span class="s6">1</span><span class="s1">])</span><span class="s5">;</span><span class="s1"> | |
tree->body() = tree->body() + tree->rightTop()->body()</span><span class="s5">;</span><span class="s1"> | |
} | |
</span><span class="s4">if </span><span class="s1">(wrapers[</span><span class="s6">2</span><span class="s1">].size() > </span><span class="s6">0</span><span class="s1">){ | |
tree->leftButtom() = </span><span class="s4">new </span><span class="s1">NbodyNode(width)</span><span class="s5">;</span><span class="s1"> | |
buildTree(tree->leftButtom()</span><span class="s5">,</span><span class="s1">complex<</span><span class="s4">float </span><span class="s1">>(start.real()</span><span class="s5">,</span><span class="s1">centerY)</span><span class="s5">,</span><span class="s1"> | |
complex<</span><span class="s4">float </span><span class="s1">>(centerX</span><span class="s5">,</span><span class="s1">end.imag())</span><span class="s5">,</span><span class="s1">wrapers[</span><span class="s6">2</span><span class="s1">])</span><span class="s5">;</span><span class="s1"> | |
tree->body() = tree->body() + tree->leftButtom()->body()</span><span class="s5">;</span><span class="s1"> | |
} | |
</span><span class="s4">if </span><span class="s1">(wrapers[</span><span class="s6">3</span><span class="s1">].size() > </span><span class="s6">0</span><span class="s1">){ | |
tree->rightButtom() = </span><span class="s4">new </span><span class="s1">NbodyNode(width)</span><span class="s5">;</span><span class="s1"> | |
buildTree(tree->rightButtom()</span><span class="s5">,</span><span class="s1">center</span><span class="s5">,</span><span class="s1">end</span><span class="s5">,</span><span class="s1">wrapers[</span><span class="s6">3</span><span class="s1">])</span><span class="s5">;</span><span class="s1"> | |
tree->body() = tree->body() + tree->rightButtom()->body()</span><span class="s5">;</span><span class="s1"> | |
} | |
</span><span class="s4">return true</span><span class="s5">;</span><span class="s1"> | |
} | |
</span></pre> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "Plant.h" | |
#include "NbodyNode.h" | |
#include <queue> | |
#include "mpi.h" | |
#include "OpenGL/gl.h" | |
#include "GLUT.H" | |
#include <unistd.h> | |
#include "Tree.h" | |
#include <pthread.h> | |
void draw_solid_circle(double x, double y, double radius,bool red); | |
void draw(); | |
void* fresh(void* arg); | |
vector<Plant*> ps; | |
int main(int argc,char** argv) { | |
vector<Plant> plants; | |
plants.push_back(Plant(450,511,200)); | |
plants.push_back(Plant(500,500,580)); | |
plants.push_back(Plant(550,300,200)); | |
plants.push_back(Plant(550,100,190)); | |
plants.push_back(Plant(550,190,160)); | |
plants.push_back(Plant(550,290,660)); | |
plants.push_back(Plant(550,390,250)); | |
//plants.push_back(Plant(760,77,90000)); | |
plants.push_back(Plant(200,105,200)); | |
plants.push_back(Plant(132,666,996)); | |
plants.push_back(Plant(430,400,200)); | |
plants.push_back(Plant(364,244,200)); | |
plants.push_back(Plant(869,666,300)); | |
plants.push_back(Plant(111,111,200)); | |
plants.push_back(Plant(222,211,200)); | |
plants.push_back(Plant(363,999,544)); | |
plants.push_back(Plant(120,400,200)); | |
plants.push_back(Plant(966,244,500)); | |
plants.push_back(Plant(100,666,550)); | |
Tree t = Tree(1000,plants); | |
ps = t.getPlants(); | |
glutInit(&argc, argv); | |
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); | |
glutInitWindowPosition(500, 100); | |
glutInitWindowSize(1000, 1000); | |
glutCreateWindow("An Example OpenGL Program"); | |
glClearColor(0.0, 0.0, 0.0, 0.0); | |
glMatrixMode(GL_PROJECTION); | |
gluOrtho2D(1.0, 1000, 1, 1000); | |
glutDisplayFunc(draw); | |
pthread_t tid; | |
pthread_create(&tid, nullptr,fresh, &t); | |
glutMainLoop(); | |
return 0; | |
} | |
void draw() | |
{ | |
glClear(GL_COLOR_BUFFER_BIT); | |
for (vector<Plant*>::iterator i = ps.begin(); i < ps.end(); i++) { | |
int rad = (*i)->getM() >= 5000 ? 10 : ((*i)->getM()/100.0); | |
draw_solid_circle((*i)->getX(),(*i)->getY(),rad,rad >= 10); | |
} | |
glFlush(); | |
} | |
void draw_solid_circle(double x, double y, double radius,bool red) | |
{ | |
int count; | |
int sections=200; | |
GLdouble TWOPI=2.0f * 3.14159f; | |
glBegin(GL_TRIANGLE_FAN); | |
glColor3f(1.0,1.0,1.0); | |
if (red) | |
{ | |
glColor3f(1.0,0.0,0.0); | |
} | |
glVertex2f(x, y); | |
for(count=0; count<=sections; count++) | |
{ | |
glVertex2f(x+radius*cos(count*TWOPI/sections), y+radius*sin(count*TWOPI/sections)); | |
} | |
glEnd(); | |
} | |
void* fresh(void* arg) | |
{ | |
Tree* t = (Tree*)arg; | |
while (true){ | |
glutPostRedisplay(); | |
t->update(); | |
usleep(1000); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by ZHRY on 2017/6/1. | |
// | |
#include "NbodyNode.h" | |
NbodyNode::NbodyNode(int w):_width(w) { | |
_isPlant = false; | |
_body = new Plant(); | |
} | |
NbodyNode::~NbodyNode() { | |
if (_body != nullptr) | |
delete _body; | |
if (_leftTop != nullptr) | |
delete(_leftTop); | |
if (_rightTop != nullptr) | |
delete(_rightTop); | |
if (_leftButtom != nullptr) | |
delete(_leftButtom); | |
if (_rightButtom != nullptr) | |
delete(_rightButtom); | |
} | |
NbodyNode*& NbodyNode::leftTop() | |
{ | |
return _leftTop; | |
} | |
NbodyNode*& NbodyNode::rightTop() | |
{ | |
return _rightTop; | |
} | |
NbodyNode*& NbodyNode::leftButtom() | |
{ | |
return _leftButtom; | |
} | |
NbodyNode*& NbodyNode::rightButtom() | |
{ | |
return _rightButtom; | |
} | |
bool& NbodyNode::isPlant() | |
{ | |
return _isPlant; | |
} | |
Plant& NbodyNode::body() | |
{ | |
return *_body; | |
} | |
void NbodyNode::updateBody() { | |
if (isPlant()) | |
{ | |
return; | |
} | |
body() = Plant(); | |
if (leftTop() != nullptr) | |
{ | |
leftTop()->updateBody(); | |
body() = body() + leftTop()->body(); | |
} | |
if (rightTop() != nullptr) | |
{ | |
rightTop()->updateBody(); | |
body() = body() + rightTop()->body(); | |
} | |
if (leftButtom() != nullptr) | |
{ | |
leftButtom()->updateBody(); | |
body() = body() + leftButtom()->body(); | |
} | |
if (rightButtom() != nullptr) | |
{ | |
rightButtom()->updateBody(); | |
body() = body() + rightButtom()->body(); | |
} | |
} | |
int NbodyNode::width() { | |
return _width; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by ZHRY on 2017/6/1. | |
// | |
#ifndef NBODY_NBODYNODE_H | |
#define NBODY_NBODYNODE_H | |
#include <complex> | |
#include <vector> | |
class Plant; | |
class NbodyNode { | |
public: | |
NbodyNode(int w); | |
~NbodyNode(); | |
NbodyNode*& leftTop() ; | |
NbodyNode*& rightTop() ; | |
NbodyNode*& leftButtom() ; | |
NbodyNode*& rightButtom() ; | |
bool& isPlant(); | |
Plant& body() ; | |
void updateBody(); | |
int width(); | |
private: | |
NbodyNode* _leftTop = 0; | |
NbodyNode* _rightTop = 0; | |
NbodyNode* _leftButtom = 0; | |
NbodyNode* _rightButtom = 0; | |
bool _isPlant; | |
Plant* _body; | |
int _width; | |
}; | |
#include "Plant.h" | |
#endif //NBODY_NBODYNODE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by ZHRY on 2017/5/31. | |
// | |
#include "Plant.h" | |
const double Plant::theta = 0.5; | |
const double Plant::G = 1e-3; | |
Plant Plant::operator+(Plant &plant) { | |
int newX, newY; | |
int allMass = m + plant.m; | |
newX = (m * loction.real() + plant.m * plant.loction.real()) / allMass; | |
newY = (m * loction.imag() + plant.m * plant.loction.imag()) / allMass; | |
return Plant(newX, newY, allMass); | |
} | |
void Plant::update(Tree *t) { | |
f = complex<double>(0, 0); | |
NbodyNode *tree = t->tree(); | |
queue<NbodyNode*> q; | |
q.push(tree); | |
while (!q.empty()) { | |
NbodyNode *cur = q.front(); | |
q.pop(); | |
if (cur == nullptr) { | |
continue; | |
} | |
if (cur->isPlant()) { | |
this->calculateF(cur->body()); | |
continue; | |
} | |
double theta = cur->width() / (*this - cur->body()); | |
if (theta <= Plant::theta) { | |
this->calculateF(cur->body()); | |
} else { | |
q.push(cur->leftTop()); | |
q.push(cur->rightTop()); | |
q.push(cur->leftButtom()); | |
q.push(cur->rightButtom()); | |
} | |
} | |
} | |
void Plant::calculateF(Plant &plant) { | |
complex<double> r = (plant.loction - loction); | |
if (r.real() == 0 || r.imag() == 0) | |
{ | |
return; | |
} | |
double realRpow = r.real()*r.real() + r.imag()*r.imag(); | |
double realF = (G * m * plant.m) / (realRpow); | |
double scale = sqrt(pow(realF,2) / (realRpow)); | |
f += complex<double>(r.real()*scale,r.imag()*scale); | |
} | |
bool Plant::operator==(Plant &plant) { | |
return m == plant.m && loction == plant.loction; | |
} | |
void Plant::respawn() { | |
loction = complex<double>(0,300+m/1000); | |
} | |
void Plant::move() { | |
a = complex<double>(f.real()/m,f.imag()/m); | |
loction += speed+ a/complex<double>(2.0,2.0); | |
speed += a; | |
if (loction.real() <0 || loction.real() > 1000) | |
{ | |
loction = complex<double>(500,loction.imag()); | |
speed = complex<double>(0.001,0.001); | |
} | |
if (loction.imag() <0 || loction.imag() > 1000) | |
{ | |
loction = complex<double>(loction.real(),500); | |
speed = complex<double>(0.001,0.001); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by ZHRY on 2017/5/31. | |
// | |
#ifndef NBODY_PLANT_H | |
#define NBODY_PLANT_H | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <complex> | |
#include "mpi.h" | |
#include "NbodyNode.h" | |
#include <queue> | |
#include <math.h> | |
class Tree; | |
using namespace std; | |
class Plant { | |
public: | |
const static double theta; | |
const static double G ; //new define G with scale | |
Plant() :f(0,0),loction(0,0),a(0,0),speed(0,0),m(0){} | |
Plant(double x, double y ,int m) : Plant(){ | |
loction = complex<double>(x,y); | |
this->m = m; | |
} | |
void update(Tree* t); | |
double getX() | |
{ | |
return loction.real(); | |
} | |
double getY() | |
{ | |
return loction.imag(); | |
} | |
complex<double> location() | |
{ | |
return loction; | |
} | |
int getM() | |
{ | |
return m; | |
} | |
Plant operator+(Plant& plant); | |
double operator-(Plant& plant) | |
{ | |
return sqrt(pow(loction.real() - plant.loction.real(),2) + pow(loction.imag() - plant.loction.imag(),2)); | |
} | |
void calculateF(Plant& plant); | |
bool operator==(Plant& plant); | |
void respawn(); | |
void move(); | |
private: | |
double m; | |
complex<double> f; | |
complex<double> loction; | |
complex<double> speed,a; | |
}; | |
#include "Tree.h" | |
#endif //NBODY_PLANT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by ZHRY on 2017/6/1. | |
// | |
#include "Tree.h" | |
Tree::Tree(int maxWidth, vector<Plant> plants) { | |
_tree = new NbodyNode(maxWidth); | |
if(!buildTree(_tree, complex<double>(0, 0), complex<double>(maxWidth, maxWidth), plants)) | |
{ | |
printf("can not build tree\n"); | |
} | |
} | |
Tree::~Tree() { | |
delete _tree; | |
} | |
const vector<Plant *>& Tree::getPlants() const { | |
return plants; | |
} | |
NbodyNode *Tree::tree() { | |
return _tree; | |
} | |
void Tree::update() { | |
for (vector<Plant*>::iterator i = plants.begin(); i != plants.end(); i++) { | |
(*i)->update(this); | |
} | |
for (vector<Plant*>::iterator i = plants.begin(); i != plants.end(); i++) { | |
(*i)->move(); | |
} | |
tree()->updateBody(); | |
} | |
bool Tree::buildTree(NbodyNode *tree, complex<double> start, complex<double> end, vector<Plant> &plants) { | |
if (tree == nullptr) | |
return false; | |
complex<double> check = end - start; | |
if (check.real() <= 0 && check.imag() <= 0) { | |
printf("check failed\n"); | |
return false; | |
} | |
if (plants.size() == 1) { | |
tree->body() = plants.front(); | |
tree->isPlant() = true; | |
this->plants.push_back(&tree->body()); | |
return true; | |
} | |
vector<Plant> wrapers[4]; | |
int centerX = (start.real() + end.real()) / 2; | |
int centerY = (start.imag() + end.imag()) / 2; | |
complex<double> center = complex<double>(centerX, centerY); | |
complex<double> sub = complex<double>(); | |
for (vector<Plant>::iterator i = plants.begin(); i != plants.end(); i++) { | |
sub = i->location() - center; | |
if (sub.real() <= 0 && sub.imag() <= 0) { | |
wrapers[0].push_back(*i); | |
} else if (sub.real() < 0 && sub.imag() > 0) { | |
wrapers[2].push_back(*i); | |
} else if (sub.real() > 0 && sub.imag() < 0) { | |
wrapers[1].push_back(*i); | |
} else if (sub.real() >= 0 && sub.imag() >= 0) { | |
wrapers[3].push_back(*i); | |
} | |
} | |
int width = tree->width() / 4; | |
tree->body() = Plant(); | |
bool ret = true; | |
if (wrapers[0].size() > 0) { | |
tree->leftTop() = new NbodyNode(width); | |
ret = ret && buildTree(tree->leftTop(), start, center, wrapers[0]); | |
tree->body() = tree->body() + tree->leftTop()->body(); | |
} | |
if (wrapers[1].size() > 0) { | |
tree->rightTop() = new NbodyNode(width); | |
ret = ret && buildTree(tree->rightTop(), complex<double>(start.real() + centerX, start.imag()), | |
complex<double>(end.real(), centerY), wrapers[1]); | |
tree->body() = tree->body() + tree->rightTop()->body(); | |
} | |
if (wrapers[2].size() > 0) { | |
tree->leftButtom() = new NbodyNode(width); | |
ret = ret && buildTree(tree->leftButtom(), complex<double>(start.real(), centerY), | |
complex<double>(centerX, end.imag()), wrapers[2]); | |
tree->body() = tree->body() + tree->leftButtom()->body(); | |
} | |
if (wrapers[3].size() > 0) { | |
tree->rightButtom() = new NbodyNode(width); | |
ret = ret && buildTree(tree->rightButtom(), center, end, wrapers[3]); | |
tree->body() = tree->body() + tree->rightButtom()->body(); | |
} | |
return ret; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by ZHRY on 2017/6/1. | |
// | |
#ifndef NBODY_TREE_H | |
#define NBODY_TREE_H | |
#include <stdio.h> | |
#include "NbodyNode.h" | |
using namespace std; | |
class Tree { | |
public: | |
Tree(int maxWidth,std::vector<Plant> plants); | |
~Tree(); | |
bool buildTree(NbodyNode* tree,complex<double > start,complex<double > end,vector<Plant>& plants); | |
const vector<Plant*>& getPlants() const ; | |
NbodyNode* tree(); | |
void update(); | |
private: | |
vector<Plant*> plants; | |
NbodyNode* _tree; | |
}; | |
#endif //NBODY_TREE_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment