The approach I like for this problem is what Perlbotics suggested. Make a table. I suggest a hash of arrays where the keys are angles and each value is an array of sin and cos values. Then you choose a random angle (0-360) and get both sin and cos from a fast hash with the negative signs included. This takes care of all four quadrands.
Do this for each axis of rotation as you proposed. The article I posted was about picking uniformly distributed points on the surface of a sphere which I believe is more difficult than your problem. The only point I was making with my previous post is that if you pick random sine values the corresponding angles are not uniformly distributed. I'm not sure about proving this approach of three rotations but it seems good to me. I'll think about it more and maybe I'll come up with a proof.
use warnings;
use strict;
my $ref_trig = make_trigtable();
print "\nangle sine cosine\n";
foreach (1..15) {
my $angle = sprintf "%.1f", rand(3600)/10;
printf "%5.1f %8.5f %8.5f\n", $angle, $ref_trig->{$angle}[0], $ref
+_trig->{$angle}[0];
}
sub make_trigtable {
use constant PI => 4 * atan2(1, 1);
use constant DEG_TO_RAD => PI / 180;
my %trig;
foreach (0..3600) {
my $angle = sprintf "%.1f", $_/10;
$trig{$angle}=[sin $angle * DEG_TO_RAD, cos $angle * DEG_TO_RA
+D];
}
return \%trig;
}
__END__
C:\perlmonks>perl sinhash.pl
angle sine cosine
216.2 -0.59061 -0.59061
268.6 -0.99970 -0.99970
166.8 0.22835 0.22835
276.8 -0.99297 -0.99297
81.6 0.98927 0.98927
355.4 -0.08020 -0.08020
11.9 0.20620 0.20620
82.3 0.99098 0.99098
70.1 0.94029 0.94029
173.1 0.12014 0.12014
14.5 0.25038 0.25038
251.3 -0.94721 -0.94721
161.6 0.31565 0.31565
117.7 0.88539 0.88539
319.7 -0.64679 -0.64679
|