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