#!/usr/bin/perl

# -------------------------------------------------------------------------
# pipe v0.1: Perl script to generate data for cutting tube or pipe joints.
#
# Mike Spencer -- mspencer@tallships.ca -- Tue Nov 18  2003
# -------------------------------------------------------------------------


$PI = 3.14159;

# INCREMENT Interval
# ------------------
# The idea here is that we will lay out the output numbers on paper
# that will later be wrapped around a pipe.  It's convenient to have
# equal intervals between data points so that we can easily use graph
# paper or the like to do it.  So the increment $SINCR is a linear
# value.  It's converted to a corresponding angle in the calculation.

# If you're using inches, an $SINCR value of 0.25 reresents 1/4" and
# the intervals on the graph paper will be 1/4".  If that's too many,
# you can increase the value to, say, 0.5 or whatever.

$SINCR = 0.25;

$usage = 
"   Usage: pipe [-g] small-dia big-dia angle-in-degrees

    Find the wrap-pattern values for cutting the end of the small-dia
	pipe to connect to the side of the large-dia pipe.

    Ouput value X is the distance along the wrap direction.
    Ouput value Y is the distance from the wrap baseline to the cut line.

    -g  Option: bare output of (theta, y) suitable for gnuplot datafile.
        This must come first on the command line (simple-minded comline
        parsing.)

    small-dia and large-dia may be equal.
    small-dia may NOT be larger than large-dia.
    Assumes that the axes of the pipes intersect.  No provision is
    made for skew connections or multi-pipe joints.
";

if( $#ARGV != 2 && $#ARGV != 3 )
{   die $usage;
}

if( $ARGV[0] eq '-g' )
{  $gnuplot = 1;
   shift;
}
else
{  $gnuplot = 0;
}

$#ARGV != 2 && die $usage;

if( ! ($ARGV[0] =~ /^[0-9\.]+$/ && $ARGV[1] =~ /^[0-9\.]+$/ ) )
{    print "   Arguments (\"$ARGV[0]\", \"$ARGV[1]\") not both numbers\n\n";
	 die $usage;
}
if( $ARGV[1] < $ARGV[0] )
{    print "   Small diameter ($ARGV[0]) bigger than large diameter ($ARGV[1])\n\n";
     die $usage;
}

$phi = $ARGV[2] * $PI / 180;
$cosphi = cos($phi);
$sinphi = sin($phi);

# The command line arguments are diameters.  The calculation needs
# radii.

$r = $ARGV[0] / 2;
$R = $ARGV[1] / 2;


# This is the angular increment for the iterative calculation

$incr = $SINCR * 180 /($PI * $r);    #15;


if( ! $gnuplot )
{
    printf("\n# Large dia:  %5.2f\n# Small dia:  %5.2f\n# Small circ: %5.2f\n",
              $R, $r,$PI*$r*2);
    printf("# Angle:      %d deg (%.2f radians)\n#\n", $ARGV[2],$phi);

    printf("#  X          Y        theta (deg)\n");
    printf("#--------  --------    -----------\n");
}

for( $theta=0,$s=0; $theta<= 360; $theta+=$incr,$s+=$SINCR)
{   $irad = $theta * $PI / 180;
	$d = ($r - $r*cos($irad)) * $cosphi + $R - 
          sqrt($R**2 - ($r**2 * sin($irad)**2));


    if( $gnuplot )
    {
        printf("%5.1f   %5.2f\n", $theta, $d);
    }
    else
    {    printf("%6.2f     %5.2f        # %5.1f\n", $s, $d, $theta);
    }

}
