wernermisc/vialtray/tray.pl

260 lines
3.7 KiB
Perl
Executable File

#!/usr/bin/perl
use POSIX;
$PI = atan2(1, 1)*4;
$epsilon = 0.02;
$d = 25.4/8; # 1/8"
$r = $d/2;
sub orig
{
$x0 = $_[0];
$y0 = $_[1];
}
sub mil
{
return $_[0]/1000*25.4;
}
sub cut
{
if (defined $x) {
if ($x == $_[0]+$x0 && $y == $_[1]+$y0) {
shift @_;
shift @_;
} else {
print "\n";
}
}
while (@_) {
$x = shift @_;
$y = shift @_;
$x += $x0;
$y += $y0;
print "$x $y $z\n";
}
}
sub mm
{
local ($x, $y, @m) = @_;
return ($x*$m[0]+$y*$m[1], $x*$m[2]+$y*$m[3]);
}
sub a2m
{
local ($a) = $_[0]/180*$PI;
return (cos($a), sin($a), -sin($a), cos($a));
}
sub yarc
{
local ($x, $y, $dx, $dy0, $dy1, $r, @m) = @_;
local ($dy);
$dx = ($dx > 0 ? 1 : -1)*sqrt($r*$r-$dy0*$dy0+$epsilon);
$dy = $dy0;
while (1) {
if ($dy0 < $dy1) {
last if $dy >= $dy1-$epsilon;
} else {
last if $dy <= $dy1+$epsilon;
}
print $x+$dx, " ", $y+$dy, " ", $z, "\n";
($dx, $dy) = &mm($dx, $dy, @m);
}
}
sub circ
{
local ($x, $y, $r, $n) = @_;
local ($a, $dx, $dy);
for ($a = 0; $a <= 2*$PI+$epsilon; $a += 2*$PI/$n) {
$dx = $r*sin($a);
$dy = $r*cos($a);
print $x+$dx, " ", $y+$dy, " ", $z, "\n";
}
}
#
# general shape:
#
# <------ 150 ------>
# +-------------------+
# | | ^
# | () () () () () () | |
# | () () () () () () | | 93
# | () () () () () () | |
# | () () () () () () | |
# | | v
# +-------------------+
#
# start depth
$z0 = -0.5;
# floor depth
$zf = -18;
# maximum depth step
$zs = 2.5;
# distance between columns
$xs = 24;
# distance between vial centers within columns
$ys = 20;
# vial diameter
$vd = 18.7;
# minimum wall thickness
$mw = 2.5;
$nc = 6;
$nr = 4;
@m_cw = &a2m(1);
@m_ccw = &a2m(-1);
# vial hole radius
$vr = $vd/2;
# circle radii: first, last, increment
$r0 = $r/2;
$r1 = $vr-$r*1.5;
$rs = $r*0.75;
#
# x offset at which the vial bay stops
#
$t = $ys/2-$mw/2;
$xo = sqrt($vr*$vr-$t*$t);
#
# radius of the arcs connecting vial bays
#
$br = $vr*($mw/2)/$t;
# x offset of the center of the arcs connecting vial bays
#
#$bx = $xo+sqrt($br*$br-($mw/2)*($mw/2));
$bx = $xo+$xo*($mw/2)/$vr;
print STDERR "t = $t\n";
print STDERR "xo = $xo\n";
print STDERR "br = $br\n";
print STDERR "bx = $bx\n";
# adjust the z step
$nz = POSIX::ceil(($z0-$zf)/$zs);
$zs = ($z0-$zf)/$nz;
print STDERR "nz = $nz\n";
print STDERR "zs = $zs\n";
print STDERR "r0 = $r0\n";
print STDERR "r1 = $r1\n";
print STDERR "rs = $rs\n";
sub do_col
{
local ($x0) = @_;
local ($rw, $end);
for ($rw = 0; $rw != $nr; $rw++) {
if ($rw) {
$end = $rw == $nr-1 ? $vr : ($ys-$mw)/2;
&yarc($x0-$bx, $y0-$ys/2,
1, -$mw/2-$r, $mw/2+$r, $br+$r, @m_ccw);
&yarc($x0, $y0,
-1, -($ys-$mw)/2+$r, $end-$r, $vr-$r, @m_cw);
} else {
&yarc($x0, $y0,
1, -$vr+$r, ($ys-$mw)/2-$r, $vr-$r, @m_cw);
}
$y0 += $ys;
}
for ($rw = 0; $rw != $nr; $rw++) {
$y0 -= $ys;
if ($rw) {
$end = $rw == $nr-1 ? $vr : ($ys-$mw)/2;
&yarc($x0+$bx, $y0+$ys/2,
-1, $mw/2+$r, -$mw/2-$r, $br+$r, @m_ccw);
&yarc($x0, $y0,
1, ($ys-$mw)/2-$r, -$end+$r, $vr-$r, @m_cw);
} else {
&yarc($x0, $y0,
1, $vr-$r, -($ys-$mw)/2+$r, $vr-$r, @m_cw);
}
}
}
sub do_cols
{
local ($c, $x);
$x = $x0;
for ($c = 0; $c != $nc; $c++) {
&do_col($x);
$x += $xs;
print "\n";
}
}
sub do_circles
{
local ($c, $rw, $x, $y);
local ($rr);
$x = $x0;
for ($c = 0; $c != $nc; $c++) {
$y = $y0;
for ($rw = 0; $rw != $nr; $rw++) {
for ($rr = $r0; $rr <= $r1; $rr += $rs) {
&circ($x, $y, $rr, 180);
}
print "\n";
$y += $ys;
}
$x += $xs;
}
}
($x0, $y0) = (5+$ys/2, 6.5+$ys/2);
$z = $z0;
for ($i = 0; $i != $nz; $i++) {
# print "#%%r_tool=0\n";
&do_circles;
# print "#%%r_tool=", $r, "\n";
&do_cols;
$z -= $zs;
}