Tube muttering calculator??
#1
Senior Member
Thread Starter
Join Date: Dec 2011
Location: NE Ohio
Posts: 2,546
Bikes: 1992 Serotta Colorado II,Co-Motion Speedster, Giant Escape Hybrid, 1977 Schwinn Super Le Tour
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
Quoted: 427 Post(s)
Likes: 0
Liked 106 Times
in
80 Posts
Tube muttering calculator??
I was attempting to use Metal Geek to create some cope templates for practice. After entering the info the template does not go all the way around the tube.
Any help would be great!
Thanks!
Any help would be great!
Thanks!
#2
Team Beer
Join Date: Apr 2004
Location: Sacramento CA
Posts: 6,325
Bikes: Too Many
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
Quoted: 111 Post(s)
Liked 149 Times
in
98 Posts
I generally use this tool. Haven't had those problems. You may want to check your print settings.
https://dogfeatherdesign.com/ttn_js/
https://dogfeatherdesign.com/ttn_js/
__________________
I'm not one for fawning over bicycles, but I do believe that our bikes communicate with us, and what this bike is saying is, "You're an idiot." BikeSnobNYC
I'm not one for fawning over bicycles, but I do believe that our bikes communicate with us, and what this bike is saying is, "You're an idiot." BikeSnobNYC
Likes For Cynikal:
#3
Senior Member
Join Date: Dec 2019
Posts: 896
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
Quoted: 307 Post(s)
Liked 243 Times
in
198 Posts
You might be printing it at the wrong resolution. I print from the GIMP and there's an "Image Settings" tab when you go to print where you can set the X resolution and Y resolution in pixels per inch. Set them both to the same thing. Idk what the right values are for the metalgeek pngs though. But you could experiment by printing it at say 100px/in, measuring it, and then working out from that what it's supposed to be.
#5
Randomhead
Join Date: Aug 2008
Location: Happy Valley, Pennsylvania
Posts: 23,830
Mentioned: 0 Post(s)
Tagged: 0 Thread(s)
Quoted: 4 Post(s)
Liked 3,230 Times
in
2,229 Posts
your print driver is scaling to fit. You need to turn that off. It's in the directions for the tube mitering software, I think.
#6
Senior Member
Join Date: Jul 2006
Location: San Jose (Willow Glen) Ca
Posts: 9,528
Bikes: Kirk Custom JK Special, '84 Team Miyata,(dura ace old school) 80?? SR Semi-Pro 600 Arabesque
Mentioned: 103 Post(s)
Tagged: 0 Thread(s)
Quoted: 2147 Post(s)
Liked 2,405 Times
in
1,334 Posts
Likes For squirtdad:
#7
Senior Member
Join Date: Jun 2004
Location: Torrance, CA
Posts: 3,043
Bikes: Homebuilt steel
Mentioned: 18 Post(s)
Tagged: 0 Thread(s)
Quoted: 2083 Post(s)
Liked 400 Times
in
316 Posts
I like tubemiter.exe
It works fine but realize that the template doesn't bevel the edges of the tube for a truly righteous fit. Plan on filing for a proper fit and hold the tubes up to a lightbulb to see how much light comes though between the tubes. The fit doesn't need to be perfect, but shoot high with your expectation for high pride in building!
It works fine but realize that the template doesn't bevel the edges of the tube for a truly righteous fit. Plan on filing for a proper fit and hold the tubes up to a lightbulb to see how much light comes though between the tubes. The fit doesn't need to be perfect, but shoot high with your expectation for high pride in building!
#8
Senior Member
Join Date: Dec 2019
Posts: 896
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
Quoted: 307 Post(s)
Liked 243 Times
in
198 Posts
I like tubemiter.exe
It works fine but realize that the template doesn't bevel the edges of the tube for a truly righteous fit. Plan on filing for a proper fit and hold the tubes up to a lightbulb to see how much light comes though between the tubes. The fit doesn't need to be perfect, but shoot high with your expectation for high pride in building!
It works fine but realize that the template doesn't bevel the edges of the tube for a truly righteous fit. Plan on filing for a proper fit and hold the tubes up to a lightbulb to see how much light comes though between the tubes. The fit doesn't need to be perfect, but shoot high with your expectation for high pride in building!
#9
Senior Member
Thread Starter
Join Date: Dec 2011
Location: NE Ohio
Posts: 2,546
Bikes: 1992 Serotta Colorado II,Co-Motion Speedster, Giant Escape Hybrid, 1977 Schwinn Super Le Tour
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
Quoted: 427 Post(s)
Likes: 0
Liked 106 Times
in
80 Posts
Re: Mitreing.
Coming from a woodworking background mitres were for flat work and coping was for curved.
But I will move into frame building terminology!!
Coming from a woodworking background mitres were for flat work and coping was for curved.
But I will move into frame building terminology!!
#10
Senior Member
Thread Starter
Join Date: Dec 2011
Location: NE Ohio
Posts: 2,546
Bikes: 1992 Serotta Colorado II,Co-Motion Speedster, Giant Escape Hybrid, 1977 Schwinn Super Le Tour
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
Quoted: 427 Post(s)
Likes: 0
Liked 106 Times
in
80 Posts
My wife ,whom I am making this frame for, came to my rescue and switched the printer setting!!
#11
Randomhead
Join Date: Aug 2008
Location: Happy Valley, Pennsylvania
Posts: 23,830
Mentioned: 0 Post(s)
Tagged: 0 Thread(s)
Quoted: 4 Post(s)
Liked 3,230 Times
in
2,229 Posts
what's annoying is that next time you print something it's going to go all the way to the edges like you don't want
As far as the etymology of coping/mitering, there really isn't another good word and both are used for tubing. Coping might be a better fit, since in woodworking it's making two curved surfaces fit together. Seems like this comes up occasionally on the framebuilding facebook group.
As far as the etymology of coping/mitering, there really isn't another good word and both are used for tubing. Coping might be a better fit, since in woodworking it's making two curved surfaces fit together. Seems like this comes up occasionally on the framebuilding facebook group.
Last edited by unterhausen; 11-30-21 at 10:36 AM.
#12
Senior Member
Join Date: Oct 2014
Location: Portland, OR
Posts: 12,188
Bikes: (2) ti TiCycles, 2007 w/ triple and 2011 fixed, 1979 Peter Mooney, ~1983 Trek 420 now fixed and ~1973 Raleigh Carlton Competition gravel grinder
Mentioned: 121 Post(s)
Tagged: 0 Thread(s)
Quoted: 4339 Post(s)
Liked 3,409 Times
in
2,208 Posts
#13
framebuilder
Framebuilders say "brass" instead of "bronze" like what it really is when we braze things together. Should it be called a fixture or jig has come up for discussion in the past. In the car and industry world it is called coping. I suppose the reason we call it mitering is because that is the word we learned from those of us that went to the UK for our framebuilding training.
Likes For Doug Fattic:
#14
Randomhead
Join Date: Aug 2008
Location: Happy Valley, Pennsylvania
Posts: 23,830
Mentioned: 0 Post(s)
Tagged: 0 Thread(s)
Quoted: 4 Post(s)
Liked 3,230 Times
in
2,229 Posts
What everyone calls bronze is actually brass, so I'm calling it brass again. Or LFB. Not sure who decided it was bronze.
From wiki (you can find other sources) "Brass is composed of copper and zinc, whereas bronze is made up of copper and tin"
Okay, gasflux calls C04 "bronze" even though it's about 30% zinc and has less than one percent tin.
From wiki (you can find other sources) "Brass is composed of copper and zinc, whereas bronze is made up of copper and tin"
Okay, gasflux calls C04 "bronze" even though it's about 30% zinc and has less than one percent tin.
Likes For unterhausen:
#15
Old fart
Join Date: Nov 2004
Location: Appleton WI
Posts: 24,563
Bikes: Several, mostly not name brands.
Mentioned: 153 Post(s)
Tagged: 0 Thread(s)
Quoted: 3398 Post(s)
Liked 3,003 Times
in
1,725 Posts
If you have a C compiler, this open-source code will print a template you can use to miter tubes:
/*----------------------------------------------------------------------------*/
/* Written by Eric Fahlgren efahl@adams.com */
/* November 1994 */
/* */
/* Adapted by Jason Byrne in 2015 to print a miter on each side of tube. */
/* jbyrne27@gmail.com */
/* */
/* Distribute as you see fit. Please retain my name and email address above. */
/* */
/* */
/* If you find any bugs or anomalous behavior, please email me with an */
/* example. */
/*----------------------------------------------------------------------------*/
void fix_libc_(){} /* Subvert stupidity of acc on Sparc */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/*----------------------------------------------------------------------------*/
#define PI 3.14159265359
#define HALF_PI 1.57079632679489661923132169164E+0
#define TWO_PI 6.28318530717958647692528676656E+0
#define SEGS 36
#define INC (TWO_PI / SEGS)
#define DTOR 1.74532925199432957692369076849E-2 /* PI / 180 */
#define RTOD 5.72957795130823208767981548141E+1 /* 180 / PI */
#define DEG(r) ((r) * RTOD)
#define DEGREES(r) ((r) * RTOD)
#define RAD(d) ((d) * DTOR)
#define RADIANS(d) ((d) * DTOR)
/*----------------------------------------------------------------------------*/
typedef enum { FALSE, TRUE } BOOL;
typedef enum { out_PS, out_VIEW } OutputDest;
OutputDest Output = out_PS;
/*----------------------------------------------------------------------------*/
static double PS_MaxY = 0.0;
static BOOL PS_GuideLines = TRUE;
void PS_Header(double R1, double R2, double R3, double F, double A, double A2, char *Label, double P, double *paperSize)
{
if ( Output != out_PS ) return;
printf("%%!PS-Adobe-2.0\n");
printf("gsave\n");
printf("initgraphics\n");
printf("<</PageSize [%g %g]>>setpagedevice", paperSize[0]*72.0, paperSize[1]*72.0); //Units are inches*72
printf("\n");
printf("72 dup scale\n");
printf("0.5 0.5 translate\n");
printf("0.005 setlinewidth\n");
printf("/tick { lineto 0 0.05 rlineto 0 -0.10 rlineto 0 0.05 rlineto } def\n");
printf("/pnum { 10 string cvs show } def\n");
printf("/Courier findfont 10 72 div scalefont setfont\n");
printf("gsave\n");
printf(" 90 rotate\n");
printf(" 1.0 -1.5 translate\n");
printf(" newpath 0.1 1.25 moveto (%s) show\n", Label);
printf(" newpath 0.1 1.00 moveto (D this tube = ) show %f pnum\n", 2*R1);
printf(" newpath 0.1 0.75 moveto (D butt to R = ) show %f pnum\n", 2*R2);
printf(" newpath 0.1 0.50 moveto (D butt to L = ) show %f pnum\n", 2*R3);
printf(" newpath 0.1 0.25 moveto (Offset = ) show %f pnum\n", F );
printf(" newpath 0.1 0.00 moveto (Angle R = ) show %f pnum\n", 90.0-DEGREES(A) );
printf(" newpath 0.1 -0.25 moveto (Angle L = ) show %f pnum\n", 90.0-DEGREES(A2) );
printf(" newpath 0.1 -0.50 moveto (Phase = ) show %f pnum\n", DEGREES(P) );
printf("grestore\n");
printf("newpath 0 0 moveto\n");
}
/*----------------------------------------------------------------------------*/
void PS_Line(double x, double y)
{
if ( Output != out_PS ) return;
if ( y > PS_MaxY ) PS_MaxY = y;
printf("%f %f tick\n", x, y);
}
/*----------------------------------------------------------------------------*/
void PS_Trailer(double x, double y)
{
if ( Output != out_PS ) return;
// printf("0 %f rlineto\n", -y);
printf("closepath stroke\n");
if ( PS_GuideLines ) {
printf("newpath 0 0 moveto 0 %f lineto stroke\n", PS_MaxY);
printf("newpath %f 0 moveto %f %f lineto stroke\n", x/4.0, x/4.0, PS_MaxY);
printf("newpath %f 0 moveto %f %f lineto stroke\n", x/2.0, x/2.0, PS_MaxY);
printf("newpath %f 0 moveto %f %f lineto stroke\n", 3*x/4.0, 3*x/4.0, PS_MaxY);
printf("newpath %f 0 moveto %f %f lineto stroke\n", x, x, PS_MaxY);
printf("newpath 0 %f moveto %f %f lineto stroke\n", PS_MaxY, x, PS_MaxY);
}
printf("showpage\n");
printf("grestore\n");
}
/*----------------------------------------------------------------------------*/
void VIEW_Header(double R1, double R2, double F, double A, char *Label)
{
if ( Output != out_VIEW ) return;
printf("var cre var=xxR1 rea=%f uni=length\n", R1);
printf("var cre var=xxR2 rea=%f uni=length\n", R2);
printf("var cre var=xxF rea=%f uni=length\n", F);
printf("var cre var=xxA rea=%f uni=angle\n", DEGREES(A));
printf("geo cre cur pol pol=.mod1.ground.pol1 loc= &\n");
}
/*----------------------------------------------------------------------------*/
void VIEW_Line(double x, double y, double z)
{
if ( Output != out_VIEW ) return;
printf("%f, %f, %f, &\n", x, y, z);
}
/*----------------------------------------------------------------------------*/
void VIEW_Trailer(double x, double y, double z)
{
if ( Output != out_VIEW ) return;
printf("%f,%f,%f\n", x, y, z);
}
/*----------------------------------------------------------------------------*/
void Header(double R1, double R2, double R3, double F, double A, double A2, char *Label, double P, double *paperSize)
{
switch ( Output ) {
case out_PS : PS_Header (R1, R2, R3, F, A, A2, Label, P, paperSize); break;
case out_VIEW: VIEW_Header(R1, R2, F, A, Label); break;
}
}
/*----------------------------------------------------------------------------*/
void Line(double x, double y, double z, double l)
{
switch ( Output ) {
case out_PS : PS_Line (l, z); break;
case out_VIEW: VIEW_Line(x, y, z); break;
}
}
/*----------------------------------------------------------------------------*/
void Trailer(double x, double y, double z, double l)
{
switch ( Output ) {
case out_PS : PS_Trailer(l, z); break;
case out_VIEW: VIEW_Trailer(x, y, z); break;
}
}
/*----------------------------------------------------------------------------*/
double DrawMiter(double R1, double R2, double F, double A, double L, double Z, double P)
{
int i;
double x, y, z;
double theta;
double R2sqr = R2 * R2;
double m = tan(A); /* Slope of line */
double m2 = tan(A / 2.0); /* To compute intercept */
double b, d;
double points [SEGS+1];
double zmax;
double zmin;
zmax = -1000;
zmin = 1000;
for ( i = 0; i <= SEGS; i++ ) {
theta = -HALF_PI + i * INC + P;
x = R1 * cos(theta) - F; /* x with offset */
y = R1 * sin(theta); /* y */
if ( R2 == 0.0 ) {
z = 0.0; /* z against a flat plate */
b = 0.0;
}
else {
d = R2sqr - x*x; /* z against tube */
z = d < 0.0 ? 0.0 : sqrt(d); /* z without tilt */
b = m * m2 * z; /* Compute intercept of tilted line */
}
z += y * m + b; /* Compute z increment from tilted line */
x += F; /* Move x back where it should be */
if (z > zmax)
zmax = z;
if (z < zmin)
zmin = z;
points[i] = z;
}
for ( i = 0; i <= SEGS; i++ ) {
if ( Output == out_PS ) {
Line(x, y, points[i]+L+Z-zmin, i * INC * R1);
}
}
return zmax-zmin;
}
/*----------------------------------------------------------------------------*/
void WritePoints(double R1, double R2, double R3, double F, double A, double A2, double L, double P, char *Label, double *paperSize)
{
double x, y;
double Z;
Header(R1, R2, R3, F, A, A2, Label, P, paperSize);
Z=DrawMiter(R1, R3, F, A2, 0, 0, 0);
Line(x, y, 0, SEGS * INC * R1);
Line(x, y, 0, 0);
DrawMiter(R1, R2, F, PI-A, L, Z, P);
Line(x, y, 0, SEGS * INC * R1);
Line(x, y, 0, 0);
Trailer(x, y, 0, (SEGS) * INC * R1);
}
/*----------------------------------------------------------------------------*/
void Usage(void)
{
fprintf(stderr, "miter [-dnumber] [-Dnumber] [-p] [-anumber] [-onumber] [-lstring] [-v]\n");
fprintf(stderr, " Example:\n");
fprintf(stderr, " miter -d1.0 -D1.25 -a27 -l"Top tube to head tube"\n");
fprintf(stderr, "\n");
fprintf(stderr, " -d - diameter of mitered tube; default 1.0\n");
fprintf(stderr, " -D - diameter of right tube butting against; default 1.0\n");
fprintf(stderr, " -E - diameter of left tube butting against; default 1.0\n");
fprintf(stderr, " -L - length between deepest point (facing towards middle of tube) of each miter; default 4.0\n");
fprintf(stderr, " -p - butt against flat plate\n");
fprintf(stderr, " -o - offset of d centerline from D centerline; default 0.0\n");
fprintf(stderr, " -a - included angle between centerlines on right side; default 90\n");
fprintf(stderr, " -b - included angle between centerlines on left side; default 90\n");
fprintf(stderr, " -P - phase angle between centerlines of each miter; default 0\n");
fprintf(stderr, " -l - label to print on output\n");
fprintf(stderr, " -v - print output for ADAMS/View\n");
fprintf(stderr, " -g - suppress guidelines on PostScript\n");
fprintf(stderr, " -Z - paper size:\n");
fprintf(stderr, " 0: ANSI A (8.5x11)\n");
fprintf(stderr, " 1: ANSI B (11x17)\n");
fprintf(stderr, " 2: ANSI C (17x22)\n");
fprintf(stderr, " 3: ANSI D (22x34)\n");
fprintf(stderr, " 4: ANSI E (34x44)\n");
fprintf(stderr, " 5: A0 (33.1x46.8)\n");
fprintf(stderr, " 6: A1 (23.4x33.1)\n");
fprintf(stderr, " 7: A2 (16.5x23.4)\n");
fprintf(stderr, " 8: A3 (11.7x16.5)\n");
fprintf(stderr, " 9: A4 (8.3x11.7)\n");
fprintf(stderr, " 10: A5 (5.8x8.3)\n");
fprintf(stderr, " 11: B0 (39.4x55.7)\n");
fprintf(stderr, " 12: B1 (27.8x39.4)\n");
fprintf(stderr, " 13: B2 (19.7x27.8)\n");
fprintf(stderr, " 14: B3 (13.9x19.7)\n");
fprintf(stderr, " 15: B4 (9.8x13.9)\n");
fprintf(stderr, " 16: B5 (6.9x9.8)\n");
exit(1);
}
/*----------------------------------------------------------------------------*/
int main(int ArgC, char *ArgV[])
{
int iArg;
double R1 = 0.5; /* Radius of tube for which we are cutting the miter */
double R2 = 0.5; /* Radius of tube against which we are butting on right*/
double R3 = 0.5; /* Radius of tube against which we are butting on left*/
double L = 4.0; /* Length of mitered tube between deepest point of each miter */
double F = 0.0; /* Offset of R1 centerline from R2 centerline */
double A = 0.0; /* Angle between R1 centerline and R2 centerline */
double P = 0.0; /* Angle between centerline of each miter */
double A2 = 0.0; /* Angle between R1 centerline and R2 centerline on other end*/
char *Label = ""; /* Any comment you wish to provide */
int Z = 0;
double paperSize[2]; /*Paper size in postscript units (inches*72) */
for ( iArg = 1; iArg < ArgC; iArg++ ) {
if ( ArgV[iArg][0] != '-' ) Usage();
switch ( ArgV[iArg][1] ) {
case 'l':
Label = &ArgV[iArg][2];
break;
case 'd':
sscanf(&ArgV[iArg][2], "%lf", &R1);
R1 /= 2.0;
break;
case 'D':
sscanf(&ArgV[iArg][2], "%lf", &R2);
R2 /= 2.0;
break;
case 'E':
sscanf(&ArgV[iArg][2], "%lf", &R3);
R3 /= 2.0;
break;
case 'L':
sscanf(&ArgV[iArg][2], "%lf", &L);
break;
case 'p':
R2 = 0.0;
break;
case 'a':
sscanf(&ArgV[iArg][2], "%lf", &A);
A = RADIANS(90.0 - A);
break;
case 'b':
sscanf(&ArgV[iArg][2], "%lf", &A2);
A2 = RADIANS(90.0 - A2);
break;
case 'P':
sscanf(&ArgV[iArg][2], "%lf", &P);
P = RADIANS(P);
break;
case 'o':
sscanf(&ArgV[iArg][2], "%lf", &F);
break;
case 'v':
Output = out_VIEW;
break;
case 'g':
PS_GuideLines = FALSE;
break;
case 'Z':
sscanf(&ArgV[iArg][2], "%d", &Z);
break;
default:
Usage();
break;
}
}
switch (Z) {
case 0:
paperSize[0] = 8.5; paperSize[1] = 11; break;
case 1:
paperSize[0] = 11; paperSize[1] = 17; break;
case 2:
paperSize[0] = 17; paperSize[1] = 22; break;
case 3:
paperSize[0] = 22; paperSize[1] = 34; break;
case 4:
paperSize[0] = 34; paperSize[1] = 44; break;
case 5:
paperSize[0] = 33.1; paperSize[1] = 46.8; break;
case 6:
paperSize[0] = 23.4; paperSize[1] = 33.1; break;
case 7:
paperSize[0] = 16.5; paperSize[1] = 23.4; break;
case 8:
paperSize[0] = 11.7; paperSize[1] = 16.5; break;
case 9:
paperSize[0] = 8.3; paperSize[1] = 11.7; break;
case 10:
paperSize[0] = 5.8; paperSize[1] = 8.3; break;
case 11:
paperSize[0] = 39.4; paperSize[1] = 55.7; break;
case 12:
paperSize[0] = 27.8; paperSize[1] = 39.4; break;
case 13:
paperSize[0] = 19.7; paperSize[1] = 27.8; break;
case 14:
paperSize[0] = 13.9; paperSize[1] = 19.7; break;
case 15:
paperSize[0] = 9.8; paperSize[1] = 13.9; break;
case 16:
paperSize[0] = 6.9; paperSize[1] = 9.8; break;
default:
paperSize[0] = 8.5; paperSize[1] = 11; break;
}
WritePoints(R1, R2, R3, F, A, A2, L, P, Label, paperSize);
#ifdef TESTING
WritePoints(0.75, 1.625, 0.0, RADIANS(atan(1.7/16.0)));
WritePoints(0.75 / 2.0, 1.625 / 2.0, 0.0, atan(1.7/16.0), "Chain stay to BB");
WritePoints(0.5 / 2.0, 1.125 / 2.0, 0.25, RADIANS(45.0), "Right seat stay to seat tube");
WritePoints(0.5 / 2.0, 1.125 / 2.0, -0.25, RADIANS(45.0), "Left seat stay to seat tube");
WritePoints(1.00/2, 1.25/2, 0.0, RADIANS(90.0 - 72.0), "Top tube to head tube");
WritePoints(1.00/2, 1.125/2, 0.0, RADIANS(90.0 - 75.0), "Top tube to seat tube");
#endif
exit(0);
}
/*----------------------------------------------------------------------------*/
/* Written by Eric Fahlgren efahl@adams.com */
/* November 1994 */
/* */
/* Adapted by Jason Byrne in 2015 to print a miter on each side of tube. */
/* jbyrne27@gmail.com */
/* */
/* Distribute as you see fit. Please retain my name and email address above. */
/* */
/* */
/* If you find any bugs or anomalous behavior, please email me with an */
/* example. */
/*----------------------------------------------------------------------------*/
void fix_libc_(){} /* Subvert stupidity of acc on Sparc */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/*----------------------------------------------------------------------------*/
#define PI 3.14159265359
#define HALF_PI 1.57079632679489661923132169164E+0
#define TWO_PI 6.28318530717958647692528676656E+0
#define SEGS 36
#define INC (TWO_PI / SEGS)
#define DTOR 1.74532925199432957692369076849E-2 /* PI / 180 */
#define RTOD 5.72957795130823208767981548141E+1 /* 180 / PI */
#define DEG(r) ((r) * RTOD)
#define DEGREES(r) ((r) * RTOD)
#define RAD(d) ((d) * DTOR)
#define RADIANS(d) ((d) * DTOR)
/*----------------------------------------------------------------------------*/
typedef enum { FALSE, TRUE } BOOL;
typedef enum { out_PS, out_VIEW } OutputDest;
OutputDest Output = out_PS;
/*----------------------------------------------------------------------------*/
static double PS_MaxY = 0.0;
static BOOL PS_GuideLines = TRUE;
void PS_Header(double R1, double R2, double R3, double F, double A, double A2, char *Label, double P, double *paperSize)
{
if ( Output != out_PS ) return;
printf("%%!PS-Adobe-2.0\n");
printf("gsave\n");
printf("initgraphics\n");
printf("<</PageSize [%g %g]>>setpagedevice", paperSize[0]*72.0, paperSize[1]*72.0); //Units are inches*72
printf("\n");
printf("72 dup scale\n");
printf("0.5 0.5 translate\n");
printf("0.005 setlinewidth\n");
printf("/tick { lineto 0 0.05 rlineto 0 -0.10 rlineto 0 0.05 rlineto } def\n");
printf("/pnum { 10 string cvs show } def\n");
printf("/Courier findfont 10 72 div scalefont setfont\n");
printf("gsave\n");
printf(" 90 rotate\n");
printf(" 1.0 -1.5 translate\n");
printf(" newpath 0.1 1.25 moveto (%s) show\n", Label);
printf(" newpath 0.1 1.00 moveto (D this tube = ) show %f pnum\n", 2*R1);
printf(" newpath 0.1 0.75 moveto (D butt to R = ) show %f pnum\n", 2*R2);
printf(" newpath 0.1 0.50 moveto (D butt to L = ) show %f pnum\n", 2*R3);
printf(" newpath 0.1 0.25 moveto (Offset = ) show %f pnum\n", F );
printf(" newpath 0.1 0.00 moveto (Angle R = ) show %f pnum\n", 90.0-DEGREES(A) );
printf(" newpath 0.1 -0.25 moveto (Angle L = ) show %f pnum\n", 90.0-DEGREES(A2) );
printf(" newpath 0.1 -0.50 moveto (Phase = ) show %f pnum\n", DEGREES(P) );
printf("grestore\n");
printf("newpath 0 0 moveto\n");
}
/*----------------------------------------------------------------------------*/
void PS_Line(double x, double y)
{
if ( Output != out_PS ) return;
if ( y > PS_MaxY ) PS_MaxY = y;
printf("%f %f tick\n", x, y);
}
/*----------------------------------------------------------------------------*/
void PS_Trailer(double x, double y)
{
if ( Output != out_PS ) return;
// printf("0 %f rlineto\n", -y);
printf("closepath stroke\n");
if ( PS_GuideLines ) {
printf("newpath 0 0 moveto 0 %f lineto stroke\n", PS_MaxY);
printf("newpath %f 0 moveto %f %f lineto stroke\n", x/4.0, x/4.0, PS_MaxY);
printf("newpath %f 0 moveto %f %f lineto stroke\n", x/2.0, x/2.0, PS_MaxY);
printf("newpath %f 0 moveto %f %f lineto stroke\n", 3*x/4.0, 3*x/4.0, PS_MaxY);
printf("newpath %f 0 moveto %f %f lineto stroke\n", x, x, PS_MaxY);
printf("newpath 0 %f moveto %f %f lineto stroke\n", PS_MaxY, x, PS_MaxY);
}
printf("showpage\n");
printf("grestore\n");
}
/*----------------------------------------------------------------------------*/
void VIEW_Header(double R1, double R2, double F, double A, char *Label)
{
if ( Output != out_VIEW ) return;
printf("var cre var=xxR1 rea=%f uni=length\n", R1);
printf("var cre var=xxR2 rea=%f uni=length\n", R2);
printf("var cre var=xxF rea=%f uni=length\n", F);
printf("var cre var=xxA rea=%f uni=angle\n", DEGREES(A));
printf("geo cre cur pol pol=.mod1.ground.pol1 loc= &\n");
}
/*----------------------------------------------------------------------------*/
void VIEW_Line(double x, double y, double z)
{
if ( Output != out_VIEW ) return;
printf("%f, %f, %f, &\n", x, y, z);
}
/*----------------------------------------------------------------------------*/
void VIEW_Trailer(double x, double y, double z)
{
if ( Output != out_VIEW ) return;
printf("%f,%f,%f\n", x, y, z);
}
/*----------------------------------------------------------------------------*/
void Header(double R1, double R2, double R3, double F, double A, double A2, char *Label, double P, double *paperSize)
{
switch ( Output ) {
case out_PS : PS_Header (R1, R2, R3, F, A, A2, Label, P, paperSize); break;
case out_VIEW: VIEW_Header(R1, R2, F, A, Label); break;
}
}
/*----------------------------------------------------------------------------*/
void Line(double x, double y, double z, double l)
{
switch ( Output ) {
case out_PS : PS_Line (l, z); break;
case out_VIEW: VIEW_Line(x, y, z); break;
}
}
/*----------------------------------------------------------------------------*/
void Trailer(double x, double y, double z, double l)
{
switch ( Output ) {
case out_PS : PS_Trailer(l, z); break;
case out_VIEW: VIEW_Trailer(x, y, z); break;
}
}
/*----------------------------------------------------------------------------*/
double DrawMiter(double R1, double R2, double F, double A, double L, double Z, double P)
{
int i;
double x, y, z;
double theta;
double R2sqr = R2 * R2;
double m = tan(A); /* Slope of line */
double m2 = tan(A / 2.0); /* To compute intercept */
double b, d;
double points [SEGS+1];
double zmax;
double zmin;
zmax = -1000;
zmin = 1000;
for ( i = 0; i <= SEGS; i++ ) {
theta = -HALF_PI + i * INC + P;
x = R1 * cos(theta) - F; /* x with offset */
y = R1 * sin(theta); /* y */
if ( R2 == 0.0 ) {
z = 0.0; /* z against a flat plate */
b = 0.0;
}
else {
d = R2sqr - x*x; /* z against tube */
z = d < 0.0 ? 0.0 : sqrt(d); /* z without tilt */
b = m * m2 * z; /* Compute intercept of tilted line */
}
z += y * m + b; /* Compute z increment from tilted line */
x += F; /* Move x back where it should be */
if (z > zmax)
zmax = z;
if (z < zmin)
zmin = z;
points[i] = z;
}
for ( i = 0; i <= SEGS; i++ ) {
if ( Output == out_PS ) {
Line(x, y, points[i]+L+Z-zmin, i * INC * R1);
}
}
return zmax-zmin;
}
/*----------------------------------------------------------------------------*/
void WritePoints(double R1, double R2, double R3, double F, double A, double A2, double L, double P, char *Label, double *paperSize)
{
double x, y;
double Z;
Header(R1, R2, R3, F, A, A2, Label, P, paperSize);
Z=DrawMiter(R1, R3, F, A2, 0, 0, 0);
Line(x, y, 0, SEGS * INC * R1);
Line(x, y, 0, 0);
DrawMiter(R1, R2, F, PI-A, L, Z, P);
Line(x, y, 0, SEGS * INC * R1);
Line(x, y, 0, 0);
Trailer(x, y, 0, (SEGS) * INC * R1);
}
/*----------------------------------------------------------------------------*/
void Usage(void)
{
fprintf(stderr, "miter [-dnumber] [-Dnumber] [-p] [-anumber] [-onumber] [-lstring] [-v]\n");
fprintf(stderr, " Example:\n");
fprintf(stderr, " miter -d1.0 -D1.25 -a27 -l"Top tube to head tube"\n");
fprintf(stderr, "\n");
fprintf(stderr, " -d - diameter of mitered tube; default 1.0\n");
fprintf(stderr, " -D - diameter of right tube butting against; default 1.0\n");
fprintf(stderr, " -E - diameter of left tube butting against; default 1.0\n");
fprintf(stderr, " -L - length between deepest point (facing towards middle of tube) of each miter; default 4.0\n");
fprintf(stderr, " -p - butt against flat plate\n");
fprintf(stderr, " -o - offset of d centerline from D centerline; default 0.0\n");
fprintf(stderr, " -a - included angle between centerlines on right side; default 90\n");
fprintf(stderr, " -b - included angle between centerlines on left side; default 90\n");
fprintf(stderr, " -P - phase angle between centerlines of each miter; default 0\n");
fprintf(stderr, " -l - label to print on output\n");
fprintf(stderr, " -v - print output for ADAMS/View\n");
fprintf(stderr, " -g - suppress guidelines on PostScript\n");
fprintf(stderr, " -Z - paper size:\n");
fprintf(stderr, " 0: ANSI A (8.5x11)\n");
fprintf(stderr, " 1: ANSI B (11x17)\n");
fprintf(stderr, " 2: ANSI C (17x22)\n");
fprintf(stderr, " 3: ANSI D (22x34)\n");
fprintf(stderr, " 4: ANSI E (34x44)\n");
fprintf(stderr, " 5: A0 (33.1x46.8)\n");
fprintf(stderr, " 6: A1 (23.4x33.1)\n");
fprintf(stderr, " 7: A2 (16.5x23.4)\n");
fprintf(stderr, " 8: A3 (11.7x16.5)\n");
fprintf(stderr, " 9: A4 (8.3x11.7)\n");
fprintf(stderr, " 10: A5 (5.8x8.3)\n");
fprintf(stderr, " 11: B0 (39.4x55.7)\n");
fprintf(stderr, " 12: B1 (27.8x39.4)\n");
fprintf(stderr, " 13: B2 (19.7x27.8)\n");
fprintf(stderr, " 14: B3 (13.9x19.7)\n");
fprintf(stderr, " 15: B4 (9.8x13.9)\n");
fprintf(stderr, " 16: B5 (6.9x9.8)\n");
exit(1);
}
/*----------------------------------------------------------------------------*/
int main(int ArgC, char *ArgV[])
{
int iArg;
double R1 = 0.5; /* Radius of tube for which we are cutting the miter */
double R2 = 0.5; /* Radius of tube against which we are butting on right*/
double R3 = 0.5; /* Radius of tube against which we are butting on left*/
double L = 4.0; /* Length of mitered tube between deepest point of each miter */
double F = 0.0; /* Offset of R1 centerline from R2 centerline */
double A = 0.0; /* Angle between R1 centerline and R2 centerline */
double P = 0.0; /* Angle between centerline of each miter */
double A2 = 0.0; /* Angle between R1 centerline and R2 centerline on other end*/
char *Label = ""; /* Any comment you wish to provide */
int Z = 0;
double paperSize[2]; /*Paper size in postscript units (inches*72) */
for ( iArg = 1; iArg < ArgC; iArg++ ) {
if ( ArgV[iArg][0] != '-' ) Usage();
switch ( ArgV[iArg][1] ) {
case 'l':
Label = &ArgV[iArg][2];
break;
case 'd':
sscanf(&ArgV[iArg][2], "%lf", &R1);
R1 /= 2.0;
break;
case 'D':
sscanf(&ArgV[iArg][2], "%lf", &R2);
R2 /= 2.0;
break;
case 'E':
sscanf(&ArgV[iArg][2], "%lf", &R3);
R3 /= 2.0;
break;
case 'L':
sscanf(&ArgV[iArg][2], "%lf", &L);
break;
case 'p':
R2 = 0.0;
break;
case 'a':
sscanf(&ArgV[iArg][2], "%lf", &A);
A = RADIANS(90.0 - A);
break;
case 'b':
sscanf(&ArgV[iArg][2], "%lf", &A2);
A2 = RADIANS(90.0 - A2);
break;
case 'P':
sscanf(&ArgV[iArg][2], "%lf", &P);
P = RADIANS(P);
break;
case 'o':
sscanf(&ArgV[iArg][2], "%lf", &F);
break;
case 'v':
Output = out_VIEW;
break;
case 'g':
PS_GuideLines = FALSE;
break;
case 'Z':
sscanf(&ArgV[iArg][2], "%d", &Z);
break;
default:
Usage();
break;
}
}
switch (Z) {
case 0:
paperSize[0] = 8.5; paperSize[1] = 11; break;
case 1:
paperSize[0] = 11; paperSize[1] = 17; break;
case 2:
paperSize[0] = 17; paperSize[1] = 22; break;
case 3:
paperSize[0] = 22; paperSize[1] = 34; break;
case 4:
paperSize[0] = 34; paperSize[1] = 44; break;
case 5:
paperSize[0] = 33.1; paperSize[1] = 46.8; break;
case 6:
paperSize[0] = 23.4; paperSize[1] = 33.1; break;
case 7:
paperSize[0] = 16.5; paperSize[1] = 23.4; break;
case 8:
paperSize[0] = 11.7; paperSize[1] = 16.5; break;
case 9:
paperSize[0] = 8.3; paperSize[1] = 11.7; break;
case 10:
paperSize[0] = 5.8; paperSize[1] = 8.3; break;
case 11:
paperSize[0] = 39.4; paperSize[1] = 55.7; break;
case 12:
paperSize[0] = 27.8; paperSize[1] = 39.4; break;
case 13:
paperSize[0] = 19.7; paperSize[1] = 27.8; break;
case 14:
paperSize[0] = 13.9; paperSize[1] = 19.7; break;
case 15:
paperSize[0] = 9.8; paperSize[1] = 13.9; break;
case 16:
paperSize[0] = 6.9; paperSize[1] = 9.8; break;
default:
paperSize[0] = 8.5; paperSize[1] = 11; break;
}
WritePoints(R1, R2, R3, F, A, A2, L, P, Label, paperSize);
#ifdef TESTING
WritePoints(0.75, 1.625, 0.0, RADIANS(atan(1.7/16.0)));
WritePoints(0.75 / 2.0, 1.625 / 2.0, 0.0, atan(1.7/16.0), "Chain stay to BB");
WritePoints(0.5 / 2.0, 1.125 / 2.0, 0.25, RADIANS(45.0), "Right seat stay to seat tube");
WritePoints(0.5 / 2.0, 1.125 / 2.0, -0.25, RADIANS(45.0), "Left seat stay to seat tube");
WritePoints(1.00/2, 1.25/2, 0.0, RADIANS(90.0 - 72.0), "Top tube to head tube");
WritePoints(1.00/2, 1.125/2, 0.0, RADIANS(90.0 - 75.0), "Top tube to seat tube");
#endif
exit(0);
}