ClarkeRubber

Gravity simulator under Earth's surface

Oct 22nd, 2011
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.94 KB | None | 0 0
  1. <?php
  2. /*
  3.     Method:
  4. 1. Construct spherical lattice that will be contained within
  5. another larger sphere that we will be testing the gravity at -
  6. at different points.
  7.  
  8. 2. Move the point from the centre of the large, containing sphere
  9. to an outside location of any choosing.
  10.  
  11. 3. Display the results at the test points on a graph.
  12.  
  13. 4. Win.
  14.  
  15.     Method for constructing spherical lattice:
  16. 1. inputs, radius of the larger sphere (a: large whole number, preferably a multiple of 10), radius of the interior
  17. spheres (b: small whole number that should evenly and naturally divide the radius of the larger sphere in whole number ratios)
  18.  
  19. 2. A valid internal sphere is one whose surface (radius) does not exceed the boundaries of the larger containing sphere, and does not over lap with any other spheres. For the sake of simplicity (not accuracy, this is an estimate), I am going to treat the interior spheres as cubes (mainly because I am going to be constructing a cubic lattice), this is because using pythagoras' theorem to test whether the corners of the cubes exceed the distance from the center of the sphere to the surface of the larger containing sphere. (pythagoras' theorem in 3 dimensions r^2 = (x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2
  20.  
  21. 3. Build the sphere using a top down view (treating the XY plane as the top view), start at position (b, b, sqrt(a^2-(2*b)^2))
  22. then copy this location into the other 3 quadrants. These points will be loaded into an array and given unique identifiers.
  23.  
  24. 4. Move to the next level down, (b, b, [start y]-b*2*1), the times by 1 indicates where the level itteration number goes, this will cause the level to decrement down (I know it's a tautology) by a diameter each time. Copy this result to the other 3 quadrants once more.
  25.  
  26. 5. Move to the other test points on that level. Do this by using the simple pixel mapping that I used in the image printer. Move to the next X value (curPx + 2b), and then test the 8 points around the cube, (x+b, y+b, z+b), (x-b, y+b, z+b), (x-b, y-b, z+b)... etc. If the distance to any of these points from (0, 0, 0) is greater than the radius of the larger containing circle, the sphere will not be created and the testing will move to the next Y row, also testing this cube's points. When the Y test fails, move down to the next level. Copy these results to the other 3 quadrants.
  27.  
  28. 6. Note, when initial testing of the next level fails, end constructing the cube lattice.
  29.  
  30.     How to move the point (easy):This is basic modulus and common factors. The crests of each of the frequencies line up
  31. 1. Start at (0, 0, 0). Work out the force vectors (F = GM/r^2), and split this into the X, Y, Z values (so each X, Y, Z value will be true for F^2 = X^2 + Y^2 + Z^2), load these values into array. Force[testpoint][x] = F.
  32.  
  33. 2. Once the array has been filled, work out the sum of the X, Y, Z values for force, the result will be the next force. Return F = X^2 + Y^2 + Z^2.
  34.  
  35.     GRAPH RESULTS:
  36. 1. X-axis is the distance from the centre of the sphere, Y-axis is the resultant net force.
  37.  
  38. Now I gotta write this son of a bitch...
  39. */
  40.  
  41. function cubeLatticeArray($a, $b){
  42.   //$a is the radius of the larger sphere, $b is the radius of the smallers spheres that are fitting into the larger sphere.
  43.   //This function will only solve for one eighth of the cube. I will later have this function copy these results over
  44.   //to the other 7 parts of the sphere.
  45.   $radius = pow($a, 2);
  46.     $points[0] = array('x' => $b, 'y' => $b, 'z' => sqrt(pow($a, 2)-pow(2*$b, 2))-$b); //I solved this line for myself, stfu
  47.     $pass = true;
  48.     for($i = 1; $pass == true; $i++){
  49.         $current = end($points);
  50.         if($radius > (pow($current['x']+$b, 2)+pow($current['y']+3*$b, 2)+pow($current['z']+$b, 2))){
  51.             //Move to the next Y cube relative to the last exact position
  52.             $points[$i] = array('x' => $current['x'], 'y' => $current['y']+2*$b, 'z' => $current['z']);
  53.         }elseif($radius > (pow($current['x']+3*$b, 2)+pow(2*$b, 2)+pow($current['z']+$b, 2))){
  54.             //Move to the next X cube relative to the last Z and X position (not Y)
  55.             $points[$i] = array('x' => $current['x']+2*$b, 'y' => $b, 'z' => $current['z']);
  56.         }elseif($radius > (pow(2*$b, 2)+pow(2*$b, 2)+pow($current['z']-3*$b, 2)) && $current['z']-3*$b >= 0){
  57.             //Move to the next Z cube relative to the last Z value (not x or y)
  58.             $points[$i] = array('x' => $b, 'y' => $b, 'z' => $current['z']-2*$b);
  59.         }else{
  60.             $pass = false;
  61.             $total = $i;
  62.         }
  63.     }
  64.     foreach($points as $key => $value){
  65.         $total++;
  66.         $points[$total]['x'] = -$value['x'];
  67.         $points[$total]['y'] = -$value['y'];
  68.         $points[$total]['z'] = -$value['z'];
  69.         $total++;
  70.         $points[$total]['x'] = -$value['x'];
  71.         $points[$total]['y'] = $value['y'];
  72.         $points[$total]['z'] = -$value['z'];
  73.         $total++;
  74.         $points[$total]['x'] = -$value['x'];
  75.         $points[$total]['y'] = -$value['y'];
  76.         $points[$total]['z'] = $value['z'];
  77.         $total++;
  78.         $points[$total]['x'] = $value['x'];
  79.         $points[$total]['y'] = -$value['y'];
  80.         $points[$total]['z'] = -$value['z'];
  81.         $total++;
  82.         $points[$total]['x'] = -$value['x'];
  83.         $points[$total]['y'] = $value['y'];
  84.         $points[$total]['z'] = $value['z'];
  85.         $total++;
  86.         $points[$total]['x'] = $value['x'];
  87.         $points[$total]['y'] = -$value['y'];
  88.         $points[$total]['z'] = $value['z'];
  89.         $total++;
  90.         $points[$total]['x'] = $value['x'];
  91.         $points[$total]['y'] = $value['y'];
  92.         $points[$total]['z'] = -$value['z'];
  93.     }
  94.     return $points;
  95. }
  96.  
  97. function gravityAtPoints($pos, $array, $radius, $mass, $total){
  98.   //$pos is the distance away from the origin, $array is the array of spheres, $radius is the radius of the spheres, $mass is the total mass of the planet
  99.   //$total is the total amount of spheres.
  100.   $g = 6.6742*pow(10, -11);
  101.   print $g."\n";
  102.   $sphereMass = $mass/$total;
  103.   foreach($array as $key => $value){
  104.     if($value['x'] < $pos){
  105.       $times = -1;
  106.     }else{
  107.       $times = 1;
  108.     }
  109.     $difx = abs($pos-$value['x']);
  110.     $dify = abs($value['y']);
  111.     $difz = abs($value['z']);
  112.     $dist = pow($difx, 2)+pow($dify, 2)+pow($difz, 2);
  113.     $force = ($g*$sphereMass)/$dist;
  114.     $tanh = atan($dify/$difx);
  115.     $xforce = $force*cos($tanh);
  116.     //print "difx: $difx dify: $dify difz: $difz dist: $dist xforce: $xforce \n";
  117.     $sumForce += $xforce*$times;
  118.   }
  119.   return $sumForce;
  120. }
  121.  
  122.  
  123. $radius = 10;
  124. $sphereSize = 200;
  125. $mass = 5.9736*pow(10, 24);
  126. $array = cubeLatticeArray($sphereSize, $radius);
  127.  
  128. end($array);
  129. $total = key($array);
  130.  
  131. var_dump($array);
  132. $pos = 0;
  133.  
  134.  
  135. //THE FILE PRINTER STARTS HERE
  136.  
  137. echo "Name of Your Function\n"; // :D
  138.  
  139. //Your parameters
  140. $domain = array("neg" => 1, "pos" => 300); //Please don't use decimal values. :\
  141. $lineThickness = 3; //Decimals are cool here.
  142. $accuracy = 0.1; //lower the number = higher the accuracy, longer the processing time, larger the image. Please only use values of 10^x
  143.  
  144. //---Begin main program
  145. $maxheight = 0;
  146. $minheight = 0;
  147. for($n = -$domain["neg"]/$accuracy; $n <= $domain["pos"]/$accuracy; $n++){
  148.   $j++;
  149.   $i = gravityAtPoints(abs($n*$accuracy), $array, $radius, $mass, $total)/-10000000; //testing how many steps that it will take for the number $n to reach 1.
  150.   if($i > $maxheight || $j == 0){ //if the result is larger than all the  rest, the new result will become the largest result.
  151.     $maxheight = $i;
  152.   }
  153.   if($i < $minheight || $j == 0){
  154.     $minheight = $i;
  155.   }
  156.   echo $n*$accuracy." = $i\n";
  157.   $x[$j] = $i; //$n is the position along the x-axis, $i is the position along the y-axis.
  158. }
  159. $x[0] = $x[1]; //<same as the line below me>
  160. $x[$j+1] = $x[$j]; //This is because of line 72, where $dif is set. It will try to reference an array with no entry, so dif would otherwise become $x[$CurPx]
  161. //var_dump($x);
  162.  
  163. //---begin writing file
  164. unlink("image.ppm"); //file that we will be editing, we are are deleting the file so we have a clean file to work on
  165. $fh = fopen("image.ppm", 'a+'); //creates the image file that we will be editting and opens the file for appending
  166.  
  167. $domain["dif"] = $domain["neg"]+$domain["pos"];
  168. $width = floor($domain["dif"]/$accuracy); //width of the image is the largest number that was tested
  169. $height = floor(abs($minheight - $maxheight)+1); //height is the largest amount of steps that it took to reach zero
  170.  
  171. $startWrite = "P3\n# image.ppm\n".$width." ".$height."\n255"; //fomatting the ppm file
  172. fwrite($fh, $startWrite);
  173.  
  174. $j = 0;
  175. for($k = -$domain["neg"]/$accuracy; $k < $width*$height; $k++){
  176.   $CurPx = $j%$width; //basic modulus to decide when a new line must be made
  177.   if($j%5 == 0){ //basic formatting decides when a new line must be placed
  178.     $Nl = " \n";
  179.   }else{
  180.     $Nl = " ";
  181.   }
  182.   if($CurPx == 0){
  183.     $CurPy++;
  184.   }
  185.   $dist = $x[$CurPx] - ($maxheight-$CurPy+1);
  186.   $dif = abs($x[$CurPx]-$x[$CurPx+1])+$lineThickness;
  187.   if($dist > -$dif && $dist < $dif){ //basic algebra, fuck I hate zero being counted as an integer
  188.     $red = "255"; //if the if statement above reflects the array which was made on line 23, the pixel will be white
  189.     $green = "255";
  190.     $blue = "255";
  191.   }elseif($CurPy >= $maxheight+1){ //if Y >= 0
  192.     $clr = str_pad(abs(255-abs(floor(255*(($CurPy-$maxheight-2)/$minheight)))), 3, "0", STR_PAD_LEFT);
  193.     if(0 == $CurPx%($width/$domain["dif"])){
  194.       $red = "128";
  195.       $green = "128";
  196.       $blue = "128";
  197.     }elseif($CurPx <= $domain["neg"]/$accuracy){
  198.       $blue = $clr;
  199.       $red = $clr;
  200.       $green = "000";
  201.     }else{
  202.       $green = $clr;
  203.       $blue = "000";
  204.       $red = "000";
  205.     }
  206.   }elseif($CurPy < $maxheight+1){ //if Y < 0
  207.     $clr = str_pad(abs(floor(255*($CurPy/$maxheight))), 3, "0", STR_PAD_LEFT);
  208.     if(0 == $CurPx%($width/$domain["dif"])){
  209.       $red = "128";
  210.       $green = "128";
  211.       $blue = "128";
  212.     }elseif($CurPx <= $domain["neg"]/$accuracy){
  213.       $blue = $clr;
  214.       $red = "000";
  215.       $green = "000";
  216.     }else{
  217.       $red = $clr;
  218.       $blue = "000";
  219.       $green = "000";
  220.     }
  221.   }
  222.   $write = "$Nl$red $green $blue"; //the line that is to be outputted
  223.     fwrite($fh, $write); //write the pixel to the file.
  224.     $j++;
  225. }
  226. fclose($fh); //close the file, done!
  227. ?>
  228.  
Advertisement
Add Comment
Please, Sign In to add comment