1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-15 09:10:38 +02:00
wernermisc/vialtray/tray.pl
Werner Almesberger 1d72af733e vialtray: make a tray for vials containing 0402/0603 components (in progress)
This doesn't work yet. In particular, going through "cameo" doesn't seem
the most convenient choice, since "cameo" requires paths to be closed,
which is something the paths we use here aren't. (Conceptually, thet are
closed, but the implementation skips some small segments.)

This commit is just a snapshot before I experiment with changing the
algorithm.
2010-11-27 20:17:25 -03:00

259 lines
3.6 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 ------>
# +-------------------+
# | | ^
# | () () () () () () | |
# | () () () () () () | | 90
# | () () () () () () | |
# | () () () () () () | |
# | | v
# +-------------------+
#
# start depth
$z0 = -0.5;
# floor depth
$zf = -15;
# maximum depth step
$zs = 2;
# distance between columns
$xs = 24;
# distance between vial centers within columns
$ys = 20;
# vial diameter
$vd = 18.6;
# minimum wall thickness
$mw = 2;
$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*0.75;
$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, $mw/2, $br, @m_ccw);
&yarc($x0, $y0,
-1, -($ys-$mw)/2, $end, $vr, @m_cw);
} else {
&yarc($x0, $y0,
1, -$vr, ($ys-$mw)/2, $vr, @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, -$mw/2, $br, @m_ccw);
&yarc($x0, $y0,
1, ($ys-$mw)/2, -$end, $vr, @m_cw);
} else {
&yarc($x0, $y0,
1, $vr, -($ys-$mw)/2, $vr, @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);
}
$y += $ys;
}
$x += $xs;
print "\n";
}
}
($x0, $y0) = (5+$ys/2, 5+$ys/2);
$z = $z0;
for ($i = 0; $i != $nz; $i++) {
print "#%%r_tool=", $r, "\n";
&do_cols;
print "#%%r_tool=0\n";
&do_circles;
$z -= $zs;
}