ClarkeRubber

3D animation - Interacting Masses with Depth Perception

Nov 29th, 2011
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 11.45 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.     $limit = ($threshold/$c)+abs($distance-$focus)/$depth;
  67.    
  68.     //---Find out how out of focus the point is
  69.     //Distance between the point and the origin of the ray. This will be a judge of how big the point will appear
  70.     //echo "limit = $limit </br>\n";
  71.     //Kids stuff.
  72.     //More precisely; maximum_angle/(distance_from_origin_to_point^2 + level_of_blur)
  73.     //The size of the point is relative to the inverse square of it's distance from the origin of the screen, hence: 1/d^2
  74.     /*
  75.     $dif = intval(abs($distance-$focus)/$depth);
  76.     if($dif == 0){
  77.         $dif = 1;
  78.     }
  79.     */
  80.     if($angle < $limit){
  81.         //---Depending on the angle formed and the level of focus, return the brightness of the ray/pixel.
  82.         $return = intval(255-255*$angle/$limit);
  83.         //$return = intval((($threshold*$dif-$angle)/($threshold*$dif))*255);
  84.         return $return;
  85.     }else{
  86.         return 0;
  87.     }
  88. }
  89.  
  90. function movePoint($current_point, $other_points, $mass, $time_interval, $key){
  91.     //Given the above information, this function will return the resulting point after it has been affected by the gravity of the other points.
  92.     /* Basically the method is:
  93.         -Find the distance between the given point, and another of the rest of the points
  94.         -Find the net force experienced by the point
  95.         -Separate net force into the X, Y and Z planes.
  96.         -Repeat steps 1-3, summing up the separated forces.
  97.         -Then, a = G*((m1*m2)/(r^2))/m1
  98.         -I guess that the period is going to affect the velocity, and then displacement... how does it go again. :S
  99.         -s = ut+1/2at^2
  100.         -...I'm going to need more information from the $current_point, I believe. Going to need velocity aswell.
  101.         -shit...
  102.     */
  103.     $net['x'] = 0;
  104.     $net['y'] = 0;
  105.     $net['z'] = 0;
  106.    
  107.     $dif['x'] = 0;
  108.     $dif['y'] = 0;
  109.     $dif['z'] = 0;
  110.     foreach($other_points as $key => $other){
  111.         //I suck at creating variable names
  112.         //And I didn't really think this through
  113.         if(!($current_point['x'] == $other['x'] && $current_point['y'] == $other['y'] && $current_point['z'] == $other['x'])){
  114.             $dif['x'] = $other['x']-$current_point['x'];
  115.             $dif['y'] = $other['y']-$current_point['y'];
  116.             $dif['z'] = $other['z']-$current_point['z'];
  117.             $distance = sqrt(pow($dif['x'], 2)+pow($dif['y'], 2)+pow($dif['z'], 2)); //Pretty much the radius
  118.             $acceleration = ((6.67300*pow(10, -11)*$mass)/pow($distance, 2)); //I guess that's right
  119.             //now to divide this into the 3 planes, x, y and z
  120.             if($dif['x'] < 0){
  121.                 $multiplier['x'] = -1;
  122.             }elseif($dif['x'] == 0){
  123.                 $multiplier['x'] = 0;
  124.             }else{
  125.                 $multiplier['x'] = 1;
  126.             }
  127.            
  128.             if($dif['y'] < 0){
  129.                 $multiplier['y'] = -1;
  130.             }elseif($dif['y'] == 0){
  131.                 $multiplier['y'] = 0;
  132.             }else{
  133.                 $multiplier['y'] = 1;
  134.             }
  135.            
  136.             if($dif['z'] < 0){
  137.                 $multiplier['z'] = -1;
  138.             }elseif($dif['x'] == 0){
  139.                 $multiplier['z'] = 0;
  140.             }else{
  141.                 $multiplier['z'] = 1;
  142.             }
  143.            
  144.             $output_acceleration['x'] += $multiplier['x']*abs($acceleration*cos(acos($dif['x']/$distance)));
  145.             $output_acceleration['y'] += $multiplier['y']*abs($acceleration*cos(acos($dif['y']/$distance)));
  146.             $output_acceleration['z'] += $multiplier['z']*abs($acceleration*cos(acos($dif['z']/$distance)));
  147.            
  148.             //echo "acc = $acceleration = (" . $output_acceleration['x'] . ", " . $output_acceleration['y'] . ", " . $output_acceleration['z'] . ") </br> \n";
  149.             //That was more simple that I thought.
  150.         }
  151.     }
  152.     $displacement['x'] = $current_point['xv']*$time_interval+0.5*$output_acceleration['x']*pow($time_interval, 2); // s = ut+(1/2)at^2
  153.     $displacement['y'] = $current_point['yv']*$time_interval+0.5*$output_acceleration['y']*pow($time_interval, 2); // s = ut+(1/2)at^2
  154.     $displacement['z'] = $current_point['zv']*$time_interval+0.5*$output_acceleration['z']*pow($time_interval, 2); // s = ut+(1/2)at^2
  155.  
  156.     echo "displacement = (". $displacement['x'] .", ". $displacement['y'] .", ". $displacement['z'] .") </br> \n";
  157.  
  158.     global $points;
  159.     $points[$key]['xv'] = $displacement['x']/$time_interval;
  160.     $points[$key]['yv'] = $displacement['y']/$time_interval;
  161.     $points[$key]['zv'] = $displacement['z']/$time_interval;
  162.  
  163.     $current_point['x'] += $displacement['x'];
  164.     $current_point['y'] += $displacement['y'];
  165.     $current_point['z'] += $displacement['z'];
  166.     //Holy shit, I think that's done. This isn't written the most efficiently, but it will do.
  167.     //echo "vel = (". $points[$key]['xv'] .", ". $points[$key]['yv'] .", ". $points[$key]['zv'] .") </br> \n";
  168.     //echo "out = (". $current_point['x'] .", ". $current_point['y'] .", ". $current_point['z'] .") </br> \n\n";
  169.     return $current_point;
  170. }
  171.  
  172. //---Variables
  173. $screen_dimensions = array('height' => 400, 'width' => 400); //Do not make this very large as too much memory/time will be used and the program will fail.
  174. $screen_position = array('x' => 0, 'y' => -1400, 'z' => 0); //I spose this could be changed, but I haven't bothered with it.
  175.  
  176. $amount_of_frames = 1000; //1 second = 1 frame
  177.  
  178. $screen_viewingAngle = 80; //In degrees
  179. //$focus = (0.5*$screen_dimensions['width'])/tan(deg2rad(0.5*$screen_viewingAngle))+70; //The Y frame which will be in focus.
  180. $focus = 0;
  181. $depth_of_field = 1000; //This is kinda like the F-stop on a lens.
  182. $angular_threshold = 750000; //This is kinda different, but it's basically the accuracy of the imaging. 0 would be perfect, but would not work.
  183. /* Do not use these yet.
  184. $screen_yaw = 0;
  185. $screen_pitch = 0;
  186. $screen_roll = 0;
  187. */
  188.  
  189. /* BEGIN MAIN PROGRAM */
  190.  
  191. //---Pre-processing variables (inititators of a sort)
  192. $offset['y'] = (0.5*$screen_dimensions['width'])/tan(deg2rad(0.5*$screen_viewingAngle))+$screen_position['y'];
  193. //$offset['x'] = 0.5*$screen_dimensions['width']+$screen_position['x']; NOT USED
  194. $offset['z'] = 0.5*$screen_dimensions['height']-$screen_position['z'];
  195.  
  196. $funny_variable[1] = 0.5*$screen_dimensions['width'];
  197. $funny_variable[2] = 0.5*$screen_dimensions['width']+$screen_position['x'];
  198.  
  199. $points = cubeLatticeArray(800, 115);
  200. foreach($points as $key => $value){
  201.     //Make the velocity on each of the points zero (initiate variables)
  202.     $points[$key]['xv'] = 0;
  203.     $points[$key]['yv'] = 0;
  204.     $points[$key]['zv'] = 0;
  205. }
  206. //---Reset '$current' variables
  207. for($h = 0; $h < $amount_of_frames; $h++){
  208.     $current['z'] = $offset['z'];
  209.     $current['x'] = $screen_position['x']-$funny_variable[1];
  210.  
  211.     //---Begin writing file
  212.     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
  213.     $fh = fopen("image$h.ppm", 'a+'); //creates the image file that we will be editting and opens the file for appending
  214.  
  215.     $print_height = 1+$screen_dimensions['height'];
  216.     $print_width = 1+$screen_dimensions['width'];
  217.  
  218.     $startWrite = "P3\n# image$h.ppm\n$print_width $print_height\n255"; //fomatting the ppm file
  219.     fwrite($fh, $startWrite);
  220.  
  221.     //---Begin building rays and printing the file
  222.     //These two steps are done at the same time for efficiency, and memory
  223.     for($i = 0; $i < ($print_height*$print_width); $i++){
  224.         //---Origin points
  225.         $lines['x'][1] = $screen_position['x'];
  226.         $lines['y'][1] = $screen_position['y'];
  227.         $lines['z'][1] = $screen_position['z'];
  228.  
  229.         //---Resolve when to move to the next row of pixels
  230.         if($i > 0){
  231.             $current['x']++;
  232.         }
  233.         if($current['x'] > $funny_variable[2]){
  234.             $current['x'] = -$funny_variable[1]+$screen_position['x'];
  235.             $current['z']--;
  236.         }
  237.         //---To points
  238.         $lines['x'][2] = $current['x'];
  239.         $lines['y'][2] = $offset['y'];
  240.         $lines['z'][2] = $current['z'];
  241.  
  242.         if($i%5 == 0){ //basic formatting decides when a new line must be placed
  243.             $Nl = " \n";
  244.         }else{
  245.             $Nl = " ";
  246.         }
  247.         $out = 000;
  248.         foreach($points as $value){
  249.             $colour = minAngle($lines, $value, $angular_threshold, $focus, $depth_of_field);
  250.             if($colour == 255){
  251.                 $out = $colour;
  252.                 break 1;
  253.             //}elseif($colour >= 0 && $colour >= $out){
  254.             }elseif($colour >= 0){
  255.                 $out = str_pad(intval($colour+$out), 3, "0", STR_PAD_LEFT);
  256.                 if($out >= 255){
  257.                     $out = 255;
  258.                     break 1;
  259.                 }
  260.             }
  261.         }
  262.         //printf("(%+'04.2d, %+'04.2d, %+'04.2d) = %'03d </br>", $lines['x'][2], $lines['y'][2], $lines['z'][2], $out);
  263.         //echo "(".$lines['x'][2].", ".$lines['y'][2].", ".$lines['z'][2].")= $out </br>\n";
  264.         $write = "$Nl$out $out $out"; //the line that is to be outputted
  265.         fwrite($fh, $write); //write the pixel to the file.
  266.     }
  267.     fclose($fh);
  268.     foreach($points as $key => $value){
  269.         $new_points[$key] = movePoint($value, $points, 1000000000000000, 1, $key);
  270.     }
  271.     foreach($new_points as $key => $value){
  272.         $points[$key] = $value;
  273.     }
  274. }
  275. ?>
  276.  
Advertisement
Add Comment
Please, Sign In to add comment