Below is the file 'firm/led_controller/proj_lookup.pl' from this revision. You can also download the file.
#!/usr/bin/perl -w # ### BOILERPLATE ### # Orthographic Cube Firmware # Copyright (C) 2006 Peter Todd <pete@petertodd.org> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # ### BOILERPLATE ### # Create the x,y,z vertex rotation table. # This takes a x,y,z vertex and rotates it about the x axis and the y axis. No rotation is done for the z axis. # Some observations... Since this is a cube, x,y,z are either +l or -l where h # is the length of any side of the cube. So we map + to 1 and - to 0 # The rotations, a and b, are stored as 0 - $p representing 0 to 2pi # The equations to obtain x,y,z given a,b are as follows: # # x = x(cos a) + y(sin a)(sin b) + z(sin a)(cos b) # y = y(cos b) - z(sin b) # z = -x(sin a) + y(cos a)(sin b) + z(cos a)(cos b) # Observe that each of the three parts can be represented as the sum of k(cos i)(cos j), # therefore our actual lookup table will be in the that form. The lookups will # then simply substitute cos(90 + x) where sin's are needed. $dsize = 35; $l = 8; $r = 64; $p = $r / 2; $pi = 3.1415926532; $cs = 256/4; $m = 16; print "#define proj_lookup_tbl(k,i,j) (proj_lookup_tbl_real[(((k) * ($r * $r)) + ((i) * $r)) + (j)])\n"; print "// The following takes k,i,j and returns k(cos i)(cos j)\n"; print "#define ccterm(k,i,j) ((uint16_t)proj_lookup_tbl(((uint8_t)(k)),((uint8_t)(i)) >> 2,((uint8_t)(j)) >> 2))\n"; print "\n"; print "// The following takes vertex x,y,z and angles a,b and returns the rotated x,y or z\n"; print "\n"; print "// x = x(cos a) + y(sin a)(sin b) + z(sin a)(cos b)\n"; print "// = x(cos a)(cos 0) + y(cos a + 90)(cos b + 90) + z(cos a + 90)(cos b)\n"; print "#define proj_lookup_x(x,y,z,a,b) (uint8_t)(((ccterm(x,a,0) + ccterm(y,a + $cs,b + $cs) + ccterm(z,a + $cs,b)) / $m) + ($dsize / 2))\n"; print "\n"; print "// y = y(cos b) - z(sin b)\n"; print "// = y(cos 0)(cos b) - z(cos 0)(cos b + 90)\n"; print "#define proj_lookup_y(x,y,z,a,b) (uint8_t)(((ccterm(y,0,b) - ccterm(z,0,b + $cs)) / $m) + ($dsize / 2))\n"; print "\n"; print "// z = -x(sin a) + y(cos a)(sin b) + z(cos a)(cos b)\n"; print "// = -x(cos a + 90)(cos 0) + y(cos a)(cos b + 90) + z(cos a)(cos b)\n"; print "#define proj_lookup_z(x,y,z,a,b) (uint8_t)(((ccterm(-x,a + $cs,0) + ccterm(y,a,b + $cs) + ccterm(z,a,b)) / $m) + ($dsize / 2))\n"; print "\n"; sub round { my($number) = shift; return int($number + .5 * ($number <=> 0));; } # create the lookup table # # outer loop is the constant $thigh = $tlow = 0; print "const int8_t proj_lookup_tbl_real[] = {\n"; for ($k = 0; $k < 2; $k++){ print " // k = $k\n"; # inner loops are the two angles for ($i = 0; $i < $r; $i++){ print " "; for ($j = 0; $j < $r; $j++){ $d = (($k - 0.5) * 2) * $l * cos(($i / $r) * $pi * 2) * cos(($j / $r) * $pi * 2); $d = $d * $m; # report on the extremes of the table if ($d > $thigh) { $thigh = $d; } if ($d < $tlow) { $tlow = $d; } # hard limit to -128 to 127 if ($d < -128) { $d = -128; } if ($d > 127) { $d = 127; } $d = round($d); print "$d"; if ($j != ($r - 1)){ print ","; } } print ""; if ($i != ($r - 1)){ print ","; } print " // i = $i \n"; } print ""; if ($k != 1){ print ","; } print " // k = $k \n"; } print "}; // highest value = $thigh lowest value = $tlow (before limiting to -128 to 127)\n";