use Data::Dumper;
use constant tau => pi*2;
+my $ellipse = 25 / 2;
+my $circle = 7 / 2;
+my $channelh = 3;
+my $channelw = 4;
+my $xscale = 35 / 25;
+my $N = 180; # around ellipse
+my $M = 80; # around each circle
+my @channeldistprops = (0, 1/3, 2/3);
+
+my $NMdiv = $ENV{'LEMONSTAND_COARSE'} || 1;
+
+$M /= $NMdiv;
+$N /= $NMdiv;
+
print <<END;
// -*- C -*-
// *** AUTOGENERATED - DO NOT EDIT ***
END
-my $ellipse = 20;
-my $circle = 6;
-my $xscale = 2;
-my $N = 30; # around ellipse
-my $M = 20; # around each circle
+print "torusyup = ", ($circle / sqrt(2)), ";\n";
our @ellipse = map {
my $theta = tau * $_ / $N;
} 0..($M-1) ];
} 0..($N-1);
+sub scadvec ($) {
+ my ($v) = @_;
+ return "[ ".(join ", ", @$v)." ]"
+}
+
sub torusy () {
print "module Torusy(){ polyhedron(points=[";
my $ptix = 0;
foreach my $j (0..$M-1) {
print "," if $ptix;
print "\n";
- print " [ ", (join ", ", @{ $circles[$i][$j] }), " ]";
+ print " ",(scadvec $circles[$i][$j]);
$cirpt[$i][$j] = $ptix++;
}
}
torusy();
+
+our @distances;
+push @distances, 0;
+foreach my $i (1..$N) {
+ my $dist = $distances[ $i-1 ];
+ $dist += abs($ellipse[$i % $N] - $ellipse[$i-1]);
+ $distances[$i] = $dist;
+}
+
+sub infodistprop ($) {
+ my ($distprop) = @_;
+ # returns
+ # ( $ellipse_centreline_point,
+ # $along_vector )
+ my $dist = $distprop * $distances[$N];
+ foreach my $i (0..$N-1) {
+ my $prorata =
+ ($dist - $distances[$i]) /
+ ($distances[$i+1] - $distances[$i]);
+ next unless 0 <= $prorata && $prorata <= 1;
+ print "// infodistprop $distprop => #$i=$ellipse[$i] $prorata $ellipse[$i+1]\n";
+ return (
+ (1-$prorata) * $ellipse[$i] + ($prorata) * $ellipse[$i+1],
+ $alongs[$i],
+ );
+ }
+ die "$distprop ?";
+}
+
+sub channels(){
+ print "module Channels(){\n";
+
+ foreach my $cdp (
+ (map { 0.5 * $_ } @channeldistprops),
+ (map { 0.5 * ($_+1) } @channeldistprops),
+ ) {
+ my ($ctr, $along) = infodistprop($cdp);
+ my $angle = atan2(-$along->[0], $along->[1]);
+ print " translate(",scadvec($ctr),")\n";
+ print " rotate([0,0,$angle*360/",tau,"])\n";
+ print " rotate([0,90,0])\n";
+ print " translate([0,0, -2*$circle])\n";
+ print " scale([1, $channelw/$channelh/2, 1])\n";
+ print " rotate([0,0,360/8/2])\n";
+ print " cylinder(r=$channelh, h=4*$circle, \$fn=8);\n";
+ }
+ print "}\n";
+}
+
+channels();
+
while (<DATA>) { print };
STDOUT->error and die $!;
STDOUT->flush or die $!;
__DATA__
-Torusy();
+module Stand(){
+ difference(){
+ translate([0,0,torusyup])
+ Torusy();
+ Channels();
+ translate([-200,-200,-50])
+ cube([400,400,50]);
+ }
+}
+Stand();