#!/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 ------> # +-------------------+ # | | ^ # | () () () () () () | | # | () () () () () () | | 90 # | () () () () () () | | # | () () () () () () | | # | | 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, 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; }