Skip to content

Commit

Permalink
cleanup, runs realtime with N=1k, not bad for a javascript/html page!…
Browse files Browse the repository at this point in the history
… Starts slowing down around 2k
  • Loading branch information
Elucidation committed Jan 1, 2012
1 parent 693dbbb commit 36cb171
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 16 deletions.
18 changes: 16 additions & 2 deletions README.markdown
Expand Up @@ -11,13 +11,27 @@ Some screenshots are also in repo.
With Brute force : `O(n^2)` calculations (exactly `(N-1)*N/2` actually), roughly 125k force calculations for N=500.
With Barnes-Hut tree calcualtions, it'll be `O(nlogn)`.

With a low number of bodies N < 50 or so, a slightly streamlined brute force is more efficient than a Barnes-Hut tree, but
as N increases, the efficiency increases dramatically (90-99%).

Status
---
Basic framework set up, basic graviation working with forward euler and leapfrog integration.

Brute-force calculation `O(n^2)` for all bodies.
Barnes-Hut calculation implemented and working.
Brute-force calculation `O(n^2)` for all bodies. Real-time for roughly N < 500
Barnes-Hut calculation implemented and working. Real-time for N > 1k etc.

Efficiency information is shown in real-time to the right of the canvas.

Example with 1,000 bodies.
``
# Bodies: 1000
# Force calculations per step: 32457
BN TREE - Depth: 11, # Nodes: 1544, # Leafs: 891
BN Tree O(nlogn) [32457]
Efficiency vs Brute Force O(n^2) [1000000] 96.75%
Efficiency vs Half Brute Force O(n^2) [499500] 93.50%
``


Next step, build quad-tree from bodies as in [LearnHTML5](https://github.com/Elucidation/LearnHTML5) repo.
Binary file added bnTree1000Screenshot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion bntree.js
Expand Up @@ -58,6 +58,9 @@ function addBody(x,y,vx,vy,m) {
if (DEBUG) {
console.log("ADD BODY M: ",m," P:",x,",",y," V:",vx,",",vy);
}
if (bods.N >= 100 && DEBUG > 0) {
setDEBUG(0); // temp check to keep debug off when too many bodies
}
}
// BN Tree code ------
var bnDepth=0, bnNumNodes=0, bnNumLeafs=0;
Expand Down Expand Up @@ -113,7 +116,7 @@ function bnBuildTree() {
bnAddBody(bnRoot,i,0);
}
else {
console.log("Body ",i," has left the BNtree area. Not added");
if (DEBUG>=4) {console.log("Body ",i," has left the BNtree area. Not added");}
}
}
if (DEBUG>=2) {
Expand Down
35 changes: 27 additions & 8 deletions graphics.js
Expand Up @@ -2,8 +2,13 @@ var DEBUGMAX = 5; // Levels of DEBUG

// Arrow Length Multipliers
drawArrows = false; // Button edit
arrowMult = 1;
arrowLengthRatio = 5;

// Circle Sizes
var MINRADIUS = 1;
var MAXRADIUS = 5;

var SHOW_BN_TREE = false;

// Canvas Context
var c;
Expand All @@ -27,7 +32,7 @@ function initGraphics(canvasId,dataId){
// Main Drawing --------------------------

function drawBNtree() {
if (bnRoot) {drawBNnode(bnRoot)};
if (bnRoot && SHOW_BN_TREE) {drawBNnode(bnRoot)};
}
function drawBNnode(node) {
// If body in node
Expand Down Expand Up @@ -137,9 +142,6 @@ function refreshGraphics() {
updateData();
}

var MINRADIUS = 1;
var MAXRADIUS = 20;

function massToRadius(mass) {
return MINRADIUS+(mass-MINMASS)/(MAXMASS-MINMASS)*(MAXRADIUS-MINRADIUS);

Expand Down Expand Up @@ -173,10 +175,26 @@ function drawCircle(x,y,r) {
function drawArrow(x,y,x2,y2,h,color) {
h = (typeof(h) != 'undefined' && h != '') ? h : 10; // Default h
color = typeof(color) != 'undefined' ? color : '#0f0'; // Default color
var angle = Math.atan2(y2-y,x2-x);

x2 = x + (x2-x)*arrowMult;
y2 = y + (y2-y)*arrowMult;
// Resize arrow based on arrowLengthRatio
// v = [x2-x,y2-y];
// vMag = Math.sqrt(v[0]*v[0]+v[1]*v[1]);
// if (vMag==0) {vMag = 1;}
// console.log(vMag);

// x2 = x + v[0]*arrowLengthRatio/vMag;
// y2 = y + v[1]*arrowLengthRatio/vMag;

// Linear Ratio
x2 = x + (x2-x)/arrowLengthRatio;
y2 = y + (y2-y)/arrowLengthRatio;

// Logarithmic Ratio
// var d = getDist(x,y,x2,y2);
// var arrowLength = (Math.log(2+d)-Math.log(2))/Math.log(1.1);
// x2 = x + (x2-x)/d * arrowLength;
// y2 = y + (y2-y)/d * arrowLength;


c.strokeStyle = color;
c.fillStyle = color;
Expand All @@ -191,6 +209,7 @@ function drawArrow(x,y,x2,y2,h,color) {
c.stroke();

// Arrow head
var angle = Math.atan2(y2-y,x2-x);
c.beginPath();
c.moveTo(x2,y2);
c.lineTo(x2-h*Math.cos(angle-Math.PI/8),y2-h*Math.sin(angle-Math.PI/8));
Expand Down
2 changes: 1 addition & 1 deletion index.html
Expand Up @@ -15,7 +15,7 @@ <h2>Barnes-Hut Implementation in HTML/Javascript</h2>
<p>Click to place body<br/>
Drag to set velocity of body<br/>
Press e/d keys while dragging to change mass of body<br/>
No collision checks
No collision checks, Bodies exert no gravitation when outside canvas area (but still get attracted back in).
</p>
<p><div>
Load Input JSON File:<br/>
Expand Down
8 changes: 4 additions & 4 deletions userInput.js
Expand Up @@ -48,8 +48,8 @@ function mouseMove(e) {
else if(e.layerX) {mouseX = e.layerX;mouseY = e.layerY;} // IE
dragx2 = mouseX;
dragy2 = mouseY;
dragx2 = (mouseX-dragx)/arrowMult + dragx;
dragy2 = (mouseY-dragy)/arrowMult + dragy;
dragx2 = (mouseX-dragx)/arrowLengthRatio + dragx;
dragy2 = (mouseY-dragy)/arrowLengthRatio + dragy;
refreshGraphics();
}
}
Expand All @@ -62,8 +62,8 @@ function mouseUp(e) {
if(e.offsetX) {mouseX = e.offsetX; mouseY = e.offsetY;}
else if(e.layerX) {mouseX = e.layerX;mouseY = e.layerY;} // IE

mouseX = (mouseX-dragx)/arrowMult + dragx;
mouseY = (mouseY-dragy)/arrowMult + dragy;
mouseX = (mouseX-dragx)/arrowLengthRatio + dragx;
mouseY = (mouseY-dragy)/arrowLengthRatio + dragy;

addBody(dragx,dragy,mouseX-dragx,mouseY-dragy,dragm);
refreshGraphics();
Expand Down

0 comments on commit 36cb171

Please sign in to comment.