require 'printf'

NB. nearest_index - Return the nearest index of y in list x
NB. Usage: list nearest_index item
NB. If <item> is midway between to values in <list>, the lower
NB. index is returned.
NB. Example: 1 2 3 4 5 nearest_index 1.9  --> 1
nearest_index=: (i. <./) @: | @: -
NB. nearest_index=: 4 : 0
NB. (i. <./) |x-y
NB. )

NB. rnd - Consistent rounding
NB. Usage: dp rnd value
NB.  Round to <dp> decimal places
NB.  <value> a vector of values to round
NB. Example: (i.7) rnd 1p1
NB. Example: 1 rnd 3.35 3.45 3.55 3.65 3.75
NB. 0j1 ": value is inconsistent, as is J-printf, Dylog APL and gcc-printf
NB. APL+Win and Excel-round() get it right
rnd=: 4 : 0
s=: y*10^x			NB. Scale the values to be rounded
r=: 0.5 <: 1|s		NB. boolean to round up or not
(r + <. s)*10^-x
)

NB. un_thd - Unified Inch Screw Threads per ASME B1.1-2003
NB. UN Class 3 Threads
NB.
NB. Usage: un_thd D n
NB.  where <D> = Basic diameter
NB.        <n> = Threads per inch
NB.
NB. --- Tolerances ---
NB. EXTERNAL THREADS
NB. Major Dia Tol: eDt  = 0.060*P^(2/3)
NB. Pitch Dia Tol: ePDt = 0.750*(0.0015*D^(1/3)+0.0015*LE^(1/2)+0.015*P^(2/3))
NB. Minor Dia Tol: UN:  eDmt  = ePDt + 0.21650635P (layout and check)
NB. 			   UNR: eDmtr = ePDt + 0.10825318P (layout and check)
NB.
NB. INTERNAL THREADS
NB. Major Dia Tol: iDt  = 0.14433757P + iPDt
NB. Pitch Dia Tol: iPDt = 0.975*ePDt
NB. Minor Dia Tol: iDmt = [0.05*P^(2/3)+0.03*P/D]-0.002
NB.                  iDmt = min(0.394*P, iDmt)
NB.                  for n = [13..80]: iDmt = max(0.23*P-1.5P^2, iDmt)
NB.                  for n =  [0..12]: iDmt = max(0.120*P, iDmt)
NB.
NB. --- Limits of Size ---
NB. EXTERNAL THREADS
NB. Max Major Dia: eDmx = D
NB. Min Major Dia: eDmn = D - eDt
NB.
NB. Max Pitch Dia: ePDmx = PD
NB. Min Pitch Dia: ePDmn = PD - ePDt
NB.
NB. Max Minor Dia: UN:  eDmmx = Dm
NB.                UNR: eDmmx = Dm - H/8
NB. Min Minor Dia: eDmmn = ePDmn - 0.64951905*P
NB.
NB. INTERNAL THREADS
NB. Max Major Dia: iDmx = Compute from Fig 3
NB. Min Major Dia: iDmn = D
NB.
NB. Max Pitch Dia: iPDmx = PD + iPDt
NB. Min Pitch Dia: iPDmn = PD 
NB.
NB. Max Minor Dia: iDmmx = iDmmn + iDmt (round to 4 decimal places)
NB. Min Minor Dia: iDmmn = iPDmn - 0.43301122*P
NB.   (rnd to 3 decimal places for D >= 0.138 and add a zero)
NB.
NB. --- Length of Engagement ---
NB. UNC, UNF:   LE = D
NB. 4, 6, 8-UN: LE = D
NB. UNEF, 12, 16, 20, 28, 32-UN: LE = 9P
NB. UNS: LE = 9P

NB. Vector of basic diameters
vD=: 0.0600 0.0730 0.0860 0.0990 0.1120 0.1250 0.1380 0.1640 0.1900 0.2160 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 1.0625 1.1250 1.1875 1.2500 1.3125 1.3750 1.4375 1.5000 1.5625 1.6250 1.6875 1.7500 1.8125 1.8750 1.9375 2.0000 2.1250 2.2500 2.3750 2.5000 2.6250 2.7500 2.8750 3.0000 3.1250 3.2500 3.3750 3.5000 3.6250 3.7500 3.8750 4.0000 4.1250 4.2500 4.3750 4.5000 4.6250 4.7500 4.8750 5.0000 5.1250 5.2500 5.3750 5.5000 5.6250 5.7500 5.8750 6.0000
UNC=: _1 64 56 48 40 40 32 32 24 24 20 18 16 14 13 12 11 _1 10 _1 9 _1 8 _1 7 _1 7 _1 6 _1 6 _1 _1 _1 5 _1 _1 _1 4.5 _1 4.5 _1 4 _1 4 _1 4 _1 4 _1 4 _1 4 _1 4 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 
UNF=: 80 72 64 56 48 44 40 36 32 28 28 24 24 20 20 18 18 _1 16 _1 14 _1 12 _1 12 _1 12 _1 12 _1 12 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 
UNEF=: _1 _1 _1 _1 _1 _1 _1 _1 _1 32 32 32 32 28 28 24 24 24 20 20 20 20 20 18 18 18 18 18 18 18 18 18 18 18 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 
UN4=: _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 4 _1 4 _1 4 _1 4 _1 4 _1 4 _1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
UN6=: _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 6 _1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
UN8=: _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
UN12=: _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 12 12 12 12 12 12 _1 12 _1 12 _1 12 _1 12 _1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12
UN16=: _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 16 16 16 16 16 _1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 
UN20=: _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 20 20 _1 _1 20 20 20 _1 _1 _1 _1 _1 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 
UN28=: _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 28 28 _1 _1 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 
UN32=: _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 32 32 32 32 32 32 32 32 32 32 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 
size=: '0 1 2 3 4 5 6 8 10 12 1/4 5/16 3/8 7/16 1/2 9/16 5/8 11/16 3/4 13/16 7/8 15/16 1 1-1/16 1-1/8 1-3/16 1-1/4 1-5/16 1-3/8 1-7/16 1-1/2 1-9/16 1-5/8 1-11/16 1-3/4 1-13/16 1-7/8 1-15/16 2 2-1/8 2-1/4 2-3/8 2-1/2 2-5/8 2-3/4 2-7/8 3 3-1/8 3-1/4 3-3/8 3-1/2 3-5/8 3-3/4 3-7/8 4 4-1/8 4-1/4 4-3/8 4-1/2 4-5/8 4-3/4 4-7/8 5 5-1/8 5-1/4 5-3/8 5-1/2 5-5/8 5-3/4 5-7/8 6'
mUN =: |: 11 71 $ UNC,UNF,UNEF,UN4,UN6,UN8,UN12,UN16,UN20,UN28,UN32


un_thd =: 3 : 0
D =: 0 { y
n =: 1 { y

iD =: vD nearest_index D
D =: iD { vD
in =: (iD { mUN) nearest_index n
n =: in { iD { mUN

P =: %n
PD =: D - +: 0.32475953*P

NB. --- Length of Engagement ---
NB. UNC, UNF:   LE = D
NB. 4, 6, 8-UN: LE = D
NB. UNEF, 12, 16, 20, 28, 32-UN: LE = 9P
NB. UNS: LE = 9P
P9=. 9*P
vLE =: D,D,P9,D,D,D,5$P9
LE =: in { vLE

NB. --- Tolerances ---
NB. EXTERNAL THREADS
eDt  =: 0.060*P^2r3				NB. Major Dia Tol
ePDt =: 0.750*(0.0015*D^(%3))+(0.0015*%:LE)+0.015*P^2r3		NB. Pitch Dia Tol
eDmt  =: ePDt + 0.21650635*P	NB. Minor Dia Tol: UN:   (layout & check)
eDmtr =: ePDt + 0.10825318*P	NB. UNR:  (layout & check)

NB. INTERNAL THREADS
iPDt =: 0.975*ePDt							NB. Pitch Dia Tol
iDt =: iPDt + 0.14433757*P					NB. Major Dia Tol
iDmt =: _0.002 + (0.05*P^2r3)+0.03*P%D		NB. Minor Dia Tol
iDmt =: iDmt <. 0.394*P						NB. Minimum of

if. n <: 12 do.
  iDmt =: iDmt >. 0.120*P					NB. for n = [0..12] maximum of
else.
 iDmt =: iDmt >. (0.23*P)-1.5* *:P			NB. for n = [13..80]
end.

NB. --- Limits of Size ---
NB. INTERNAL THREADS
iPDmx =: PD + iPDt							NB. Max Pitch Dia
iPDmn =: PD									NB. Min Pitch Dia

iDmn =: D									NB. Min Major Dia
iDmx =: iPDmx + (P * %:3)*0.500 - 0.041667	NB. Max Major Dia

iDmmn =: iPDmn - 0.43301122*P	NB. Min Minor Dia
iDmmx =: iDmmn + iDmt 			NB. Max Minor Dia (round to 4 decimal places)
NB.   (rnd to 3 decimal places for D >= 0.138 and add a zero)

NB. EXTERNAL THREADS
eDmx =: D									NB. Max Major Dia
eDmn =: D - eDt								NB. Min Major Dia

ePDmx =: PD									NB. Max Pitch Dia
ePDmn =: PD - ePDt							NB. Min Pitch Dia

eDmmx =: iDmmn								NB. Max Minor Dia: UN
NB. eDmmxr =: Dm - H/8						NB. UNR 
eDmmn =: ePDmn - 0.64951905*P				NB. Min Minor Dia


 f=: ' MAX/MIN: %.4f / %.4f       NOM-TOL: %.4f +/- %.4f'
('INT MAJOR:',f) printf ([ , l2t) iDmx,  iDmn
('INT PITCH:',f) printf ([ , l2t) iPDmx, iPDmn
('INT MINOR:',f) printf ([ , l2t) iDmmx, iDmmn
'\n' printf ''
('EXT MAJOR:',f) printf ([ , l2t) eDmx,  eDmn
('EXT PITCH:',f) printf ([ , l2t) ePDmx, ePDmn
('EXT MINOR:',f) printf ([ , l2t) eDmmx, eDmmn

)
