chiark / gitweb /
lemon-stand.scad.pl: channelstopup (for revert)
[reprap-play.git] / lemon-stand.scad.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4 use Math::Trig;
5 use Math::Vector::Real;
6 use IO::File;
7 use Data::Dumper;
8 use constant tau => pi*2;
9
10 my $ellipse = 25;
11 my $circle = 7;
12 my $channel = 5;
13 my $xscale = 35/25;
14 my $N = 30; #180; # around ellipse
15 my $M = 20; #80; # around each circle
16 my @channeldistprops = (0, 1/3, 2/3);
17
18 print <<END;
19 // -*- C -*-
20 // *** AUTOGENERATED - DO NOT EDIT ***
21 END
22
23 print "torusyup = ", ($circle / sqrt(2)), ";\n";
24 print "channelstopup = ", ($channel / sqrt(2)), ";\n";
25
26 our @ellipse = map {
27     my $theta = tau * $_ / $N;
28     V( cos($theta) * $ellipse * $xscale, sin($theta) * $ellipse, 0 )
29 } 0..($N-1);
30
31 #print Dumper(\@ellipse);
32
33 our @alongs = map {
34     my $i = $_;
35     $ellipse[ ($i+1) % $N ] - $ellipse[ ($i-1) % $N];
36 } 0..($N-1);
37
38 our @circles = map {
39     my $i = $_;
40     my $centre = $ellipse[$i];
41     my $axis = $alongs[$i]->versor();
42     my $rad0 = $axis x V(0,0,1);
43     my $rad1 = $rad0 x $axis;
44     [ map {
45         my $theta = tau * $_ / $M;
46         $centre + $circle * ($rad0 * cos($theta) + $rad1 * sin($theta));
47     } 0..($M-1) ];
48 } 0..($N-1);
49
50 sub scadvec ($) {
51     my ($v) = @_;
52     return "[ ".(join ", ", @$v)." ]"
53 }
54
55 sub torusy () {
56     print "module Torusy(){ polyhedron(points=[";
57     my $ptix = 0;
58     my @cirpt;
59     foreach my $i (0..$N-1) {
60         foreach my $j (0..$M-1) {
61             print "," if $ptix;
62             print "\n";
63             print "    ",(scadvec $circles[$i][$j]);
64             $cirpt[$i][$j] = $ptix++;
65         }
66     }
67     print "\n  ],\n";
68
69     print "  faces=[";
70     foreach my $i (0..$N-1) {
71         my $i2 = ($i+1) % $N;
72         foreach my $j (0..$M-1) {
73             my $j2 = ($j+1) % $M;
74             print "," if $i || $j;
75             print "\n";
76             print "   [ ", (join ", ",
77                             $cirpt[ $i  ][ $j  ],
78                             $cirpt[ $i  ][ $j2 ],
79                             $cirpt[ $i2 ][ $j  ],
80                            ), " ],";
81             print "   [ ", (join ", ",
82                             $cirpt[ $i  ][ $j2 ],
83                             $cirpt[ $i2 ][ $j2 ],
84                             $cirpt[ $i2 ][ $j  ],
85                            ), " ]";
86         }
87     }
88     print "\n  ]);\n}\n";
89 }
90
91 torusy();
92
93
94 our @distances;
95 push @distances, 0;
96 foreach my $i (1..$N) {
97     my $dist = $distances[ $i-1 ];
98     $dist += abs($ellipse[$i % $N] - $ellipse[$i-1]);
99     $distances[$i] = $dist;
100 }
101
102 sub infodistprop ($) {
103     my ($distprop) = @_;
104     # returns
105     #   ( $ellipse_centreline_point,
106     #     $along_vector )
107     my $dist = $distprop * $distances[$N];
108     foreach my $i (0..$N-1) {
109         my $prorata =
110             ($dist - $distances[$i]) /
111             ($distances[$i+1] - $distances[$i]);
112         next unless 0 <= $prorata && $prorata <= 1;
113         print "// infodistprop $distprop => #$i=$ellipse[$i] $prorata $ellipse[$i+1]\n";
114         return (
115                 (1-$prorata) * $ellipse[$i] + ($prorata) * $ellipse[$i+1],
116                 $alongs[$i],
117                );
118     }
119     die "$distprop ?";
120 }
121
122 sub channels(){
123     print "module Channels(){\n";
124     
125     foreach my $cdp (
126                      (map { 0.5 *  $_    } @channeldistprops),
127                      (map { 0.5 * ($_+1) } @channeldistprops),
128                     ) {
129         my ($ctr, $along) = infodistprop($cdp);
130         my $angle = atan2(-$along->[0], $along->[1]);
131         print "  translate(",scadvec($ctr),")\n";
132         print "  rotate([0,0,$angle*360/",tau,"])\n";
133         print "  rotate([0,90,0])\n";
134         print "  translate([0,0, -2*$circle])\n";
135         print "  cylinder(r=$channel, h=4*$circle, \$fn=$M);\n";
136     }
137     print "}\n";
138 }
139
140 channels();
141
142 while (<DATA>) { print };
143
144 STDOUT->error and die $!;
145 STDOUT->flush or die $!;
146
147 __DATA__
148 module Stand(){
149     difference(){
150         translate([0,0,torusyup])
151             Torusy();
152         intersection(){
153             Channels();
154             translate([-200,-200,-50])
155                 cube([400,400, 50+channelstopup]);
156         }
157         translate([-200,-200,-50])
158             cube([400,400,50]);
159     }
160 }
161 Stand();