chiark / gitweb /
sleepphone-cable-box: adjust from v1
[reprap-play.git] / electron-token.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 = 60 / 2;
11 my $circle = 3.5 / 2;
12 my $xscale = 33 / 100;
13 my $N = 180; # around ellipse
14 my $M = 80; # around each circle
15
16 my $NMdiv = $ENV{'ELECTRONTOKEN_COARSE'} || 1;
17
18 $M /= $NMdiv;
19 $N /= $NMdiv;
20
21 print <<END;
22 // -*- C -*-
23 // *** AUTOGENERATED - DO NOT EDIT ***
24 END
25
26 print "torusyup = ", ($circle / sqrt(2)), ";\n";
27
28 our @ellipse = map {
29     my $theta = tau * $_ / $N;
30     V( cos($theta) * $ellipse * $xscale, sin($theta) * $ellipse, 0 )
31 } 0..($N-1);
32
33 #print Dumper(\@ellipse);
34
35 our @alongs = map {
36     my $i = $_;
37     $ellipse[ ($i+1) % $N ] - $ellipse[ ($i-1) % $N];
38 } 0..($N-1);
39
40 our @circles = map {
41     my $i = $_;
42     my $centre = $ellipse[$i];
43     my $axis = $alongs[$i]->versor();
44     my $rad0 = $axis x V(0,0,1);
45     my $rad1 = $rad0 x $axis;
46     [ map {
47         my $theta = tau * $_ / $M;
48         $centre + $circle * ($rad0 * cos($theta) + $rad1 * sin($theta));
49     } 0..($M-1) ];
50 } 0..($N-1);
51
52 sub scadvec ($) {
53     my ($v) = @_;
54     return "[ ".(join ", ", @$v)." ]"
55 }
56
57 sub torusy () {
58     print "module Torusy(){ polyhedron(points=[";
59     my $ptix = 0;
60     my @cirpt;
61     foreach my $i (0..$N-1) {
62         foreach my $j (0..$M-1) {
63             print "," if $ptix;
64             print "\n";
65             print "    ",(scadvec $circles[$i][$j]);
66             $cirpt[$i][$j] = $ptix++;
67         }
68     }
69     print "\n  ],\n";
70
71     print "  faces=[";
72     foreach my $i (0..$N-1) {
73         my $i2 = ($i+1) % $N;
74         foreach my $j (0..$M-1) {
75             my $j2 = ($j+1) % $M;
76             print "," if $i || $j;
77             print "\n";
78             print "   [ ", (join ", ",
79                             $cirpt[ $i  ][ $j  ],
80                             $cirpt[ $i  ][ $j2 ],
81                             $cirpt[ $i2 ][ $j  ],
82                            ), " ],";
83             print "   [ ", (join ", ",
84                             $cirpt[ $i  ][ $j2 ],
85                             $cirpt[ $i2 ][ $j2 ],
86                             $cirpt[ $i2 ][ $j  ],
87                            ), " ]";
88         }
89     }
90     print "\n  ]);\n}\n";
91 }
92
93 torusy();
94
95
96 our @distances;
97 push @distances, 0;
98 foreach my $i (1..$N) {
99     my $dist = $distances[ $i-1 ];
100     $dist += abs($ellipse[$i % $N] - $ellipse[$i-1]);
101     $distances[$i] = $dist;
102 }
103
104 sub infodistprop ($) {
105     my ($distprop) = @_;
106     # returns
107     #   ( $ellipse_centreline_point,
108     #     $along_vector )
109     my $dist = $distprop * $distances[$N];
110     foreach my $i (0..$N-1) {
111         my $prorata =
112             ($dist - $distances[$i]) /
113             ($distances[$i+1] - $distances[$i]);
114         next unless 0 <= $prorata && $prorata <= 1;
115         print "// infodistprop $distprop => #$i=$ellipse[$i] $prorata $ellipse[$i+1]\n";
116         return (
117                 (1-$prorata) * $ellipse[$i] + ($prorata) * $ellipse[$i+1],
118                 $alongs[$i],
119                );
120     }
121     die "$distprop ?";
122 }
123
124 while (<DATA>) { print };
125
126 STDOUT->error and die $!;
127 STDOUT->flush or die $!;
128
129 __DATA__
130 module Token(){
131     difference(){
132         for (rot=[ 0,120,240 ])
133             rotate([0,0, rot])
134             translate([0,0,torusyup])
135             Torusy();
136         translate([-200,-200,-50])
137             cube([400,400,50]);
138     }
139 }
140 Token();