ClarkeRubber

3D animation - interacting masses

Nov 26th, 2011
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 10.75 KB | None | 0 0
  1. <?php
  2. function cubeLatticeArray($a, $b){
  3.   //$a is the radius of the larger sphere, $b is the radius of the smallers spheres that are fitting into the larger sphere.
  4.   //This function will only solve for one eighth of the cube. I will later have this function copy these results over
  5.   //to the other 7 parts of the sphere.
  6.   $radius = pow($a, 2);
  7.     $points[0] = array('x' => $b, 'y' => $b, 'z' => sqrt(pow($a, 2)-pow(2*$b, 2))-$b); //I solved this line for myself, stfu
  8.     $pass = true;
  9.     for($i = 1; $pass == true; $i++){
  10.         $current = end($points);
  11.         if($radius > (pow($current['x']+$b, 2)+pow($current['y']+3*$b, 2)+pow($current['z']+$b, 2))){
  12.             //Move to the next Y cube relative to the last exact position
  13.             $points[$i] = array('x' => $current['x'], 'y' => $current['y']+2*$b, 'z' => $current['z']);
  14.         }elseif($radius > (pow($current['x']+3*$b, 2)+pow(2*$b, 2)+pow($current['z']+$b, 2))){
  15.             //Move to the next X cube relative to the last Z and X position (not Y)
  16.             $points[$i] = array('x' => $current['x']+2*$b, 'y' => $b, 'z' => $current['z']);
  17.         }elseif($radius > (pow(2*$b, 2)+pow(2*$b, 2)+pow($current['z']-3*$b, 2)) && $current['z']-3*$b >= 0){
  18.             //Move to the next Z cube relative to the last Z value (not x or y)
  19.             $points[$i] = array('x' => $b, 'y' => $b, 'z' => $current['z']-2*$b);
  20.         }else{
  21.             $pass = false;
  22.             $total = $i;
  23.         }
  24.     }
  25.     foreach($points as $key => $value){
  26.         $total++;
  27.         $points[$total]['x'] = -$value['x'];
  28.         $points[$total]['y'] = -$value['y'];
  29.         $points[$total]['z'] = -$value['z'];
  30.         $total++;
  31.         $points[$total]['x'] = -$value['x'];
  32.         $points[$total]['y'] = $value['y'];
  33.         $points[$total]['z'] = -$value['z'];
  34.         $total++;
  35.         $points[$total]['x'] = -$value['x'];
  36.         $points[$total]['y'] = -$value['y'];
  37.         $points[$total]['z'] = $value['z'];
  38.         $total++;
  39.         $points[$total]['x'] = $value['x'];
  40.         $points[$total]['y'] = -$value['y'];
  41.         $points[$total]['z'] = -$value['z'];
  42.         $total++;
  43.         $points[$total]['x'] = -$value['x'];
  44.         $points[$total]['y'] = $value['y'];
  45.         $points[$total]['z'] = $value['z'];
  46.         $total++;
  47.         $points[$total]['x'] = $value['x'];
  48.         $points[$total]['y'] = -$value['y'];
  49.         $points[$total]['z'] = $value['z'];
  50.         $total++;
  51.         $points[$total]['x'] = $value['x'];
  52.         $points[$total]['y'] = $value['y'];
  53.         $points[$total]['z'] = -$value['z'];
  54.     }
  55.     echo "$total </br>";
  56.     return $points;
  57. }
  58.  
  59. function minAngle($line, $p, $threshold, $focus, $depth){
  60.     //---Find the side lengths of the triangle created by the point and the line
  61.     $b = pow($line['x'][1]-$line['x'][2], 2)+pow($line['y'][1]-$line['y'][2], 2)+pow($line['z'][1]-$line['z'][2], 2); //Difference between the two points of the line
  62.     $c = pow($line['x'][1]-$p['x'], 2)+pow($line['y'][1]-$p['y'], 2)+pow($line['z'][1]-$p['z'], 2); //Difference between the start of the line and the point
  63.     $a = pow($p['x']-$line['x'][2], 2)+pow($p['y']-$line['y'][2], 2)+pow($p['z']-$line['z'][2], 2); //difference between the end of the line and the point
  64.     //---Find the angle formed between the ray and the point
  65.     $angle = rad2deg(acos(($b+$c-$a)/(2*sqrt($b)*sqrt($c)))); //cos^(-1)((b^2 + c^2 - a^2) / 2bc), will give the angle between the point an the ray.
  66.    
  67.     //---Find out how out of focus the point is
  68.     $dif = intval(abs($p['y']-$focus)/$depth);
  69.     if($dif == 0){
  70.         $dif = 1;
  71.     }
  72.     if($angle < $threshold*$dif){
  73.         //---Depending on the angle formed and the level of focus, return the brightness of the ray/pixel.
  74.         $return = intval((($threshold*$dif-$angle)/($threshold*$dif))*255);
  75.         return $return;
  76.     }else{
  77.         return 0;
  78.     }
  79. }
  80.  
  81. function movePoint($current_point, $other_points, $mass, $time_interval){
  82.     //Given the above information, this function will return the resulting point after it has been affected by the gravity of the other points.
  83.     /* Basically the method is:
  84.         -Find the distance between the given point, and another of the rest of the points
  85.         -Find the net force experienced by the point
  86.         -Separate net force into the X, Y and Z planes.
  87.         -Repeat steps 1-3, summing up the separated forces.
  88.         -Then, a = G*((m1*m2)/(r^2))/m1
  89.         -I guess that the period is going to affect the velocity, and then displacement... how does it go again. :S
  90.         -s = ut+1/2at^2
  91.         -...I'm going to need more information from the $current_point, I believe. Going to need velocity aswell.
  92.         -shit...
  93.     */
  94.     $net['x'] = 0;
  95.     $net['y'] = 0;
  96.     $net['z'] = 0;
  97.    
  98.     $dif['x'] = 0;
  99.     $dif['y'] = 0;
  100.     $dif['z'] = 0;
  101.     foreach($other_points as $key => $other){
  102.         //I suck at creating variable names
  103.         //And I didn't really think this through
  104.         if($current_point['x'] != $other['x'] && $current_point['y'] != $other['y'] && $current_point['z'] != $other['x']){
  105.             $dif['x'] = $other['x']-$current_point['x'];
  106.             $dif['y'] = $other['y']-$current_point['y'];
  107.             $dif['z'] = $other['z']-$current_point['z'];
  108.             $distance = sqrt(pow($dif['x'], 2)+pow($dif['y'], 2)+pow($dif['z'], 2)); //Pretty much the radius
  109.             $acceleration = ((6.67300*pow(10, -11)*pow($mass, 2))/pow($distance, 2))/$mass; //I guess that's right
  110.             echo "acc = $acceleration </br> \n";
  111.             //now to divide this into the 3 planes, x, y and z
  112.             if($dif['x'] < 0){
  113.                 $multiplier['x'] = -1;
  114.             }elseif($dif['x'] == 0){
  115.                 $multiplier['x'] = 0;
  116.             }else{
  117.                 $multiplier['x'] = 1;
  118.             }
  119.            
  120.             if($dif['y'] < 0){
  121.                 $multiplier['y'] = -1;
  122.             }elseif($dif['y'] == 0){
  123.                 $multiplier['y'] = 0;
  124.             }else{
  125.                 $multiplier['y'] = 1;
  126.             }
  127.            
  128.             if($dif['z'] < 0){
  129.                 $multiplier['z'] = -1;
  130.             }elseif($dif['x'] == 0){
  131.                 $multiplier['z'] = 0;
  132.             }else{
  133.                 $multiplier['z'] = 1;
  134.             }
  135.            
  136.             $output_acceleration['x'] += $multiplier['x']*abs($acceleration*cos(acos($dif['x']/$distance)));
  137.             $output_acceleration['y'] += $multiplier['y']*abs($acceleration*cos(acos($dif['y']/$distance)));
  138.             $output_acceleration['z'] += $multiplier['z']*abs($acceleration*cos(acos($dif['z']/$distance)));
  139.            
  140.             echo "acc (" . $output_acceleration['x'] . ", " . $output_acceleration['y'] . ", " . $output_acceleration['z'] . ") </br> \n";
  141.             //That was more simple that I thought.
  142.         }else{
  143.             $current_key = $key;
  144.         }
  145.         $displacement['x'] = $current_point['xv']*$time_interval+0.5*$output_acceleration['x']*pow($time_interval, 2); // s = ut+(1/2)at^2
  146.         $displacement['y'] = $current_point['yv']*$time_interval+0.5*$output_acceleration['y']*pow($time_interval, 2); // s = ut+(1/2)at^2
  147.         $displacement['z'] = $current_point['zv']*$time_interval+0.5*$output_acceleration['z']*pow($time_interval, 2); // s = ut+(1/2)at^2
  148.         global $points;
  149.         $points[$current_key]['xv'] = $displacement['x']/$time_interval;
  150.         $points[$current_key]['yv'] = $displacement['y']/$time_interval;
  151.         $points[$current_key]['zv'] = $displacement['z']/$time_interval;
  152.     }
  153.     $current_point['x'] += $displacement['x'];
  154.     $current_point['y'] += $displacement['y'];
  155.     $current_point['z'] += $displacement['z'];
  156.     //Holy shit, I think that's done. This isn't written the most efficiently, but it will do.
  157.     return $current_point;
  158. }
  159.  
  160. //---Variables
  161. $screen_dimensions = array('height' => 100, 'width' => 100); //Do not make this very large as too much memory/time will be used and the program will fail.
  162. $screen_position = array('x' => 0, 'y' => -20, 'z' => 0); //I spose this could be changed, but I haven't bothered with it.
  163.  
  164. $amount_of_frames = 2; //1 second = 1 frame
  165.  
  166. $screen_viewingAngle = 65; //In degrees
  167. //$focus = (0.5*$screen_dimensions['width'])/tan(deg2rad(0.5*$screen_viewingAngle))+70; //The Y frame which will be in focus.
  168. $focus = 798;
  169. $depth_of_field = 150; //This is kinda like the F-stop on a lens.
  170. $angular_threshold = 1; //This is kinda different, but it's basically the accuracy of the imaging. 0 would be perfect, but would not work.
  171. /* Do not use these yet.
  172. $screen_yaw = 0;
  173. $screen_pitch = 0;
  174. $screen_roll = 0;
  175. */
  176.  
  177. /* BEGIN MAIN PROGRAM */
  178.  
  179. //---Pre-processing variables (inititators of a sort)
  180. $offset['y'] = (0.5*$screen_dimensions['width'])/tan(deg2rad(0.5*$screen_viewingAngle))+$screen_position['y'];
  181. //$offset['x'] = 0.5*$screen_dimensions['width']+$screen_position['x']; NOT USED
  182. $offset['z'] = 0.5*$screen_dimensions['height']-$screen_position['z'];
  183.  
  184. $funny_variable[1] = 0.5*$screen_dimensions['width'];
  185. $funny_variable[2] = 0.5*$screen_dimensions['width']+$screen_position['x'];
  186.  
  187. //$points = cubeLatticeArray(800, 77);
  188. $points[1] = array('x' => 0, 'y' => 0, 'z' => 0);
  189. $points[2] = array('x' => 50, 'y' => 10, 'z' => 50);
  190. foreach($points as $key => $value){
  191.     //Make the velocity on each of the points zero (initiate variables)
  192.     $points[$key]['xv'] = 0;
  193.     $points[$key]['yv'] = 0;
  194.     $points[$key]['zv'] = 0;
  195. }
  196. //---Reset '$current' variables
  197. for($h = 0; $h < $amount_of_frames; $h++){
  198.     $current['z'] = $offset['z'];
  199.     $current['x'] = $screen_position['x']-$funny_variable[1];
  200.  
  201.     //---Begin writing file
  202.     unlink("image$h.ppm"); //file that we will be editing, we are are deleting the file so we have a clean file to work on
  203.     $fh = fopen("image$h.ppm", 'a+'); //creates the image file that we will be editting and opens the file for appending
  204.  
  205.     $print_height = 1+$screen_dimensions['height'];
  206.     $print_width = 1+$screen_dimensions['width'];
  207.  
  208.     $startWrite = "P3\n# image$h.ppm\n$print_width $print_height\n255"; //fomatting the ppm file
  209.     fwrite($fh, $startWrite);
  210.  
  211.     //---Begin building rays and printing the file
  212.     //These two steps are done at the same time for efficiency, and memory
  213.     for($i = 0; $i < ($print_height*$print_width); $i++){
  214.         //---Origin points
  215.         $lines['x'][1] = $screen_position['x'];
  216.         $lines['y'][1] = $screen_position['y'];
  217.         $lines['z'][1] = $screen_position['z'];
  218.  
  219.         //---Resolve when to move to the next row of pixels
  220.         if($i > 0){
  221.             $current['x']++;
  222.         }
  223.         if($current['x'] > $funny_variable[2]){
  224.             $current['x'] = -$funny_variable[1]+$screen_position['x'];
  225.             $current['z']--;
  226.         }
  227.         //---To points
  228.         $lines['x'][2] = $current['x'];
  229.         $lines['y'][2] = $offset['y'];
  230.         $lines['z'][2] = $current['z'];
  231.  
  232.         if($i%5 == 0){ //basic formatting decides when a new line must be placed
  233.             $Nl = " \n";
  234.         }else{
  235.             $Nl = " ";
  236.         }
  237.         $out = 000;
  238.         foreach($points as $value){
  239.             $colour = minAngle($lines, $value, $angular_threshold, $focus, $depth_of_field);
  240.             if($colour == 255){
  241.                 $out = $colour;
  242.                 break 1;
  243.             //}elseif($colour >= 0 && $colour >= $out){
  244.             }elseif($colour >= 0){
  245.                 $out = str_pad(intval($colour+$out), 3, "0", STR_PAD_LEFT);
  246.                 if($out >= 255){
  247.                     $out = 255;
  248.                     break 1;
  249.                 }
  250.             }
  251.         }
  252.         printf("(%+'04.2d, %+'04.2d, %+'04.2d) = %'03d </br>", $lines['x'][2], $lines['y'][2], $lines['z'][2], $out);
  253.         //echo "(".$lines['x'][2].", ".$lines['y'][2].", ".$lines['z'][2].")= $out </br>\n";
  254.         $write = "$Nl$out $out $out"; //the line that is to be outputted
  255.         fwrite($fh, $write); //write the pixel to the file.
  256.     }
  257.     fclose($fh);
  258.     foreach($points as $key => $value){
  259.         $points[$key] = movePoint($value, $points, 1000, 1);
  260.     }
  261. }
  262. ?>
  263.  
Advertisement
Add Comment
Please, Sign In to add comment