home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 March / Chip_1998-03_cd.bin / tema / MINICAD / MC7DEMO / MINICAD.1 / SPRINGS.MPC < prev    next >
Text File  |  1997-04-30  |  53KB  |  2,635 lines

  1. Procedure Springs;
  2. {
  3. (c)1997, Diehl Graphsoft, Inc.
  4. Developed by Tom Urie
  5.  
  6. This procedure draws every spring known to man (almost).
  7. }
  8. LABEL 99;
  9.  
  10. VAR
  11.     Type : INTEGER;
  12.     Abort : BOOLEAN;
  13.  
  14.  
  15. Procedure CompressionSprings;
  16. {
  17. (c)1997, Diehl Graphsoft, Inc.
  18. Developed by Tom Urie
  19.  
  20. This procedure draws a compression spring.
  21. }
  22.  
  23. LABEL 10,20,30,99;
  24.  
  25. CONST
  26.     Fillpat1=1;
  27.     Fillpat2=27;
  28.  
  29. VAR
  30.     D,P,wd,FL,OD,SH,WL : REAL;
  31.     x0,y0,R_MW,R_SS : REAL;
  32.  
  33.     NCoils,NCoilsB,NCoilsF,TNCoils : INTEGER;
  34.     Type,Method : INTEGER;
  35.  
  36.     Abort,Inch,Section : BOOLEAN;
  37.  
  38.     sf,UPI : REAL;
  39.     Fmt : INTEGER;
  40.     UM,UM2 : STRING;
  41.     UName,DA : LONGINT;
  42.  
  43. Procedure SpringDialog;
  44. {
  45. This procedure defines the dialog box.
  46. }
  47. VAR
  48.     Width,x1,y1,x2,y2,px1,px2,px3,px4,py1,py2,py3,py4 : INTEGER;
  49.  
  50. Procedure AlignScr(Width:INTEGER; VAR x1,x2:INTEGER);
  51. VAR
  52.     scrx1,scry1,scrx2,scry2:INTEGER;
  53. BEGIN
  54.     GetScreen(scrx1,scry1,scrx2,scry2);
  55.     x1:=((scrx1+scrx2) div 2)-(Width div 2);
  56.     x2:=x1+Width; 
  57. END;
  58.  
  59. Procedure LocateButtons(DialogType,scnh,scnw : INTEGER);
  60. {
  61. This procedure locates the 'OK' and 'Cancel' buttons.
  62. }
  63. VAR
  64.     v1,v2,v3,v4 : INTEGER;
  65.     Mac : BOOLEAN;
  66.  
  67. Procedure Swap(VAR  m1,m2,m3,m4 : INTEGER);
  68. VAR
  69.     Temp : INTEGER;
  70. BEGIN
  71.     Temp:=m1;
  72.     m1:=m3;
  73.     m3:=Temp;
  74.     Temp:=m2;
  75.     m2:=m4;
  76.     m4:=Temp;
  77. END;        {of Swap}
  78.  
  79. BEGIN
  80.     Mac:=FALSE;
  81.     GetVersion(v1,v2,v3,v4);
  82.     IF v4 = 1 THEN Mac:=TRUE;
  83.  
  84.     IF DialogType = 1 THEN
  85.     BEGIN
  86.         px1:=(scnw DIV 2) - 80;
  87.         px2:=(scnw DIV 2) - 10;
  88.         px3:=(scnw DIV 2) + 10;
  89.         px4:=(scnw DIV 2) + 80;
  90.         IF Mac THEN SWAP(px1,px2,px3,px4);
  91.  
  92.         py1:=scnh-40;
  93.         py2:=scnh-20;
  94.         py3:=py1;
  95.         py4:=py2;
  96.     END ELSE IF DialogType = 2 THEN
  97.     BEGIN
  98.         px1:=scnw - 180;
  99.         px2:=scnw - 110;
  100.         px3:=scnw - 90;
  101.         px4:=scnw - 20;
  102.         IF Mac THEN SWAP(px1,px2,px3,px4);
  103.  
  104.         py1:=scnh-40;
  105.         py2:=scnh-20;
  106.         py3:=py1;
  107.         py4:=py2;
  108.     END ELSE
  109.     BEGIN
  110.         px1:=scnw - 90;
  111.         px2:=scnw - 20;
  112.         px3:=px1;
  113.         px4:=px2;
  114.  
  115.         py1:=scnh -70;
  116.         py2:=scnh - 50;
  117.         py3:=scnh - 40;
  118.         py4:=scnh - 20;
  119.         IF Mac THEN SWAP(py1,py2,py3,py4);
  120.     END;
  121. END;        {of Locate Buttons}
  122.  
  123. Procedure MakeDialog1;
  124. CONST
  125.     y1=100;
  126.     scnw = 420;
  127.     scnh = 230;
  128.     DialogType = 2;
  129.  
  130. VAR
  131.     h : INTEGER;
  132.  
  133. BEGIN
  134.     AlignScr(scnw,x1,x2);
  135.     y2:=y1+scnh;
  136.     LocateButtons(DialogType,scnh,scnw);
  137.  
  138.     BeginDialog(1,1,x1,y1,x2,y2);
  139.         AddButton('OK',1,1,px1,py1,px2,py2);
  140.         AddButton('Cancel',2,1,px3,py3,px4,py4);
  141.  
  142.         h:=0;
  143.         AddField('Method:',19,1,20,9+h,75,25+h);
  144.         AddButton('1',20,3,80,10+h,110,25+h);
  145.         AddButton('2',21,3,120,10+h,155,25+h);
  146.  
  147.         AddField('Units:',22,1,220,9+h,260,25+h);
  148.         AddButton('Inch',23,3,265,10+h,315,25+h);
  149.         AddButton('mm',24,3,320,10+h,365,25+h);
  150.  
  151.         AddField('',4,1,20,44+h,130,60+h);
  152.         AddField('',5,2,145,45+h,210,60+h);
  153.         AddField('',6,1,20,69+h,130,85+h);
  154.         AddField('',7,2,145,70+h,210,85+h);
  155.         AddField('',8,1,20,94+h,130,110+h);
  156.         AddField('',9,2,145,95+h,210,110+h);
  157.         AddField('',10,1,20,119+h,130,135+h);
  158.         AddField('',11,2,145,120+h,210,135+h);
  159.         AddField('',12,1,20,144+h,130,160+h);
  160.         AddField('',13,2,145,145+h,210,160+h);
  161.  
  162.         AddField('',30,1,220,44+h,255,60+h);
  163.         AddField('',31,1,220,69+h,255,85+h);
  164.         AddField('',32,1,220,94+h,255,110+h);
  165.         AddField('',33,1,220,119+h,255,135+h);
  166.         AddField('',34,1,220,144+h,255,160+h);
  167.  
  168.         AddField('Type of Ends:',3,1,265,39+h,375,55+h);
  169.         AddButton('Open',14,3,265,125+h,315,140+h);
  170.         AddButton('Closed',15,3,265,105+h,405,120+h);
  171.         AddButton('Open and Ground',16,3,265,85+h,405,100+h);
  172.         AddButton('Closed and Ground',17,3,265,65+h,410,80+h);
  173.  
  174.         AddButton('Section View',18,2,20,185+h,120,200+h);
  175.  
  176.     EndDialog;
  177. END;
  178.  
  179. BEGIN
  180.     MakeDialog1;
  181. END;
  182.  
  183. Procedure GetInfo;
  184. {
  185. This procedure displays the dialog box and retrieves the information.
  186. }
  187. LABEL 5,10,20,99;
  188. VAR
  189.     Value : REAL;
  190.     Item,Field,k,NTimes,NPlaces : INTEGER;
  191.     RFlag : ARRAY[1..3] OF INTEGER;
  192.     Done : BOOLEAN;
  193.  
  194. Procedure SetRButton(i,Item : INTEGER);
  195. BEGIN
  196.     IF RFlag[i] <> Item THEN BEGIN
  197.         SetItem(RFlag[i],FALSE);
  198.         SetItem(Item,TRUE);
  199.         RFlag[i]:=Item;
  200.     END;
  201. END;
  202.  
  203. PROCEDURE SetTextFields(Method:INTEGER);
  204. CONST
  205.     SLength=25;
  206.     STitle='                         ';
  207. VAR
  208.     Field,k : INTEGER;
  209.     Description : ARRAY[1..2,1..5] OF STRING;
  210. BEGIN
  211.     Description[1,1]:='Outside Diameter:';
  212.     Description[1,2]:='Wire Diameter:';
  213.     Description[1,3]:='Free Length:';
  214.     Description[1,4]:='Solid Height:';
  215.     Description[1,5]:='Working Length:';
  216.     Description[2,1]:='Mean Diameter:';
  217.     Description[2,2]:='Wire Diameter:';
  218.     Description[2,3]:='Pitch:';
  219.     Description[2,4]:='No. of Active Coils:';
  220.     Description[2,5]:='(Not Used)';
  221.     Field:=2;
  222.     FOR k:=1 TO 5 DO BEGIN;
  223.         Field:=Field+2;
  224.         SetField(Field,Description[Method,k]);
  225.     END;
  226. END;
  227.  
  228. PROCEDURE SetUnitsField(Inch:BOOLEAN);
  229. VAR
  230.     Field,k : INTEGER;
  231.     UnitsM1,UnitsM2 : STRING;
  232. BEGIN
  233.     Field:=29;
  234.     IF Inch THEN
  235.         UnitsM1:='in'
  236.     ELSE
  237.         UnitsM1:='mm';
  238.     FOR k:=1 TO 5 DO
  239.     BEGIN;
  240.         Field:=Field+1;
  241.         SetField(Field,UnitsM1);
  242.     END;
  243. END;
  244.  
  245. BEGIN
  246.     NTimes:=NTimes+1;
  247.     IF NTimes > 1 THEN GOTO 5;
  248.  
  249.     OD:=0.975;
  250.     wd:=0.125;
  251.     D:=OD-wd;
  252.     FL:=2.0;
  253.     SH:=1.117;
  254.     WL:=1.75;
  255.     TNCoils:=SH/wd;
  256.     P:=(FL-2*wd)/TNCoils;
  257.     NCoils:=TNCoils-2;
  258.     Method:=1;
  259.     Type:=4;
  260.     Inch:=TRUE;
  261.     Section:=FALSE;
  262.  
  263.     5:Done:=FALSE;
  264.     Abort:=FALSE;
  265.     RFlag[1]:=Type+13;
  266.     RFlag[2]:=Method+19;
  267.     IF Inch Then RFlag[3]:=23
  268.     ELSE RFlag[3]:=24;
  269.     GetDialog(1);
  270.     SetTitle('Compression Springs');
  271.     SetTextFields(Method);
  272.     SetUnitsField(Inch);
  273.     SetItem(RFlag[1],TRUE);
  274.     SetItem(RFlag[2],TRUE);
  275.     SetItem(RFlag[3],TRUE);
  276.     SetItem(18,Section);
  277.     IF Method = 1 THEN BEGIN
  278.         SetField(5,Num2StrF(OD));
  279.         SetField(7,Num2StrF(wd));
  280.         SetField(9,Num2StrF(FL));
  281.         SetField(11,Num2StrF(SH));
  282.         SetField(13,Num2StrF(WL));
  283.     END
  284.     ELSE BEGIN
  285.         SetField(5,Num2StrF(D));
  286.         SetField(7,Num2StrF(wd));
  287.         SetField(9,Num2StrF(P));
  288.         SetField(11,Num2Str(0,NCoils));
  289.         SetField(13,'n/a');
  290.     END;
  291.     SelField(5);
  292.     10:REPEAT
  293.         DialogEvent(Item);
  294.         IF Item=1 then
  295.             Done:=True;
  296.         IF Item=2 then BEGIN
  297.             Done:=TRUE;
  298.             Abort:=TRUE;
  299.         END;
  300.         IF (ITEM=13) AND (Method=2) THEN
  301.         BEGIN
  302.             SysBeep;
  303.             SelField(5);
  304.         END;
  305.         IF (Item>13) AND (Item<18) THEN
  306.         BEGIN
  307.             SetRButton(1,Item);
  308.             Type:=Item-13;
  309.         END; 
  310.         IF Item=18 THEN
  311.         BEGIN
  312.             SetItem(Item,NOT Section);
  313.             Section:=NOT Section;
  314.         END;
  315.         IF (Item=20) AND (Method=2) THEN
  316.         BEGIN
  317.             SetRButton(2,Item);
  318.             Method:=1;
  319.             SetTextFields(Method);
  320.             SetField(5,Num2StrF(OD));
  321.             SetField(7,Num2StrF(wd));
  322.             SetField(9,Num2StrF(FL));
  323.             SetField(11,Num2StrF(SH));
  324.             SetField(13,Num2StrF(WL));
  325.         END;
  326.         IF (Item=21) AND (Method=1) THEN
  327.         BEGIN
  328.             SetRButton(2,Item);
  329.             Method:=2;
  330.             SetTextFields(Method);
  331.             SetField(5,Num2StrF(D));
  332.             SetField(7,Num2StrF(wd));
  333.             SetField(9,Num2StrF(P));
  334.             SetField(11,Num2Str(0,NCoils));
  335.             SetField(13,'<n/a>');
  336.         END;
  337.         IF (Item=23) AND (NOT Inch) THEN
  338.         BEGIN
  339.             SetRButton(3,Item);
  340.             Inch:=TRUE;
  341.             SetUnitsField(Inch);
  342.         END;
  343.         IF (Item=24) AND (Inch) THEN
  344.         BEGIN
  345.             SetRButton(3,Item);
  346.             Inch:=FALSE;
  347.             SetUnitsField(Inch);
  348.         END;
  349.     UNTIL Done;
  350.     IF Abort THEN GOTO 99;
  351.     Field:=3;
  352.     FOR k:=1 TO 5 DO
  353.     BEGIN
  354.         Field:=Field+2;
  355.         IF (Field=13) AND (Method=2) THEN GOTO 20;
  356.         IF Str2Num(GetField(Field))>0 THEN GOTO 20;    
  357.         SysBeep;
  358.         SelField(Field);
  359.         Done:=False;
  360.         GOTO 10;
  361.     20:END;
  362.     IF Method = 1 THEN BEGIN
  363.         OD:=Str2Num(GetField(5));
  364.         wd:=Str2Num(GetField(7));
  365.         FL:=Str2Num(GetField(9));
  366.         SH:=Str2Num(GetField(11));
  367.         WL:=Str2Num(GetField(13));
  368.     END
  369.     ELSE BEGIN
  370.         D:=Str2Num(GetField(5));
  371.         wd:=Str2Num(GetField(7));
  372.         P:=Str2Num(GetField(9));
  373.         NCoils:=Str2Num(GetField(11));
  374.     END;
  375.     99:ClrDialog;
  376. END;
  377.  
  378. PROCEDURE DrawCoil(x,y,D,P,wd:REAL; Direction:INTEGER);
  379. VAR
  380.     r,L,Theta,x0,y0 : REAL;
  381. BEGIN
  382.     r:=wd/2;
  383.     Theta:=Direction*ArcTan(P/(2*D));
  384.     L:=Sqrt(D^2 + (P/2)^2);
  385.     x0:=x-r*(Sin(Theta)+Cos(Theta));
  386.     y0:=y+r*(Cos(Theta)-Sin(Theta));
  387.     Theta:=Rad2Deg(Theta);
  388.     Absolute;
  389.     MoveTo(x0,y0);
  390.     Relative;
  391.     AngleVar;
  392.     ClosePoly;
  393.     BeginPoly;
  394.         ArcTo((L+2*r),#Theta,r);
  395.         ArcTo(2*r,#(Theta-90),r);
  396.         ArcTo(-(L+2*r),#Theta,r);
  397.         ArcTo(2*r,#(Theta+90),r);
  398.     EndPoly;
  399.     NoAngleVar;
  400.     IF Section THEN BEGIN
  401.         Absolute;
  402.         MoveTo(x,y);
  403.         Relative;
  404.         FillPat(FillPat2);
  405.         Arc(-r,r,r,-r,0,360);
  406.         MoveTo(D,-P/2);
  407.         Arc(-r,r,r,-r,0,360);
  408.         FillPat(FillPat1);
  409.     END;
  410. END;
  411.  
  412. PROCEDURE DrawCoil1(x,y,D,P,wd:REAL; Direction:INTEGER);
  413. VAR
  414.     i,r,L,Theta,x0,y0 : REAL;
  415. BEGIN
  416.     r:=wd/2;
  417.     i:=Direction;
  418.     Theta:=-ArcTan(P/(2*D));
  419.     L:=Sqrt(D^2 + (P/2)^2);
  420.     x0:=x-r*(Sin(Theta)+i*Cos(Theta));
  421.     y0:=y+r*(Cos(Theta)-i*Sin(Theta));
  422.     Theta:=Rad2Deg(Theta);
  423.     Absolute;
  424.     MoveTo(x0,y0);
  425.     Relative;
  426.     AngleVar;
  427.     ClosePoly;
  428.     BeginPoly;
  429.         LineTo(i*(L/2+r),#Theta);
  430.         LineTo(2*r,#(Theta-90));
  431.         ArcTo(-i*(L/2+r),#Theta,r);
  432.         ArcTo(2*r,#(Theta+90),r);
  433.     EndPoly;
  434.     NoAngleVar;
  435.     IF Section THEN BEGIN
  436.         Absolute;
  437.         MoveTo(x,y);
  438.         Relative;
  439.         FillPat(FillPat2);
  440.         Arc(-r,r,r,-r,0,360);
  441.         FillPat(FillPat1);
  442.     END;
  443. END;
  444.  
  445. PROCEDURE DrawCoil3a(x,y,MD,P,wd:REAL;Direction:INTEGER);
  446. VAR
  447.     x0,y0,Alpha,Beta,Theta,Phi : REAL;
  448.     c,r,x1,y1,x2,y2,x3,y3,y4,dx,dy : REAL;
  449.     i : INTEGER;
  450. BEGIN
  451.     r:=wd/2;
  452.     i:=Direction;
  453.     Theta:=ArcTan(P/(2*MD));
  454.     y1:=wd/4;
  455.     x1:=Sqrt(r^2 - y1^2);
  456.     Beta:=(PI/6 + Theta/2);
  457.     Alpha:=(PI/3 - Theta)/2;
  458.     c:=wd/(2*Sin(Alpha));
  459.     x2:=c*Cos(Beta);
  460.     y2:=c*Sin(Beta);
  461.     x3:=wd*Sin(Theta)/2;
  462.     y3:=wd*Cos(Theta)/2;
  463.     y4:=y1+y3-(MD/2-x3)*Tan(Theta);
  464.     x0:=x + i*x1;
  465.     y0:=y + i*y1;
  466.     Absolute;
  467.     MoveTo(x0,y0);
  468.     Relative;
  469.     ClosePoly;
  470.     BeginPoly;
  471.         LineTo(0,0);
  472.         LineTo(-i*(MD/2 + x1),0);    
  473.         LineTo(-0,-i*y4);
  474.         ArcTo(i*(MD/2 + x2),i*(y4-y1-y2),wd/2);
  475.     EndPoly;
  476.     IF Section THEN BEGIN
  477.         Phi:=Rad2Deg(ArcTan(x1/y1));
  478.         IF Phi < 0 THEN Phi:=-1*Phi;
  479.         Absolute;
  480.         MoveTo(x,y);
  481.         Relative;
  482.         FillPat(FillPat2);
  483.         Arc(-r,r,r,-r,i*90+Phi,360-2*Phi);
  484.         FillPat(FillPat1);
  485.     END;
  486. END;
  487.  
  488. PROCEDURE DrawCoil3b(x,y,D,P,wd:REAL; Direction:INTEGER);
  489. VAR
  490.     i,r,x0,y0,a,a1,b,c,e : REAL;
  491.     Alpha,Beta,Theta : REAL;
  492. BEGIN
  493.     r:=wd/2;
  494.     i:=Direction;
  495.     Theta:=ArcTan(P/(2*D));
  496.     Alpha:=(PI/3 + Theta)/2;
  497.     b:=wd/(2*Tan(Alpha));
  498.     a:=wd/(2*Tan(Theta)) - wd/(4*Sin(Theta));
  499.     Beta:=ArcTan(2*a/wd);
  500.     c:=wd*Tan(Beta+Theta)/4;
  501.     e:=c + wd*Sin(PI/3)/2;
  502.     x0:=x+i*(r*(Sin(Theta)-Cos(Theta)));
  503.     y0:=y-i*(r*(Cos(Theta)+Sin(Theta)));
  504.     Absolute;
  505.     MoveTo(x0,y0);
  506.     Relative;
  507.     AngleVar;
  508.     BeginPoly;
  509.         ArcTo(0,#0,r);
  510.         ArcTo(i*(wd/2 + D/Cos(Theta) + b), #Rad2Deg(Theta),r);
  511.         LineTo(i*b,#120);
  512.         LineTo(i*e,#180);
  513.         ArcTo(i*(D/Cos(Theta) + wd/2 - a),#(180+Rad2Deg(Theta)),r);
  514.     EndPoly;
  515.     NoAngleVar;
  516. END;
  517.  
  518. PROCEDURE DrawCoil4a(x,y,D,P,wd:REAL; Direction:INTEGER);
  519. VAR
  520.     a,b,c,e,Beta,Beta2,dx3,dy3,dx4 : REAL;
  521.     i,r,x0,y0,y1,dy1,dy2,Theta2 : REAL;
  522. BEGIN
  523.     r:=wd/2;
  524.     i:=Direction;
  525.     dy1:=(wd-P/2)/2;
  526.     IF dy1 < 0 THEN dy1:=0;
  527.     dy2:=wd/2 - dy1;
  528.     a:=D^2 + dy1^2;
  529.     b:=-2*r*D;
  530.     c:=r^2 - dy1^2;
  531.     e:=(-b-Sqrt(b^2 - 4*a*c))/(2*a);
  532.     Theta2:=ArcSin(e);
  533.     Beta:=(PI/2+Theta2)/2;
  534.     y1:=r*Tan(Beta);
  535.     x0:=x{+i*D}-i*r;
  536.     y0:=y-i*(P/2 + dy1 + r);
  537.     Absolute;
  538.     MoveTo(x0,y0);
  539.     Relative;
  540.     ClosePoly;
  541.     BeginPoly;
  542.         LineTo(0,0);
  543.         {LineTo(-i*(D+r),0);
  544.         ArcTo(0,i*y1,r);
  545.         LineTo(i*(D+r),-i*(y1-dy1));}
  546.         ArcTo(0,i*y1,r);
  547.         IF dy1 <> 0 THEN BEGIN
  548.             Beta2:=ArcCos(Cos(Theta2)-dy1/r) - Theta2;
  549.             dx3:=r*Tan(Beta2/2)*Cos(Theta2);
  550.             dy3:=r*Tan(Beta2/2)*Sin(Theta2);
  551.             dy1:=dy1-dy3;
  552.             dx4:=r*Tan(Beta2/2)*Sin(Beta2+Theta2);
  553.             ArcTo(i*(D+r*(1+Sin(Theta2))+dx3),-i*(y1-dy1),r);
  554.             LineTo(i*dx4,-i*dy1);
  555.         END
  556.         ELSE
  557.             LineTo(i*(D+r),-i*y1);
  558.     EndPoly;
  559.     IF Section THEN BEGIN
  560.         Absolute;
  561.         MoveTo(x,y0);
  562.         Relative;
  563.         FillPat(FillPat2);
  564.         Arc(-r,r,r,-r,180,-i*180);
  565.         FillPat(FillPat1);
  566.     END;
  567. END;
  568.  
  569. PROCEDURE DrawCoil4b(x,y,D,P,wd:REAL; Direction:INTEGER);
  570. VAR
  571.     i,r,x0,y0,y1,dy1,y2,dy2,y3,y4 : REAL;
  572.     a,b,c,Alpha,SinAlpha,Beta,Theta2 : REAL;
  573. BEGIN
  574.     r:=wd/2;
  575.     i:=Direction;
  576.     dy1:=(wd-P/2)/2;
  577.     IF dy1 < 0 THEN dy1:=0;
  578.     dy2:=wd/2 - dy1;
  579.     y1:=P/2 + dy1 + r;
  580.     Theta2:=ArcTan((dy1+r)/D);
  581.     Beta:=(PI/2-Theta2)/2;
  582.     y2:=r*Tan(Beta);
  583.     y3:=r/Tan(Beta);
  584.     y4:=y1-P/2+y3-y2;
  585.     a:=(D+r)^2 + (dy1+r)^2;
  586.     b:=2*(D+r)*r;
  587.     c:=r^2 - (dy1+r)^2;
  588.     SinAlpha:=(-b + Sqrt(b^2 - 4*a*c))/(2*a);
  589.     Alpha:=ArcSin(SinAlpha);
  590.     x0:=x-i*r;
  591.     y0:=y-i*y1;
  592.     Absolute;
  593.     MoveTo(x0,y0);
  594.     Relative;
  595.     ClosePoly;
  596.     AngleVar;
  597.     BeginPoly;
  598.         LineTo(0,0);
  599.         ArcTo(i*y2,#90,r);
  600.         ArcTo(-i*(r + D/Cos(Theta2) + r*Tan(Beta)),#(Rad2Deg(Theta2))-180,r);
  601.     LineTo(-i*r*(1+tan((Theta2-Alpha)/2)),#(90+Rad2Deg(Theta2)));
  602.     ArcTo(-i*r*(1+tan((Theta2-Alpha)/2)),#(90+Rad2Deg(Alpha)),r);
  603.     EndPoly;
  604. END;
  605.  
  606. PROCEDURE DrawActiveCoils(x0,y0,D,P,wd:REAL; NCoilsF,NCoilsB:INTEGER);
  607. VAR
  608.     x,y : REAL;
  609.     j : INTEGER;
  610. BEGIN
  611.     Absolute;
  612.     x:=x0;
  613.     y:=y0-(NCoilsF-1)*P;
  614.     MoveTo(x,y);
  615.     Relative;
  616.     FOR j:=1 TO NCoilsB DO BEGIN
  617.         IF NOT SECTION THEN
  618.             DrawCoil(x,y,D,P,wd,1);
  619.         y:=y+P;
  620.     END;
  621.     FOR j:=1 TO NCoilsF DO BEGIN
  622.         DrawCoil(x,y,D,P,wd,-1);
  623.         y:=y-P;
  624.     END;
  625. END;
  626.  
  627. PROCEDURE DrawEnds(x0,y0,D,P,wd:REAL; NCoils,TNCoils,Type:INTEGER);
  628. VAR
  629.     x,y,AlphaR,AlphaL,Beta,Theta,P1,P2 : REAL;
  630.     cR,cL,x1,y1,x2R,y2R,x2L,y2L : REAL;
  631.     i,j,n : INTEGER;
  632. BEGIN
  633.     IF Type=1 THEN BEGIN
  634.         x:=x0;
  635.         y:=y0-(NCoils-1)*P;
  636.         IF NOT Section THEN
  637.             DrawCoil(x,y,D,P,wd,1);
  638.         DrawCoil1(x,y,D,P,wd,1);
  639.         x:=x0;
  640.         y:=y0;
  641.         IF NOT Section THEN
  642.             DrawCoil(x,y,D,P,wd,1);
  643.         x:=x0+D;
  644.         y:=y0+P/2;
  645.         DrawCoil1(x,y,D,P,wd,-1);
  646.     END
  647.     ELSE IF Type=2 THEN BEGIN
  648.         Theta:=ArcTan(P/(2*D));
  649.         P1:=P/4 + wd/(2*Cos(Theta)) + wd/2;
  650.         P2:=2*(P1-P/2);
  651.         x:=x0;
  652.         y:=y0 - (NCoils*P + P1);
  653.         IF NOT Section THEN
  654.             DrawCoil(x,y,D,P2,wd,1);
  655.         DrawCoil1(x,y,D,0,wd,1);
  656.         x:=x0;
  657.         y:=y0;
  658.         IF NOT Section THEN
  659.             DrawCoil(x,y,D,P2,wd,1);
  660.         x:=x0+D;
  661.         y:=y0 - P/2 + P1;
  662.         DrawCoil1(x,y,D,0,wd,-1);
  663.     END
  664.     ELSE IF Type=3 THEN BEGIN
  665.         x:=x0;
  666.         y:=y0;
  667.         IF NOT Section THEN
  668.             DrawCoil3b(x,y,D,P,wd,1);
  669.         x:=x0+D;
  670.         y:=y0+P/2;
  671.         DrawCoil3a(x,y,D,P,wd,1);
  672.         y:=y0-(NCoils-1/2)*P;
  673.         IF NOT Section THEN
  674.             DrawCoil3b(x,y,D,P,wd,-1);
  675.         x:=x0;
  676.         y:=y0-NCoils*P;
  677.         DrawCoil3a(x,y,D,P,wd,-1);
  678.     END
  679.     ELSE BEGIN
  680.         x:=x0;
  681.         y:=y0-NCoils*P;
  682.         IF NOT Section THEN
  683.             DrawCoil4b(x,y,D,P,wd,1);
  684.         DrawCoil4a(x,y,D,P,wd,1);
  685.         x:=x0+D;
  686.         y:=y0-P/2;
  687.         IF NOT Section THEN
  688.             DrawCoil4b(x,y,D,P,wd,-1);
  689.         DrawCoil4a(x,y,D,P,wd,-1);
  690.     END;
  691. END;
  692.  
  693. {
  694. Main Program.
  695. }
  696. BEGIN
  697.     DSelectAll;
  698.  
  699. {
  700. Display the dialog box and get the information.
  701. }
  702.     SpringDialog;
  703.     SetCursor(ArrowC);
  704.     GetInfo;
  705.     IF Abort THEN GOTO 99;
  706.  
  707. {
  708. Get drawing units and adjust parameters.
  709. }
  710.     GetUnits(UName,DA,Fmt,UPI,UM,UM2);
  711.     IF Inch THEN
  712.         sf:=UPI
  713.     ELSE
  714.         sf:=UPI/25.4;
  715.     OD:=OD*sf;
  716.     wd:=wd*sf;
  717.     FL:=FL*sf;
  718.     SH:=SH*sf;
  719.     WL:=WL*sf;
  720.     D:=D*sf;
  721.     P:=P*sf;
  722.     PushAttrs;
  723.     FillPat(1);
  724. {
  725. Get the location of the spring.
  726. }
  727.     GetPt(x0,y0);
  728. {
  729. Calculate spring parameters.
  730. }
  731.     IF Method = 1 THEN BEGIN
  732.         D:=OD-wd;
  733.         IF Type = 1 THEN BEGIN
  734.             TNCoils:=(SH-wd)/wd;
  735.             NCoils:=TNCoils;
  736.             P:=(WL-wd)/TNCoils;
  737.             NCoilsF:=NCoils-1;
  738.             NCoilsB:=NCoils-2;
  739.             x0:=x0-D/2;
  740.             y0:=y0+(NCoils-3/2)*P/2;
  741.         END
  742.         ELSE IF Type = 2 THEN BEGIN
  743.             TNCoils:=(SH-3*wd)/wd + 2;
  744.             NCoils:=TNCoils - 2;
  745.             P:=(WL-3*wd)/(TNCoils-2);
  746.             NCoilsF:=NCoils+1;
  747.             NCoilsB:=NCoils;
  748.             x0:=x0-D/2;
  749.             y0:=y0+(NCoils+1/2)*P/2;
  750.         END
  751.         ELSE IF Type = 3 THEN BEGIN
  752.             TNCoils:=SH/wd;
  753.             NCoils:=TNCoils - 1;
  754.             P:=(WL-wd/2)/(NCoils+1/2);
  755.             NCoilsF:=NCoils;
  756.             NCoilsB:=NCoils-1;
  757.             x0:=x0-D/2;
  758.             y0:=y0+(NCoils-1/2)*P/2;
  759.         END
  760.         ELSE BEGIN
  761.             TNCoils:=(SH-2*wd)/wd + 2;
  762.             NCoils:=TNCoils - 2;
  763.             P:=(WL-2*wd)/(TNCoils-2);
  764.             NCoilsF:=NCoils+1;
  765.             NCoilsB:=NCoils;
  766.             x0:=x0-D/2;
  767.             y0:=y0+(NCoils+1/2)*P/2;
  768.         END;
  769.     END
  770.     ELSE BEGIN
  771.         IF Type = 1 THEN BEGIN
  772.             TNCoils:=NCoils;
  773.             WL:=TNCoils*P+wd;
  774.             NCoilsF:=NCoils-1;
  775.             NCoilsB:=NCoils-2;
  776.             x0:=x0-D/2;
  777.             y0:=y0+(NCoils-3/2)*P/2;
  778.         END
  779.         ELSE IF Type=2 THEN BEGIN
  780.             TNCoils:=NCoils + 2;
  781.             NCoilsF:=NCoils+1;
  782.             NCoilsB:=NCoils;
  783.             WL:=NCoils*P+3*wd;
  784.             x0:=x0-D/2;
  785.             y0:=y0+(NCoils+1/2)*P/2;
  786.         END
  787.         ELSE IF Type = 3 THEN BEGIN
  788.             TNCoils:=NCoils + 1;
  789.             NCoilsF:=NCoils;
  790.             NCoilsB:=NCoils-1;
  791.             WL:=TNCoils*P;
  792.             x0:=x0-D/2;
  793.             y0:=y0+(NCoils-1/2)*P/2;
  794.         END
  795.         ELSE BEGIN
  796.             TNCoils:=NCoils + 2;
  797.             NCoilsF:=NCoils+1;
  798.             NCoilsB:=NCoils;
  799.             WL:=NCoils*P+2*wd;
  800.             x0:=x0-D/2;
  801.             y0:=y0+(NCoils+1/2)*P/2;
  802.         END;
  803.     END;
  804.  
  805. {
  806. Draw spring.
  807. }
  808.  
  809.     DrawEnds(x0,y0+WL/2,D,P,wd,NCoils,TNCoils,Type);
  810.     DrawActiveCoils(x0,y0+WL/2,D,P,wd,NCoilsF,NCoilsB);
  811.     Group;
  812.     PopAttrs;
  813. 99:END;    {of CompressionSprings}
  814.  
  815. Procedure ConicalCompSprings;
  816. {
  817. (c)1997, Diehl Graphsoft, Inc.
  818. Developed by Tom Urie
  819.  
  820. This procedure draws a conical compression spring.
  821. }
  822. LABEL 10,90,99;
  823.  
  824. CONST
  825.     Fillpat1=1;
  826.     Fillpat2=24;
  827.     MaxCoils=25;
  828.     MaxCoils2=50;
  829.  
  830. VAR
  831.     DS,DL,L,ODL,ODS,P,wd : REAL;
  832.     x0,y0,x,y,dy,F,p1,p2,q1,q2,q3,q4 : REAL;
  833.     a,b,c,s1,s2,s3,s4 : REAL;
  834.     Theta1,Theta2,Theta3,Theta4 : REAL;
  835.     x1,x2,y1,y2 : ARRAY[1..MaxCoils] OF REAL;
  836.     k,m,n,NCoils : Integer;
  837.  
  838.     Abort,Inch,Section : BOOLEAN;
  839.  
  840.     sf,UPI : REAL;
  841.     Fmt : INTEGER;
  842.     UM,UM2 : STRING;
  843.     UName,DA : LONGINT;
  844.  
  845. Procedure SpringDialog;
  846. {
  847. This procedure defines the dialog box.
  848. }
  849. VAR
  850.     Width,x1,y1,x2,y2,px1,px2,px3,px4,py1,py2,py3,py4 : INTEGER;
  851.  
  852. Procedure AlignScr(Width:INTEGER; VAR x1,x2:INTEGER);
  853. VAR
  854.     scrx1,scry1,scrx2,scry2:INTEGER;
  855. BEGIN
  856.     GetScreen(scrx1,scry1,scrx2,scry2);
  857.     x1:=((scrx1+scrx2) div 2)-(Width div 2);
  858.     x2:=x1+Width; 
  859. END;
  860.  
  861. Procedure LocateButtons(DialogType,scnh,scnw : INTEGER);
  862. {
  863. This procedure locates the 'OK' and 'Cancel' buttons.
  864. }
  865. VAR
  866.     v1,v2,v3,v4 : INTEGER;
  867.     Mac : BOOLEAN;
  868.  
  869. Procedure Swap(VAR  m1,m2,m3,m4 : INTEGER);
  870. VAR
  871.     Temp : INTEGER;
  872. BEGIN
  873.     Temp:=m1;
  874.     m1:=m3;
  875.     m3:=Temp;
  876.     Temp:=m2;
  877.     m2:=m4;
  878.     m4:=Temp;
  879. END;        {of Swap}
  880.  
  881. BEGIN
  882.     Mac:=FALSE;
  883.     GetVersion(v1,v2,v3,v4);
  884.     IF v4 = 1 THEN Mac:=TRUE;
  885.  
  886.     IF DialogType = 1 THEN
  887.     BEGIN
  888.         px1:=(scnw DIV 2) - 80;
  889.         px2:=(scnw DIV 2) - 10;
  890.         px3:=(scnw DIV 2) + 10;
  891.         px4:=(scnw DIV 2) + 80;
  892.         IF Mac THEN SWAP(px1,px2,px3,px4);
  893.  
  894.         py1:=scnh-40;
  895.         py2:=scnh-20;
  896.         py3:=py1;
  897.         py4:=py2;
  898.     END ELSE IF DialogType = 2 THEN
  899.     BEGIN
  900.         px1:=scnw - 180;
  901.         px2:=scnw - 110;
  902.         px3:=scnw - 90;
  903.         px4:=scnw - 20;
  904.         IF Mac THEN SWAP(px1,px2,px3,px4);
  905.  
  906.         py1:=scnh-40;
  907.         py2:=scnh-20;
  908.         py3:=py1;
  909.         py4:=py2;
  910.     END ELSE
  911.     BEGIN
  912.         px1:=scnw - 90;
  913.         px2:=scnw - 20;
  914.         px3:=px1;
  915.         px4:=px2;
  916.  
  917.         py1:=scnh -70;
  918.         py2:=scnh - 50;
  919.         py3:=scnh - 40;
  920.         py4:=scnh - 20;
  921.         IF Mac THEN SWAP(py1,py2,py3,py4);
  922.     END;
  923. END;        {of Locate Buttons}
  924.  
  925. Procedure MakeDialog2;
  926. CONST
  927.     y1=100;
  928.     scnw = 280;
  929.     scnh = 250;
  930.     DialogType = 2;
  931.  
  932. VAR
  933.         h : INTEGER;
  934.  
  935. BEGIN
  936.     AlignScr(scnw,x1,x2);
  937.     y2:=y1+scnh;
  938.     LocateButtons(DialogType,scnh,scnw);
  939.  
  940.     BeginDialog(2,1,x1,y1,x2,y2);
  941.         AddButton('OK',1,1,px1,py1,px2,py2);
  942.         AddButton('Cancel',2,1,px3,py3,px4,py4);
  943.  
  944.         h:=0;
  945.         AddField('Units:',22,1,20,9+h,60,25+h);
  946.         AddButton('Inch',23,3,65,10+h,115,25+h);
  947.         AddButton('mm',24,3,120,10+h,165,25+h);
  948.  
  949.         h:=-10;
  950.         AddField('OD - Large End:',4,1,20,44+h,130,60+h);
  951.         AddField('',5,2,155,45+h,230,60+h);
  952.         AddField('OD - Small End:',6,1,20,69+h,130,85+h);
  953.         AddField('',7,2,155,70+h,230,85+h);
  954.         AddField('Wire Diameter:',8,1,20,94+h,130,110+h);
  955.         AddField('',9,2,155,95+h,230,110+h);
  956.         AddField('Length:',10,1,20,119+h,130,135+h);
  957.         AddField('',11,2,155,120+h,230,135+h);
  958.         AddField('No. of Active Coils:',12,1,20,144+h,150,160+h);
  959.         AddField('',13,2,155,145+h,230,160+h);
  960.  
  961.         AddField('',30,1,240,44+h,275,60+h);
  962.         AddField('',31,1,240,69+h,275,85+h);
  963.         AddField('',32,1,240,94+h,275,110+h);
  964.         AddField('',33,1,240,119+h,275,135+h);
  965.  
  966.         h:=-20;
  967.         AddButton('Section View',18,2,20,185+h,500,200+h);
  968.     EndDialog;
  969. END;
  970.  
  971. BEGIN
  972.     MakeDialog2;
  973. END;
  974.  
  975. Procedure GetInfo;
  976. {
  977. This procedure displays the dialog box and retrieves the information.
  978. }
  979. LABEL 5,10,20,99;
  980. VAR
  981.     Value : REAL;
  982.     Item,Field,k,NTimes,NPlaces : INTEGER;
  983.     RFlag : ARRAY[1..20] OF INTEGER;
  984.     Done : BOOLEAN;
  985.  
  986. Procedure SetRButton(i,Item : INTEGER);
  987. BEGIN
  988.     IF RFlag[i] <> Item THEN BEGIN
  989.         SetItem(RFlag[i],FALSE);
  990.         SetItem(Item,TRUE);
  991.         RFlag[i]:=Item;
  992.     END;
  993. END;
  994.  
  995. PROCEDURE SetUnitsField(Inch:BOOLEAN);
  996. VAR
  997.     Field,k : INTEGER;
  998.     UnitsM : STRING;
  999. BEGIN
  1000.     IF Inch THEN UnitsM:='in'
  1001.     ELSE UnitsM:='mm';
  1002.     Field:=29;
  1003.     FOR k:=1 TO 4 DO
  1004.     BEGIN;
  1005.         Field:=Field+1;
  1006.         SetField(Field,UnitsM);
  1007.     END;
  1008. END;
  1009.  
  1010. BEGIN
  1011.     Inch:=TRUE;
  1012.     Section:=FALSE;
  1013.  
  1014.     ODL:=2.000;
  1015.     ODS:=0.750;
  1016.     wd:=0.125;
  1017.     L:=1.8125;
  1018.     NCoils:=6;
  1019.  
  1020.     5:Done:=FALSE;
  1021.     Abort:=FALSE;
  1022.     IF Inch Then RFlag[1]:=23
  1023.     ELSE RFlag[1]:=24;
  1024.     GetDialog(2);
  1025.     SetTitle('Conical Compression Springs');
  1026.     SetUnitsField(Inch);
  1027.     SetItem(RFlag[1],TRUE);
  1028.     SetItem(18,Section);
  1029.     SetField(5,Num2StrF(ODL));
  1030.     SetField(7,Num2StrF(ODS));
  1031.     SetField(9,Num2StrF(wd));
  1032.     SetField(11,Num2StrF(L));
  1033.     SetField(13,Num2Str(0,NCoils));
  1034.     SelField(5);
  1035.     10:REPEAT
  1036.         DialogEvent(Item);
  1037.         IF Item=1 then
  1038.             Done:=True;
  1039.         IF Item=2 then BEGIN
  1040.             Done:=TRUE;
  1041.             Abort:=TRUE;
  1042.         END;
  1043.         IF Item=18 THEN
  1044.         BEGIN
  1045.             SetItem(Item,NOT Section);
  1046.             Section:=NOT Section;
  1047.         END;
  1048.         IF (Item=23) AND (NOT Inch) THEN
  1049.         BEGIN
  1050.             SetRButton(1,Item);
  1051.             Inch:=TRUE;
  1052.             SetUnitsField(Inch);
  1053.         END;
  1054.         IF (Item=24) AND (Inch) THEN
  1055.         BEGIN
  1056.             SetRButton(1,Item);
  1057.             Inch:=FALSE;
  1058.             SetUnitsField(Inch);
  1059.         END;
  1060.     UNTIL Done;
  1061.     IF Abort THEN GOTO 99;
  1062.     Field:=3;
  1063.     FOR k:=1 TO 5 DO
  1064.     BEGIN
  1065.         Field:=Field+2;
  1066.         IF Str2Num(GetField(Field))>0 THEN GOTO 20;    
  1067.         SysBeep;
  1068.         SelField(Field);
  1069.         Done:=False;
  1070.         GOTO 10;
  1071.     20:END;
  1072.         ODL:=Str2Num(GetField(5));
  1073.         ODS:=Str2Num(GetField(7));
  1074.         wd:=Str2Num(GetField(9));
  1075.         L:=Str2Num(GetField(11));
  1076.         NCoils:=Str2Num(GetField(13));
  1077.     99:ClrDialog;
  1078. END;
  1079.  
  1080. Procedure DrawCoil(x1,y1,x2,y2,wd : REAL);
  1081. VAR
  1082.     r,L,Theta,x0,y0 : REAL;
  1083. BEGIN
  1084.     r:=wd/2;
  1085.     L:=Distance(x1,y1,x2,y2);
  1086.     Theta:=ArcCos((x2-x1)/L);
  1087.     IF y2 < y1 THEN
  1088.     Theta:=2*PI-Theta;
  1089.     x0:=x1-r*Cos(Theta)-r*Sin(Theta);
  1090.     y0:=y1-r*Sin(Theta)+r*Cos(Theta);
  1091.     Theta:=Rad2Deg(Theta);
  1092.     Absolute;
  1093.     MoveTo(x0,y0);
  1094.     Relative;
  1095.     AngleVar;
  1096.     ClosePoly;
  1097.     BeginPoly;
  1098.         ArcTo((L+2*r),#Theta,r);
  1099.         ArcTo((2*r),#(Theta-90),r);
  1100.         ArcTo(-(L+2*r),#Theta,r);
  1101.         ArcTo(-(2*r),#(Theta-90),r);
  1102.     EndPoly;
  1103.     NoAngleVar;
  1104.     IF Section THEN BEGIN
  1105.         Absolute;
  1106.         MoveTo(x1,y1);
  1107.         Relative;
  1108.         FillPat(FillPat2);
  1109.         Arc(-r,r,r,-r,0,360);
  1110.         Absolute;
  1111.         MoveTo(x2,y2);
  1112.         Relative;
  1113.         Arc(-r,r,r,-r,0,360);
  1114.         FillPat(FillPat1);
  1115.     END;
  1116. END;
  1117.  
  1118. {
  1119. Main Program.
  1120. }
  1121. BEGIN
  1122.     DSelectAll;
  1123.  
  1124. {
  1125. Display the dialog box and get the information.
  1126. }
  1127.     SpringDialog;
  1128.     SetCursor(ArrowC);
  1129.     GetInfo;
  1130.     IF Abort THEN GOTO 99;
  1131. {
  1132. Get drawing units and adjust parameters.
  1133. }
  1134.     GetUnits(UName,DA,Fmt,UPI,UM,UM2);
  1135.     IF Inch THEN
  1136.         sf:=UPI
  1137.     ELSE
  1138.         sf:=UPI/25.4;
  1139.     ODL:=ODL*sf;
  1140.     ODS:=ODS*sf;
  1141.     wd:=wd*sf;
  1142.     L:=L*sf;
  1143.     PushAttrs;
  1144.     FillPat(1);
  1145. {
  1146. Get the location of the spring.
  1147. }
  1148.     GetPt(x0,y0);
  1149. {
  1150. Calculate spring parameters.
  1151. }
  1152.     n:=NCoils;
  1153.     DS:=ODS-wd;
  1154.     DL:=ODL-wd;
  1155.     Theta1:=ArcSin(wd/DS);
  1156.     s1:=DS*Cos(Theta1)+wd;
  1157.     p1:=s1*Sin(Theta1);
  1158.     q1:=s1*Cos(Theta1);
  1159.  
  1160.     a:=1+(wd/DL)^2;
  1161.     b:=2*(wd/DL)^2;
  1162.     c:=(wd/DL)^2 - 1;
  1163.     Theta2:=ArcCos((-b+Sqrt(b^2-4*a*c))/(2*a));
  1164.     s2:=DL*Cos(Theta2) - wd/2;
  1165.     p2:=s2*Sin(Theta2);
  1166.     q2:=s2*Cos(Theta2);
  1167.  
  1168.     s3:=L-wd-p1;
  1169.     q3:=DL/2-q1+DS/2;
  1170.     Theta3:=ArcTan(q3/s3);
  1171.  
  1172.     s4:=L-wd-p2;
  1173.     q4:=q2-DL/2-DS/2;
  1174.     Theta4:=ArcTan(q4/s4);
  1175.  
  1176.     m:=n-1;
  1177.     F:=m*(m+1)/2;
  1178.  
  1179.     y1[1]:=0;                x1[1]:=DS/2;
  1180.     y1[2]:=p1;                x1[2]:=q1-DS/2;
  1181.     FOR k:=3 TO n DO
  1182.     BEGIN
  1183.         dy:=(k-2)*s3/F;
  1184.         IF dy<wd THEN dy:=wd;
  1185.         y1[k]:=y1[k-1]+dy;
  1186.         x1[k]:=x1[k-1]+dy*Tan(Theta3);
  1187.     END;
  1188.     y1[n+1]:=L-wd;        x1[n+1]:=DL/2;
  1189.  
  1190.     y2[1]:=0;            x2[1]:=DS/2;
  1191.     dy:=p1 + (y1[3]-y1[2])/2;
  1192.     y2[2]:=dy;            x2[2]:=DS/2+dy*Tan(Theta4);
  1193.     FOR k:=3 TO n-1 DO
  1194.     BEGIN
  1195.         dy:=(y1[k+1]-y1[k-1])/2;
  1196.         y2[k]:=y2[k-1]+dy;
  1197.         x2[k]:=x2[k-1]+dy*Tan(Theta4);
  1198.     END;
  1199.     y2[n]:=s4;                x2[n]:=q2-DL/2;
  1200.     y2[n+1]:=L-wd;        x2[n+1]:=DL/2;
  1201.  
  1202. {
  1203. Draw spring.
  1204. }
  1205.     x:=x0;            y:=y0+L-wd/2;
  1206.     FOR k:=1 TO n+1 DO
  1207.     BEGIN
  1208.         DrawCoil(x-x1[k],y-y1[k],x+x2[k],y-y2[k],wd);
  1209.     END;
  1210.     IF Section THEN GOTO 90;
  1211.         FOR k:=1 TO n DO
  1212.     BEGIN
  1213.         DrawCoil(x-x1[k+1],y-y1[k+1],x+x2[k],y-y2[k],wd);
  1214.     END;
  1215.     Absolute;
  1216.     MoveTo(x-x1[1], y);
  1217.     Relative;
  1218.     Arc(-wd/2,wd/2,wd/2,-wd/2,0,360);
  1219.     Absolute;
  1220.     MoveTo(x, y-L+wd/2);
  1221.     Relative;
  1222.     BeginPoly;
  1223.         LineTo(0,0);
  1224.         ArcTo(ODL/2,0,wd/2);
  1225.         ArcTo(0,wd,wd/2);
  1226.         LineTo(-ODL/2,0);
  1227.         LineTo(0,-wd);
  1228.     EndPoly;
  1229.     90:Group;
  1230.     PopAttrs;
  1231. 99:END;    {of ConicalCompSprings}
  1232.  
  1233.  
  1234. Procedure DieSprings;
  1235. {
  1236. (c)1997, Diehl Graphsoft, Inc.
  1237. Developed by Tom Urie
  1238.  
  1239. This procedure draws a heavy duty rectangular wire die spring.
  1240. }
  1241. LABEL 5,10,90,99;
  1242.  
  1243. CONST
  1244.     Fillpat1=1;
  1245.     Fillpat2=24;
  1246.  
  1247. VAR
  1248.     A,D,FL,ID,SD,OD,HD,P,wh,ww,SH,WL : REAL;
  1249.     x0,y0,q1,q2,q3,q4,Theta1,Theta2 : REAL;
  1250.     Clearance : REAL;
  1251.  
  1252.     k,nCoils : INTEGER;
  1253.  
  1254.     Abort,Inch,Section : BOOLEAN;
  1255.  
  1256.     sf,UPI : REAL;
  1257.     Fmt : INTEGER;
  1258.     UM,UM2 : STRING;
  1259.     UName,DA : LONGINT;
  1260.  
  1261. Procedure SpringDialog;
  1262. {
  1263. This procedure defines the dialog box.
  1264. }
  1265. VAR
  1266.     Width,x1,y1,x2,y2,px1,px2,px3,px4,py1,py2,py3,py4 : INTEGER;
  1267.  
  1268. Procedure AlignScr(Width:INTEGER; VAR x1,x2:INTEGER);
  1269. VAR
  1270.     scrx1,scry1,scrx2,scry2:INTEGER;
  1271. BEGIN
  1272.     GetScreen(scrx1,scry1,scrx2,scry2);
  1273.     x1:=((scrx1+scrx2) div 2)-(Width div 2);
  1274.     x2:=x1+Width; 
  1275. END;
  1276.  
  1277. Procedure LocateButtons(DialogType,scnh,scnw : INTEGER);
  1278. {
  1279. This procedure locates the 'OK' and 'Cancel' buttons.
  1280. }
  1281. VAR
  1282.     v1,v2,v3,v4 : INTEGER;
  1283.     Mac : BOOLEAN;
  1284.  
  1285. Procedure Swap(VAR  m1,m2,m3,m4 : INTEGER);
  1286. VAR
  1287.     Temp : INTEGER;
  1288. BEGIN
  1289.     Temp:=m1;
  1290.     m1:=m3;
  1291.     m3:=Temp;
  1292.     Temp:=m2;
  1293.     m2:=m4;
  1294.     m4:=Temp;
  1295. END;        {of Swap}
  1296.  
  1297. BEGIN
  1298.     Mac:=FALSE;
  1299.     GetVersion(v1,v2,v3,v4);
  1300.     IF v4 = 1 THEN Mac:=TRUE;
  1301.  
  1302.     IF DialogType = 1 THEN
  1303.     BEGIN
  1304.         px1:=(scnw DIV 2) - 80;
  1305.         px2:=(scnw DIV 2) - 10;
  1306.         px3:=(scnw DIV 2) + 10;
  1307.         px4:=(scnw DIV 2) + 80;
  1308.         IF Mac THEN SWAP(px1,px2,px3,px4);
  1309.  
  1310.         py1:=scnh-40;
  1311.         py2:=scnh-20;
  1312.         py3:=py1;
  1313.         py4:=py2;
  1314.     END ELSE IF DialogType = 2 THEN
  1315.     BEGIN
  1316.         px1:=scnw - 180;
  1317.         px2:=scnw - 110;
  1318.         px3:=scnw - 90;
  1319.         px4:=scnw - 20;
  1320.         IF Mac THEN SWAP(px1,px2,px3,px4);
  1321.  
  1322.         py1:=scnh-40;
  1323.         py2:=scnh-20;
  1324.         py3:=py1;
  1325.         py4:=py2;
  1326.     END ELSE
  1327.     BEGIN
  1328.         px1:=scnw - 90;
  1329.         px2:=scnw - 20;
  1330.         px3:=px1;
  1331.         px4:=px2;
  1332.  
  1333.         py1:=scnh -70;
  1334.         py2:=scnh - 50;
  1335.         py3:=scnh - 40;
  1336.         py4:=scnh - 20;
  1337.         IF Mac THEN SWAP(py1,py2,py3,py4);
  1338.     END;
  1339. END;        {of Locate Buttons}
  1340.  
  1341. Procedure MakeDialog3;
  1342. CONST
  1343.     y1=100;
  1344.     scnw = 320;
  1345.     scnh = 270;
  1346.     DialogType = 2;
  1347.  
  1348. VAR
  1349.     h : INTEGER;
  1350.  
  1351. BEGIN
  1352.     AlignScr(scnw,x1,x2);
  1353.     y2:=y1+scnh;
  1354.     LocateButtons(DialogType,scnh,scnw);
  1355.  
  1356.     BeginDialog(3,1,x1,y1,x2,y2);
  1357.         AddButton('OK',1,1,px1,py1,px2,py2);
  1358.         AddButton('Cancel',2,1,px3,py3,px4,py4);
  1359.  
  1360.         h:=0;
  1361.         AddField('Units:',22,1,20,9+h,60,25+h);
  1362.         AddButton('Inch',23,3,65,10+h,115,25+h);
  1363.         AddButton('mm',24,3,120,10+h,165,25+h);
  1364.  
  1365.         h:=-5;
  1366.         AddField('Fits in Hole Size:',4,1,20,44+h,130,60+h);
  1367.         AddField('',5,2,145,45+h,260,60+h);
  1368.  
  1369.         AddField('Fits Over Shaft:',6,1,20,69+h,130,85+h);
  1370.         AddField('',7,2,145,70+h,260,85+h);
  1371.  
  1372.         AddField('Wire Size (t x w):',8,1,20,94+h,140,110+h);
  1373.         AddField('',9,2,145,95+h,190,110+h);
  1374.         AddField('x',10,1,199,92+h,207,107+h);
  1375.         AddField('',11,2,215,95+h,260,110+h);
  1376.  
  1377.         AddField('Free Length:',12,1,20,119+h,130,135+h);
  1378.         AddField('',13,2,145,120+h,260,135+h);
  1379.  
  1380.         AddField('Solid Height:',14,1,20,144+h,130,160+h);
  1381.         AddField('',15,2,145,145+h,260,160+h);
  1382.  
  1383.         AddField('Working Length:',16,1,20,169+h,130,185+h);
  1384.         AddField('',17,2,145,170+h,260,185+h);
  1385.  
  1386.         AddField('',30,1,270,44+h,305,60+h);
  1387.         AddField('',31,1,270,69+h,305,85+h);
  1388.         AddField('',32,1,270,94+h,305,110+h);
  1389.         AddField('',33,1,270,119+h,305,135+h);
  1390.         AddField('',34,1,270,144+h,305,160+h);
  1391.         AddField('',35,1,270,169+h,305,185+h);
  1392.  
  1393.         h:=10;
  1394. AddButton('Section View',18,2,20,185+h,500,200+h);
  1395.  
  1396.     EndDialog;
  1397. END;
  1398.  
  1399. BEGIN
  1400.     MakeDialog3;
  1401. END;
  1402.  
  1403. Procedure GetInfo;
  1404. {
  1405. This procedure displays the dialog box and retrieves the information.
  1406. }
  1407. LABEL 5,10,20,99;
  1408. CONST
  1409.     NumParams=7;
  1410. VAR
  1411.     Value : REAL;
  1412.     Param : ARRAY[1..NumParams] OF REAL;
  1413.     Item,Field,j,k,NTimes,NPlaces : INTEGER;
  1414.     RFlag : ARRAY[1..20] OF INTEGER;
  1415.     Done,OK : BOOLEAN;
  1416.  
  1417. Procedure SetRButton(i,Item : INTEGER);
  1418. BEGIN
  1419.     IF RFlag[i] <> Item THEN BEGIN
  1420.         SetItem(RFlag[i],FALSE);
  1421.         SetItem(Item,TRUE);
  1422.         RFlag[i]:=Item;
  1423.     END;
  1424. END;
  1425.  
  1426. PROCEDURE SetUnitsField(Inch:BOOLEAN);
  1427. VAR
  1428.     Field,k : INTEGER;
  1429.     UnitsM1,UnitsM2 : STRING;
  1430. BEGIN
  1431.     IF Inch THEN
  1432.         UnitsM1:='in'
  1433.     ELSE
  1434.         UnitsM1:='mm';
  1435.     Field:=29;
  1436.     FOR k:=1 TO 6 DO
  1437.     BEGIN;
  1438.         Field:=Field+1;
  1439.         SetField(Field,UnitsM1);
  1440.     END;
  1441. END;
  1442.  
  1443. BEGIN
  1444.     NTimes:=NTimes+1;
  1445.     IF NTimes > 1 THEN GOTO 5;
  1446.  
  1447.     Inch:=TRUE;
  1448.     Section:=FALSE;
  1449.  
  1450.     Param[1]:=1.500;
  1451.     Param[2]:=0.750;
  1452.     Param[3]:=0.135;
  1453.     Param[4]:=0.345;
  1454.     Param[5]:=3.000;
  1455.     Param[6]:=1.150;
  1456.     Param[7]:=2.000;
  1457.  
  1458.     5:Done:=FALSE;
  1459.     Abort:=FALSE;
  1460.     IF Inch Then RFlag[1]:=23
  1461.     ELSE RFlag[1]:=24;
  1462.     GetDialog(3);
  1463.     SetTitle('Heavy Duty Rect. Wire Die Springs');
  1464.     SetUnitsField(Inch);
  1465.     SetItem(RFlag[1],TRUE);
  1466.     SetItem(18,Section);
  1467.  
  1468.     j:=3;
  1469.     FOR k:=1 TO NumParams DO
  1470.     BEGIN
  1471.         j:=j+2;
  1472.         SetField(j,Num2Str(3,Param[k]));
  1473.     END;
  1474.     SelField(5);
  1475.  
  1476.     10:REPEAT
  1477.         DialogEvent(Item);
  1478.         IF Item=1 then
  1479.             Done:=True;
  1480.  
  1481.         IF Item=2 then BEGIN
  1482.             Done:=TRUE;
  1483.             Abort:=TRUE;
  1484.         END;
  1485.  
  1486.         IF Item=18 THEN
  1487.         BEGIN
  1488.             SetItem(Item,NOT Section);
  1489.             Section:=NOT Section;
  1490.         END;
  1491.  
  1492.         IF (Item=23) AND (NOT Inch) THEN
  1493.         BEGIN
  1494.             SetRButton(1,Item);
  1495.             Inch:=TRUE;
  1496.             SetUnitsField(Inch);
  1497.         END;
  1498.  
  1499.         IF (Item=24) AND (Inch) THEN
  1500.         BEGIN
  1501.             SetRButton(1,Item);
  1502.             Inch:=FALSE;
  1503.             SetUnitsField(Inch);
  1504.         END;
  1505.  
  1506.     UNTIL Done;
  1507.     IF Abort THEN GOTO 99;
  1508.     Field:=3;
  1509.     FOR k:=1 TO 6 DO
  1510.     BEGIN
  1511.         Field:=Field+2;
  1512.         IF Str2Num(GetField(Field))>0 THEN GOTO 20;    
  1513.         SysBeep;
  1514.         SelField(Field);
  1515.         Done:=False;
  1516.         GOTO 10;
  1517.     20:END;
  1518.     j:=3;
  1519.     FOR k:=1 TO NumParams DO
  1520.     BEGIN
  1521.         j:=j+2;
  1522.         OK:=ValidNumStr(GetField(j),Param[k]);
  1523.         IF (NOT OK) OR (Param[k]<=0) THEN
  1524.         BEGIN
  1525.             SysBeep;
  1526.             SelField(j);
  1527.             Done:=FALSE;
  1528.             GOTO 10;
  1529.         END;
  1530.     END;
  1531.  
  1532.     HD:=Param[1];
  1533.     SD:=Param[2];
  1534.     wh:=Param[3];
  1535.     ww:=Param[4];
  1536.     FL:=Param[5];
  1537.     SH:=Param[6];
  1538.     WL:=Param[7];
  1539.  
  1540.     IF WL >= SH THEN GOTO 99;
  1541.     SysBeep;
  1542.     SelField(17);
  1543.     Done:=FALSE;
  1544.     GOTO 10;
  1545.     99:ClrDialog;
  1546. END;
  1547.  
  1548. {
  1549. Main Program.
  1550. }
  1551. BEGIN
  1552.     DSelectAll;
  1553.  
  1554. {
  1555. Display the dialog box and get the information.
  1556. }
  1557.     SpringDialog;
  1558.     SetCursor(ArrowC);
  1559.     GetInfo;
  1560.     IF Abort THEN GOTO 99;
  1561. {
  1562. Get drawing units and adjust parameters.
  1563. }
  1564.     GetUnits(UName,DA,Fmt,UPI,UM,UM2);
  1565.     IF Inch THEN
  1566.         sf:=UPI
  1567.     ELSE
  1568.         sf:=UPI/25.4;
  1569.     Clearance:=(HD-SD-2*ww)/4;
  1570.     OD:=(HD-2*Clearance)*sf;
  1571.     ID:=(OD-2*ww)*sf;
  1572.     wh:=wh*sf;
  1573.     ww:=ww*sf;
  1574.     FL:=FL*sf;
  1575.     SH:=SH*sf;
  1576.     WL:=WL*sf;
  1577.     PushAttrs;
  1578.     FillPat(1);
  1579. {
  1580. Get the location of the spring.
  1581. }
  1582.     GetPt(x0,y0);
  1583. {
  1584. Calculate spring parameters.
  1585. }
  1586.     NCoils:=SH/wh - 0.5;
  1587.     P:=(WL-wh)/(NCoils - 1/2);
  1588.     Theta1:=ArcTan(P/(2*OD));
  1589.     q1:=ww*Tan(Theta1);
  1590.     IF P/2 < wh THEN
  1591.         Theta2:=ArcTan((wh-P/2)/OD)
  1592.     ELSE Theta2:=0;
  1593.     q2:=ww*Tan(Theta2);
  1594.     q3:=(ww+ID)*Tan(Theta2);
  1595.     q4:=OD*Tan(Theta2);
  1596.  
  1597. {
  1598. Draw spring.
  1599.  
  1600. {
  1601. Draw rear active coils.
  1602. }
  1603.     IF (SH=WL) AND (NOT Section) THEN GOTO 5;
  1604.     Absolute;
  1605.     MoveTo(x0+OD/2,y0-P/2);
  1606.     Relative;
  1607.     FOR k:=1 TO NCoils-1 DO
  1608.     BEGIN
  1609.         Move(0,P);
  1610.         Poly(0,0, -OD,P/2, 0,wh, OD,-P/2, 0,-wh);
  1611.     END;
  1612.  
  1613. {
  1614. Draw front active coils (normal view);
  1615. }
  1616.     5:IF Section THEN GOTO 10;
  1617.     Absolute;
  1618.     MoveTo(x0-OD/2,y0-P);
  1619.     Relative;
  1620.     FOR k:=1 TO NCoils DO
  1621.     BEGIN
  1622.         Move(0,P);
  1623.         Poly(0,0, OD,P/2, 0,wh, -OD,-P/2, 0,-wh);
  1624.     END;
  1625.  
  1626. {
  1627. Draw end coils - normal view.
  1628. }
  1629.     Absolute;
  1630.     MoveTo(x0-OD/2,y0);
  1631.     Relative;
  1632.     Poly(0,0, OD,0, 0,P/2, -OD,-P/2);
  1633.     Absolute;
  1634.     MoveTo(x0+OD/2,y0+WL);
  1635.     Relative;
  1636.     Poly(0,0, -OD,0, 0,-P/2, OD,P/2);
  1637.     GOTO 90;
  1638.  
  1639. {
  1640. Draw end coils - section view.
  1641. }
  1642.     10:Absolute;
  1643.     MoveTo(x0-OD/2,y0);
  1644.     Relative;
  1645.     FillPat(1);
  1646.     Poly(0,0, 0,wh, OD,-q4, 0,-P/2, -OD,0);
  1647.     FillPat(FillPat2);
  1648.     Poly(0,0, 0,wh, ww,0, 0,-wh, -ww,0);
  1649.     Move(OD,0);
  1650.     Poly(0,0, 0,(wh-q4), -ww,0, 0,-(wh-q4), ww,0);
  1651.  
  1652.     Absolute;
  1653.     MoveTo(x0+OD/2,y0+WL);
  1654.     Relative;
  1655.     FillPat(1);
  1656.     Poly(0,0, 0,-wh, -OD,q4, 0,P/2, OD,0);
  1657.     FillPat(FillPat2);
  1658.     Poly(0,0, 0,-wh, -ww,0, 0,wh, ww,0);
  1659.     Move(-OD,0);
  1660.     Poly(0,0, 0,-(wh-q4), ww,0, 0,(wh-q4), -ww,0);
  1661.  
  1662. {
  1663. Draw sections - active coils.
  1664. }
  1665.     Absolute;
  1666.     MoveTo(x0-OD/2,y0);
  1667.     Relative;
  1668.     FillPat(FillPat2);
  1669.     FOR k:=1 TO NCoils-1 DO
  1670.     BEGIN
  1671.         Move(OD,P/2);
  1672.         Rect(0,0,-ww,wh);
  1673.         Move(-OD,P/2);
  1674.         Rect(0,0,ww,wh);
  1675.     END;
  1676.  
  1677.     90:Group;
  1678.     PopAttrs;
  1679. 99:END;    {of DieSprings}
  1680.  
  1681. Procedure ExtensionSprings;
  1682. {
  1683. (c)1997, Diehl Graphsoft, Inc.
  1684. Developed by Tom Urie
  1685.  
  1686. This procedure draws an extension spring.
  1687. }
  1688.  
  1689. LABEL 5,10,20,30,99;
  1690.  
  1691. CONST
  1692.     Hf2=1.00;
  1693.     G_MW = 12.0e6;
  1694.     G_SS = 10.0e6;
  1695.     LBperSqIn2NperSqMM = 6.8947e-3;
  1696.     ShowCoils = 3;
  1697.     PP1 = -10;
  1698.  
  1699. VAR
  1700.     D,HL,ID,LCF,LCW,FL,OD,P,WL,wd : REAL;
  1701.     x0,y0,x1,y1,x2,y2,R_MW,R_SS : REAL;
  1702.  
  1703.     k,n,NCoils,s,Type,View : Integer;
  1704.  
  1705.     Abort,Inch,ShowAllCoils : BOOLEAN;
  1706.  
  1707.     sf,UPI : REAL;
  1708.     Fmt : INTEGER;
  1709.     UM,UM2 : STRING;
  1710.     UName,DA : LONGINT;
  1711.  
  1712. Procedure SpringDialog;
  1713. {
  1714. This procedure defines the dialog box.
  1715. }
  1716. VAR
  1717.     Width,x1,y1,x2,y2,px1,px2,px3,px4,py1,py2,py3,py4 : INTEGER;
  1718.  
  1719. Procedure AlignScr(Width:INTEGER; VAR x1,x2:INTEGER);
  1720. VAR
  1721.     scrx1,scry1,scrx2,scry2:INTEGER;
  1722.  
  1723. BEGIN
  1724.     GetScreen(scrx1,scry1,scrx2,scry2);
  1725.     x1:=((scrx1+scrx2) div 2)-(Width div 2);
  1726.     x2:=x1+Width; 
  1727. END;
  1728.  
  1729. Procedure LocateButtons(DialogType,scnh,scnw : INTEGER);
  1730. {
  1731. This procedure locates the 'OK' and 'Cancel' buttons.
  1732. }
  1733. VAR
  1734.     v1,v2,v3,v4 : INTEGER;
  1735.     Mac : BOOLEAN;
  1736.  
  1737. Procedure Swap(VAR  m1,m2,m3,m4 : INTEGER);
  1738. VAR
  1739.     Temp : INTEGER;
  1740. BEGIN
  1741.     Temp:=m1;
  1742.     m1:=m3;
  1743.     m3:=Temp;
  1744.     Temp:=m2;
  1745.     m2:=m4;
  1746.     m4:=Temp;
  1747. END;        {of Swap}
  1748.  
  1749. BEGIN
  1750.     Mac:=FALSE;
  1751.     GetVersion(v1,v2,v3,v4);
  1752.     IF v4 = 1 THEN Mac:=TRUE;
  1753.  
  1754.     IF DialogType = 1 THEN
  1755.     BEGIN
  1756.         px1:=(scnw DIV 2) - 80;
  1757.         px2:=(scnw DIV 2) - 10;
  1758.         px3:=(scnw DIV 2) + 10;
  1759.         px4:=(scnw DIV 2) + 80;
  1760.         IF Mac THEN SWAP(px1,px2,px3,px4);
  1761.  
  1762.         py1:=scnh-40;
  1763.         py2:=scnh-20;
  1764.         py3:=py1;
  1765.         py4:=py2;
  1766.     END ELSE IF DialogType = 2 THEN
  1767.     BEGIN
  1768.         px1:=scnw - 180;
  1769.         px2:=scnw - 110;
  1770.         px3:=scnw - 90;
  1771.         px4:=scnw - 20;
  1772.         IF Mac THEN SWAP(px1,px2,px3,px4);
  1773.  
  1774.         py1:=scnh-40;
  1775.         py2:=scnh-20;
  1776.         py3:=py1;
  1777.         py4:=py2;
  1778.     END ELSE
  1779.     BEGIN
  1780.         px1:=scnw - 90;
  1781.         px2:=scnw - 20;
  1782.         px3:=px1;
  1783.         px4:=px2;
  1784.  
  1785.         py1:=scnh -70;
  1786.         py2:=scnh - 50;
  1787.         py3:=scnh - 40;
  1788.         py4:=scnh - 20;
  1789.         IF Mac THEN SWAP(py1,py2,py3,py4);
  1790.     END;
  1791. END;        {of Locate Buttons}
  1792.  
  1793. Procedure MakeDialog4;
  1794. CONST
  1795.     y1=100;
  1796.     scnw = 420;
  1797.     scnh = 270;
  1798.     DialogType = 2;
  1799.  
  1800. VAR
  1801.     h : INTEGER;
  1802.  
  1803. BEGIN
  1804.     AlignScr(scnw,x1,x2);
  1805.     y2:=y1+scnh;
  1806.     LocateButtons(DialogType,scnh,scnw);
  1807.  
  1808.     BeginDialog(4,1,x1,y1,x2,y2);
  1809.         AddButton('OK',1,1,px1,py1,px2,py2);
  1810.         AddButton('Cancel',2,1,px3,py3,px4,py4);
  1811.  
  1812.         h:=0;
  1813.         AddField('Units:',22,1,20,9+h,60,25+h);
  1814.         AddButton('Inch',23,3,65,10+h,115,25+h);
  1815.         AddButton('mm',24,3,120,10+h,170,25+h);
  1816.  
  1817.         h:=-10;
  1818.         AddField('Outside Diameter:
  1819. ',4,1,20,44+h,140,60+h);
  1820.         AddField('',5,2,145,45+h,210,60+h);
  1821.         AddField('Wire Diameter:
  1822. ',6,1,20,69+h,130,85+h);
  1823.         AddField('',7,2,145,70+h,210,85+h);
  1824.         AddField('Free Length:
  1825. ',8,1,20,94+h,130,110+h);
  1826.         AddField('',9,2,145,95+h,210,110+h);
  1827.         AddField('Working Length:',10,1,20,119+h,130,135+h);
  1828.         AddField('',11,2,145,120+h,210,135+h);
  1829.         AddField('Hook Length:',12,1,20,144+h,130,160+h);
  1830.         AddField('',13,2,145,145+h,210,160+h);
  1831.  
  1832.         AddField('',30,1,220,44+h,245,60+h);
  1833.         AddField('',31,1,220,69+h,245,85+h);
  1834.         AddField('',32,1,220,94+h,245,110+h);
  1835.         AddField('',33,1,220,119+h,245,135+h);
  1836.         AddField('',34,1,220,144+h,245,160+h);
  1837.  
  1838.         h:=-30;
  1839.         AddField('Type of Ends:',3,1,265,39+h,385,55+h);
  1840.         AddButton('Full Loop',14,3,265,65+h,345,80+h);
  1841.         AddButton('Full Round Hook',15,3,265,85+h,385,100+h);
  1842.         AddButton('Machine Loop',16,3,265,105+h,375,120+h);
  1843.         AddButton('Machine Hook',17,3,265,125+h,375,140+h);
  1844.         AddButton('Raised Hook',18,3,265,145+h,365,160+h);
  1845.         AddButton('Rectangular Hook',19,3,265,165+h,400,180+h);
  1846.         AddButton('V Hook',20,3,265,185+h,335,200+h);
  1847.  
  1848.         h:=10;
  1849.         AddField('View:',40,1,20,155+h,70,170+h);
  1850.         AddButton('Normal',41,3,20,175+h,90,190+h);
  1851.         AddButton('End View',42,3,100,175+h,190,190+h);
  1852.         AddButton('Edge View of Hooks',43,3,20,195+h,170,210+h);
  1853.         AddButton('Hooks at Right Angles',44,3,20,215+h,180,230+h);
  1854.         
  1855.         AddButton('Show All Coils',29,2,235,175+h,345,190+h);
  1856.  
  1857.     EndDialog;
  1858. END;
  1859.  
  1860. BEGIN
  1861.     MakeDialog4;
  1862. END;
  1863.  
  1864. Procedure GetInfo;
  1865. {
  1866. This procedure displays the dialog box and retrieves the information.
  1867. }
  1868. LABEL 5,10,20,99;
  1869. VAR
  1870.     Value : REAL;
  1871.     Item,Field,k,NTimes,NPlaces : INTEGER;
  1872.     RFlag : ARRAY[1..3] OF INTEGER;
  1873.     Done : BOOLEAN;
  1874.  
  1875. Procedure SetRButton(i,Item : INTEGER);
  1876. BEGIN
  1877.     IF RFlag[i] <> Item THEN BEGIN
  1878.         SetItem(RFlag[i],FALSE);
  1879.         SetItem(Item,TRUE);
  1880.         RFlag[i]:=Item;
  1881.     END;
  1882. END;
  1883.  
  1884. PROCEDURE SetUnitsField(Inch:BOOLEAN);
  1885. VAR
  1886.     Field,k : INTEGER;
  1887.     UnitsM1,UnitsM2 : STRING;
  1888. BEGIN
  1889.     Field:=29;
  1890.     IF Inch THEN
  1891.         UnitsM1:='in'
  1892.     ELSE
  1893.         UnitsM1:='mm';
  1894.     FOR k:=1 TO 5 DO
  1895.     BEGIN;
  1896.         Field:=Field+1;
  1897.         SetField(Field,UnitsM1);
  1898.     END;
  1899. END;
  1900.  
  1901. BEGIN
  1902.     NTimes:=NTimes+1;
  1903.     IF NTimes > 1 THEN GOTO 5;
  1904.     Type:=1;
  1905.     View:=1;
  1906.     Inch:=TRUE;
  1907.     ShowAllCoils:=FALSE;
  1908.  
  1909.     OD:=0.750;
  1910.     wd:=0.125;
  1911.     FL:=4.000;
  1912.     WL:=5.500;
  1913.     HL:=1.3125;
  1914.  
  1915.     5:Done:=FALSE;
  1916.     Abort:=FALSE;
  1917.     RFlag[1]:=Type+13;
  1918.     IF Inch Then RFlag[2]:=23
  1919.     ELSE RFlag[2]:=24;
  1920.     RFlag[3]:=View+40;
  1921.     GetDialog(4);
  1922.     SetTitle('Extension Springs');
  1923.     SetUnitsField(Inch);
  1924.     SetItem(RFlag[1],TRUE);
  1925.     SetItem(RFlag[2],TRUE);
  1926.     SetItem(RFlag[3],TRUE);
  1927.     SetItem(29,ShowAllCoils);
  1928.     SetField(5,Num2StrF(OD));
  1929.     SetField(7,Num2StrF(wd));
  1930.     SetField(9,Num2StrF(FL));
  1931.     SetField(11,Num2StrF(WL));
  1932.     IF Type>4 THEN SetField(13,Num2StrF(HL))
  1933.     ELSE SetField(13,'<n/a>');
  1934.     SelField(5);
  1935.     10:REPEAT
  1936.         DialogEvent(Item);
  1937.         IF Item=1 then
  1938.             Done:=True;
  1939.         IF Item=2 then BEGIN
  1940.             Done:=TRUE;
  1941.             Abort:=TRUE;
  1942.         END;
  1943.         IF (Item=13) AND (Type<5) THEN
  1944.         BEGIN
  1945.             Sysbeep;
  1946.             SelField(5);
  1947.         END;
  1948.         IF (Item>13) AND (Item<21) THEN
  1949.         BEGIN
  1950.             SetRButton(1,Item);
  1951.             Type:=Item-13;
  1952.             IF Type>4 THEN
  1953.                 SetField(13,Num2StrF(HL))
  1954.             ELSE SetField(13,'<n/a>');
  1955.         END;
  1956.         IF Item=29 THEN
  1957.         BEGIN
  1958.             SetItem(Item,NOT ShowAllCoils);
  1959.             ShowAllCoils:=NOT ShowAllCoils;
  1960.         END;
  1961.         IF (Item=23) AND (NOT Inch) THEN
  1962.         BEGIN
  1963.             SetRButton(2,Item);
  1964.             Inch:=TRUE;
  1965.             SetUnitsField(Inch);
  1966.         END;
  1967.         IF (Item=24) AND (Inch) THEN
  1968.         BEGIN
  1969.             SetRButton(2,Item);
  1970.             Inch:=FALSE;
  1971.             SetUnitsField(Inch);
  1972.         END;
  1973.         IF (Item>40) AND (Item<45) THEN
  1974.         BEGIN
  1975.             SetRButton(3,Item);
  1976.             View:=Item-40;
  1977.         END;
  1978.     UNTIL Done;
  1979.     IF Abort THEN GOTO 99;
  1980.     Field:=3;
  1981.     FOR k:=1 TO 5 DO
  1982.     BEGIN
  1983.         Field:=Field+2;
  1984.         IF (Field=13) AND (Type<5) THEN GOTO 20;
  1985.         IF Str2Num(GetField(Field))>0 THEN GOTO 20;
  1986.         SysBeep;
  1987.         SelField(Field);
  1988.         Done:=False;
  1989.         GOTO 10;
  1990.     20:END;
  1991.     OD:=Str2Num(GetField(5));
  1992.     wd:=Str2Num(GetField(7));
  1993.     FL:=Str2Num(GetField(9));
  1994.     WL:=Str2Num(GetField(11));
  1995.     IF Type>4 THEN HL:=Str2Num(GetField(13));
  1996.     99:ClrDialog;
  1997. END;
  1998.  
  1999. Procedure DrawCoil(x1,y1,x2,y2,wd:REAL);
  2000. VAR
  2001.     r,L,Theta,x0,y0 : REAL;
  2002. BEGIN
  2003.     r:=wd/2;
  2004.     L:=Distance(x1,y1,x2,y2);
  2005.     Theta:=ArcCos((x2-x1)/L);
  2006.     IF y2 < y1 THEN
  2007.     Theta:=2*PI-Theta;
  2008.     x0:=x1-r*Cos(Theta)-r*Sin(Theta);
  2009.     y0:=y1-r*Sin(Theta)+r*Cos(Theta);
  2010.     Theta:=Rad2Deg(Theta);
  2011.     Absolute;
  2012.     MoveTo(x0,y0);
  2013.     Relative;
  2014.     AngleVar;
  2015.     ClosePoly;
  2016.     BeginPoly;
  2017.         ArcTo((L+2*r),#Theta,r);
  2018.         ArcTo((2*r),#(Theta-90),r);
  2019.         ArcTo(-(L+2*r),#Theta,r);
  2020.         ArcTo(-(2*r),#(Theta-90),r);
  2021.     EndPoly;
  2022.     NoAngleVar;
  2023. END;
  2024.  
  2025. Procedure DrawEndView;
  2026. LABEL 99;
  2027. CONST
  2028.     MaxPoints=12;
  2029. VAR
  2030.     p1,p2,p3,p4,p5,p6,p7,r1,r2,r3,r4,r5 : REAL;
  2031.     q1,q2,Theta1 : REAL;
  2032.     x,y,R : ARRAY[1..MaxPoints] OF REAL;
  2033. BEGIN
  2034.     r1:=ID/2;
  2035.     r2:=OD/2;
  2036.     r3:=wd/2;
  2037.     r4:=r3+wd;
  2038.     r5:=wd/2;
  2039.     p1:=Sqrt((r1-r3)^2 - (r3+r5)^2);
  2040.     Theta1:=ArcCos((r3+r5)/(r1-r3));
  2041.     p2:=r3/(Tan(Theta1/2));
  2042.     p3:=(r3 + 2*r5)/(Tan(Theta1/2));
  2043.     p4:=r1*(Tan(Theta1/2));
  2044.     p5:=r2*(Tan(Theta1/2));
  2045.     p6:=r1*Sin(Theta1);
  2046.     p7:=r2*Sin(Theta1);
  2047.     q1:=r1*Cos(Theta1);
  2048.     q2:=r2*Cos(Theta1);
  2049.  
  2050.     x[1]:=0;                y[1]:=r2;            R[1]:=0;
  2051.     x[2]:=-r2;            y[2]:=r2;            R[2]:=r2;
  2052.     x[3]:=-r2;            y[3]:=-r2;            R[3]:=r2;
  2053.     x[4]:=r2;            y[4]:=-r2;            R[4]:=r2;
  2054.     x[5]:=r2;            y[5]:=r2;            R[5]:=r2;
  2055.     x[6]:=0;                y[6]:=r2;            R[6]:=0;
  2056.     x[7]:=0;                y[7]:=r1;            R[7]:=0;
  2057.     x[8]:=r1;            y[8]:=r1;            R[8]:=r1;
  2058.     x[9]:=r1;            y[9]:=-r1;            R[9]:=r1;
  2059.     x[10]:=-r1;        y[10]:=-r1;        R[10]:=r1;
  2060.     x[11]:=-r1;        y[11]:=r1;            R[11]:=r1;
  2061.     x[12]:=0;            y[12]:=r1;            R[12]:=0;
  2062.  
  2063.     Absolute;
  2064.     ClosePoly;
  2065.     BeginPoly;
  2066.         LineTo(x0+x[1], y0+y[1]);
  2067.         FOR k:=2 TO 5 DO
  2068.             ArcTo(x0+x[k], y0+y[k], R[k]);
  2069.         LineTo(x0+x[6], y0+y[6]);
  2070.         MoveTo(x0+x[7], y0+y[7]);
  2071.         FOR k:=8 TO 11 DO
  2072.             ArcTo(x0+x[k], y0+y[k], R[k]);
  2073.         LineTo(x0+x[12], y0+y[12]);
  2074.         MoveTo(x0+x[1], y0+y[1]);
  2075.     EndPoly;
  2076.  
  2077.     x[1]:=0;                y[1]:=r2;            R[1]:=0;
  2078.     x[2]:=-p5;            y[2]:=r2;            R[2]:=r2;
  2079.     x[3]:=-p7;            y[3]:=q2;            R[3]:=0;
  2080.     x[4]:=-(p1+p3);y[4]:=-r5;            R[4]:=r4;
  2081.     x[5]:=-p1;            y[5]:=-r5;            R[5]:=0;
  2082.     x[6]:=r2;            y[6]:=-r5;            R[6]:=r5;
  2083.     x[7]:=r2;            y[7]:=r5;            R[7]:=r5;
  2084.     x[8]:=-p1;            y[8]:=r5;            R[8]:=0;
  2085.     x[9]:=-(p1+p2);y[9]:=r5;            R[9]:=r3;
  2086.     x[10]:=-p6;        y[10]:=q1;            R[10]:=0;
  2087.     x[11]:=-p4;        y[11]:=r1;            R[11]:=r1;
  2088.     x[12]:=0;            y[12]:=r1;            R[12]:=0;
  2089.  
  2090.     BeginPoly;
  2091.         FOR k:=1 TO 11 DO
  2092.         BEGIN
  2093.             IF R[k]=0 THEN
  2094.                 LineTo(x0+x[k], y0+y[k])
  2095.             ELSE
  2096.                 ArcTo(x0+x[k], y0+y[k], R[k]);
  2097.         END;
  2098.         LineTo(x0+x[12], y0+y[12]);
  2099.         MoveTo(x0+x[1], y0+y[1]);
  2100.     EndPoly;
  2101.     Group;
  2102. END;
  2103.  
  2104. Procedure DrawEnds(Type:INTEGER);
  2105. LABEL 10,20,30,99;
  2106. CONST
  2107.     MaxPoints=16;
  2108. VAR
  2109.     p1,p2,p3,p4,p5,p6,p7,s1,s2 : REAL;
  2110.     q1,q2,q3,q4,q5,r1,r2,r3,x1,y1 : REAL;
  2111.     Theta1,Theta2,Theta3,Theta4,Theta5 : REAL;
  2112.     x,y,R : ARRAY[1..MaxPoints] OF REAL;
  2113.     i,NPoints : INTEGER;
  2114.  
  2115. BEGIN
  2116.     IF Type = 1 THEN
  2117.         BEGIN
  2118.         NPoints:=16;
  2119.         r1:=ID/2;
  2120.         r2:=OD/2;
  2121.         r3:=wd/2;
  2122.         Theta1:=ArcTan((r1+r3)/(r2+r3));
  2123.         Theta2:=Pi/2 - 2*Theta1;
  2124.         p1:=(r1+r2+r3)*Tan(Theta2) - r3/Cos(Theta2);
  2125.         p2:=(2*r1+r3)*Tan(Theta2) + r3/Cos(Theta2);
  2126.         p3:=r3*(Cos(Theta2)+Sin(Theta2));
  2127.         q1:=r3*(Cos(Theta2)-Sin(Theta2));
  2128.         Theta3:=Pi/6;
  2129.         Theta4:=(Pi/2-Theta3)/2;
  2130.         p4:=r1*Tan(Theta4);
  2131.         p5:=r2*Tan(Theta4);
  2132.         p6:=r1*Cos(Theta3);
  2133.         p7:=r2*Cos(Theta3);
  2134.         q3:=r1*Sin(Theta3);
  2135.         q4:=r2*Sin(Theta3);
  2136.  
  2137.     x[1]:=-(r2-p7);    y[1]:=q4;            R[1]:=0;
  2138.     x[2]:=-(r2-p5);    y[2]:=r2;            R[2]:=r2;
  2139.     x[3]:=-r2;                y[3]:=r2;            R[3]:=0;
  2140.     x[4]:=-2*r2;            y[4]:=r2;            R[4]:=r2;
  2141.     x[5]:=-2*r2;            y[5]:=-r2;            R[5]:=r2;
  2142.     x[6]:=-r2;                y[6]:=-r2;            R[6]:=0;
  2143.     x[7]:=-(p1-P/2);    y[7]:=-r2;            R[7]:=r2;
  2144.     x[8]:=P/2+p3;        y[8]:=r1+r3+q1;R[8]:=r3;
  2145.     x[9]:=P/2-q1;        y[9]:=r1+r3+p3;R[9]:=r3;
  2146.     x[10]:=-(p2-P/2);y[10]:=-r1;        R[10]:=r1;
  2147.     x[11]:=-r2;            y[11]:=-r1;        R[11]:=0;
  2148.     x[12]:=-(r1+r2);    y[12]:=-r1;        R[12]:=r1;
  2149.     x[13]:=-(r1+r2);    y[13]:=r1;            R[13]:=r1;
  2150.     x[14]:=-r2;            y[14]:=r1;            R[14]:=0;
  2151.     x[15]:=-(r2-p4);    y[15]:=r1;            R[15]:=r1;
  2152.     x[16]:=-(r2-p6);    y[16]:=q3;            R[16]:=0;
  2153.  
  2154.     END ELSE IF Type = 2 THEN
  2155.         BEGIN
  2156.         NPoints:=12;
  2157.         r1:=ID/2;
  2158.         r2:=OD/2;
  2159.         r3:=wd/2;
  2160.         Theta1:=ArcTan((r1+r3)/(r2+r3));
  2161.         Theta2:=Pi/2 - 2*Theta1;
  2162.         p1:=(r1+r2+r3)*Tan(Theta2) - r3/Cos(Theta2);
  2163.         p2:=(2*r1+r3)*Tan(Theta2) + r3/Cos(Theta2);
  2164.         p3:=r3*(Cos(Theta2)+Sin(Theta2));
  2165.         q1:=r3*(Cos(Theta2)-Sin(Theta2));
  2166.  
  2167.     x[1]:=-r2;                y[1]:=r2;            R[1]:=0;
  2168.     x[2]:=-2*r2;            y[2]:=r2;            R[2]:=r2;
  2169.     x[3]:=-2*r2;            y[3]:=-r2;            R[3]:=r2;
  2170.     x[4]:=-r2;                y[4]:=-r2;            R[4]:=0;
  2171.     x[5]:=-(p1-P/2);    y[5]:=-r2;            R[5]:=r2;
  2172.     x[6]:=P/2+p3;            y[6]:=r1+r3+q1;R[6]:=r3;
  2173.     x[7]:=P/2-q1;            y[7]:=r1+r3+p3;R[7]:=r3;
  2174.     x[8]:=-(p2-P/2);    y[8]:=-r1;            R[8]:=r1;
  2175.     x[9]:=-r2;                y[9]:=-r1;            R[9]:=0;
  2176.     x[10]:=-(r1+r2);    y[10]:=-r1;        R[10]:=r1;
  2177.     x[11]:=-(r1+r2);    y[11]:=r1;            R[11]:=r1;
  2178.     x[12]:=-r2;            y[12]:=r1;            R[12]:=0;
  2179.  
  2180.     END ELSE IF Type = 3 THEN
  2181.     BEGIN
  2182.         NPoints:=10;
  2183.         p1:=Hf2*wd;
  2184.         p2:=ID/2+p1;
  2185.         p3:=p2+wd;
  2186.         p4:=wd/2;
  2187.         r1:=ID/2;
  2188.         r2:=OD/2;
  2189.         r3:=wd/2;
  2190.  
  2191.         x[1]:=wd/2;        y[1]:=-r2;        R[1]:=r3;
  2192.         x[2]:=-p1;            y[2]:=-r2;        R[2]:=0;
  2193.         x[3]:=-p3;            y[3]:=-r2;        R[3]:=r2;
  2194.         x[4]:=-p3;            y[4]:=r2;        R[4]:=r2;
  2195.         x[5]:=-p4;            y[5]:=r2;        R[5]:=0;
  2196.         x[6]:=-p4;            y[6]:=r1;        R[6]:=0;
  2197.         x[7]:=-p2;            y[7]:=r1;        R[7]:=r1;
  2198.         x[8]:=-p2;            y[8]:=-r1;        R[8]:=r1;
  2199.         x[9]:=-p1;            y[9]:=-r1;        R[9]:=0;
  2200.         x[10]:=wd/2;        y[10]:=-r1;    R[10]:=r3;
  2201.  
  2202.     END ELSE IF Type = 4 THEN
  2203.     BEGIN
  2204.         NPoints:=12;
  2205.         Theta1:=Pi/6;
  2206.         p1:=Hf2*wd;
  2207.         p2:=ID/2+p1;
  2208.         p3:=OD/2+wd;
  2209.         p4:=p1+ID*Sin(Theta1)/2;
  2210.         p5:=p1+OD*Sin(Theta1)/2;
  2211.         q1:=ID*Tan(Theta1)/2;
  2212.         q2:=OD*Tan(Theta1)/2;
  2213.         q3:=ID*Cos(Theta1)/2;
  2214.         q4:=OD*Cos(Theta1)/2;
  2215.         r1:=ID/2;
  2216.         r2:=OD/2;
  2217.         r3:=wd/2;
  2218.  
  2219.         x[1]:=r3;            y[1]:=-r2;        R[1]:=r3;
  2220.         x[2]:=-p1;            y[2]:=-r2;        R[2]:=0;
  2221.         x[3]:=-p3;            y[3]:=-r2;        R[3]:=r2;
  2222.         x[4]:=-p3;            y[4]:=0;            R[4]:=0;
  2223.         x[5]:=-p3;            y[5]:=q2;        R[5]:=r2;
  2224.         x[6]:=-p5;            y[6]:=q4;        R[6]:=0;
  2225.         x[7]:=-p4;            y[7]:=q3;        R[7]:=0;
  2226.         x[8]:=-p2;            y[8]:=q1;        R[8]:=r1;
  2227.         x[9]:=-p2;            y[9]:=0;            R[9]:=0;
  2228.         x[10]:=-p2;        y[10]:=-r1;    R[10]:=r1;
  2229.         x[11]:=-p1;        y[11]:=-r1;    R[11]:=0;
  2230.         x[12]:=r3;            y[12]:=-r1;    R[12]:=r3;
  2231.  
  2232.  
  2233.     END ELSE IF (Type = 5) OR (Type = 6) THEN
  2234.     BEGIN
  2235.         NPoints:=8;
  2236.         p1:=HL+wd;
  2237.         IF Type=5 THEN
  2238.         BEGIN
  2239.             p2:=ID/2;
  2240.             r1:=ID/2;
  2241.             r2:=OD/2;
  2242.         END ELSE
  2243.         BEGIN
  2244.             p2:=wd;
  2245.             r1:=wd;
  2246.             r2:=2*wd;
  2247.         END;
  2248.         x[1]:=wd/2;        y[1]:=-OD/2;        R[1]:=wd/2;
  2249.         x[2]:=-p1;            y[2]:=-OD/2;        R[2]:=r2;
  2250.         x[3]:=x[2];        y[3]:=OD/2;        R[3]:=r2;
  2251.         x[4]:=-p2;            y[4]:=OD/2;        R[4]:=0;
  2252.         x[5]:=x[4];        y[5]:=ID/2;        R[5]:=0;
  2253.         x[6]:=x[3]+wd;    y[6]:=ID/2;        R[6]:=r1;
  2254.         x[7]:=x[6];        y[7]:=-ID/2;        R[7]:=r1;
  2255.         x[8]:=x[1];        y[8]:=-ID/2;        R[8]:=wd/2;
  2256.     END
  2257.  
  2258.     ELSE IF Type = 7 THEN
  2259.     BEGIN
  2260.         NPoints:=8;
  2261.         r1:=wd;
  2262.         r2:=wd/2;
  2263.         r3:=3*wd/2;
  2264.         p1:=D/2;
  2265.         q1:=HL-r1;
  2266.         s1:=Sqrt(p1^2 + q1^2);
  2267.         s2:=r1*s1/(r1+r2);
  2268.         Theta1:=ArcTan(q1/p1);
  2269.         Theta2:=ArcSin(r1/s2);
  2270.         Theta3:=Pi/2-Theta1-Theta2;
  2271.         p2:=r2*Tan((Pi/2 - Theta3)/2);
  2272.         q2:=HL;
  2273.         p3:=r3*Tan((Pi/2 - Theta3)/2);
  2274.         q3:=HL+wd;
  2275.         q4:=r2*(Cos(Theta3)-Sin(Theta3));
  2276.         p4:=r2*(Cos(Theta3)+Sin(Theta3));
  2277.         p5:=q1*Tan(Theta3)/2;
  2278.  
  2279.         x[1]:=q4;        y[1]:=-(D/2+p4);        R[1]:=r2;
  2280.         x[2]:=-q3;        y[2]:=-p3;        R[2]:=r3;
  2281.         x[3]:=-q3;        y[3]:=p3;        R[3]:=r3;
  2282.         x[4]:=q4-q1/2;        y[4]:=(D/2+p4)-p5;    R[4]:=0;
  2283.         x[5]:=p4-q1/2;        y[5]:=(D/2-q4)-p5;    R[5]:=0;
  2284.         x[6]:=-q2;        y[6]:=p2;        R[6]:=r1;
  2285.         x[7]:=-q2;        y[7]:=-p2;        R[7]:=r1;
  2286.         x[8]:=p4;        y[8]:=-(D/2-q4);        R[8]:=r2;
  2287.     END;
  2288.  
  2289.     IF (View = 3) THEN GOTO 20;
  2290.     x1:=x0;        y1:=y0;
  2291.     i:=1;
  2292.     Absolute;
  2293.     ClosePoly;
  2294.     10:BeginPoly;
  2295.         FOR k:=1 TO NPoints DO
  2296.         BEGIN
  2297.             IF R[k]=0 THEN
  2298.                 LineTo(x1+i*x[k],y1+i*y[k])
  2299.             ELSE
  2300.                 ArcTo(x1+i*x[k],y1+i*y[k],R[k]);
  2301.         END;
  2302.     EndPoly;
  2303.     IF i=-1 THEN GOTO 99;
  2304.     IF View = 4 THEN GOTO 20;
  2305.     i:=-1;
  2306.     x1:=x0+LCW;        y1:=y0;
  2307.     GOTO 10;
  2308.  
  2309.     20:NPoints:=6;
  2310.     i:=1;
  2311.     x1:=x0+LCW;        y1:=y0;
  2312.     30:r1:=wd;
  2313.     r2:=2*wd;
  2314.     r3:=wd/2;
  2315.     Theta1:=ArcTan(P/(2*D));
  2316.     p1:=r3*(Cos(Theta1)+Sin(Theta1));
  2317.     q1:=r3*(Cos(Theta1)-Sin(Theta1));
  2318.     p2:=(D-wd)*Sin(Theta1)/2 + r3/Cos(Theta1);
  2319.     p3:=HL+wd;
  2320.     p4:=(D+wd)*Sin(Theta1)/2 - r3/Cos(Theta1);
  2321.  
  2322.     x[1]:=-p1;        y[1]:=D/2+q1;            R[1]:=r3;
  2323.     x[2]:=q1;        y[2]:=D/2+p1;            R[2]:=r3;
  2324.     x[3]:=p2;        y[3]:=wd/2;                R[3]:=r1;
  2325.     x[4]:=p3;        y[4]:=wd/2;                R[4]:=r3;
  2326.     x[5]:=p3;        y[5]:=-wd/2;            R[5]:=r3;
  2327.     x[6]:=p4;        y[6]:=-wd/2;            R[6]:=r2;
  2328.  
  2329.     Absolute;
  2330.     BeginPoly;
  2331.         FOR k:=1 TO NPoints DO
  2332.         BEGIN
  2333.             IF R[k]=0 THEN
  2334.                 LineTo(x1+i*x[k], y1+i*y[k])
  2335.             ELSE
  2336.                 ArcTo(x1+i*x[k], y1+i*y[k], R[k]);
  2337.         END;
  2338.     EndPoly;
  2339.     IF (View = 4) OR (i=-1) THEN GOTO 99;
  2340.     i:=-1;
  2341.     x1:=x0;  y1:=y0;
  2342.     GOTO 30;
  2343. 99:END;
  2344.  
  2345. {
  2346. Main Program.
  2347. }
  2348. BEGIN
  2349.     DSelectAll;
  2350. {
  2351. Display the dialog box and get the information.
  2352. }
  2353.     SpringDialog;
  2354.     SetCursor(ArrowC);
  2355.     GetInfo;
  2356.     IF Abort THEN GOTO 99;
  2357.  
  2358. {
  2359. Get drawing units and adjust parameters.
  2360. }
  2361.     GetUnits(UName,DA,Fmt,UPI,UM,UM2);
  2362.     IF Inch THEN
  2363.         sf:=UPI
  2364.     ELSE
  2365.         sf:=UPI/25.4;
  2366.     OD:=OD*sf;
  2367.     wd:=wd*sf;
  2368.     FL:=FL*sf;
  2369.     WL:=WL*sf;
  2370.     HL:=HL*sf;
  2371.     PushAttrs;
  2372. {
  2373. Get the location of the spring.
  2374. }
  2375.     GetPt(x0,y0);
  2376. {
  2377. Calculate spring parameters.
  2378. }
  2379.     D:=OD-wd;
  2380.     ID:=OD-2*wd;
  2381.     IF (Type=1) OR (Type=2) THEN
  2382.     BEGIN
  2383.         HL:=ID+wd;
  2384.     END ELSE IF (Type=3) OR (Type=4) THEN
  2385.     BEGIN
  2386.         HL:=(Hf2*wd+ID/2);
  2387.     END ELSE
  2388.     BEGIN
  2389.         LCF:=FL-2*HL;
  2390.         LCW:=WL-2*HL;
  2391.     END;
  2392.     LCF:=FL-2*HL;
  2393.     LCW:=WL-2*HL;
  2394.     NCoils:=LCF/wd - 1/2;
  2395.     P:=LCW/(NCoils + 1/2);
  2396.     IF (ShowAllCoils) OR ((NCoils - 1) <= 2*ShowCoils) THEN
  2397.     BEGIN
  2398.         s:=NCoils;
  2399.         ShowAllCoils:=TRUE;
  2400.     END ELSE
  2401.         s:=ShowCoils;
  2402.     n:=NCoils  - s + 1;
  2403. {
  2404. Draw spring.
  2405. }
  2406.     IF View=2 THEN
  2407.     BEGIN
  2408.         DrawEndView;
  2409.         GOTO 99;
  2410.     END;
  2411.  
  2412.     IF (Type>2)OR(View>3) THEN
  2413.     BEGIN
  2414.         IF (Type>2) OR ((Type<3)AND(View=3)) THEN
  2415.         BEGIN
  2416.             x1:=x0+P/2;
  2417.             y1:=y0+D/2;
  2418.             x2:=x0;
  2419.             y2:=y0-D/2;
  2420.             DrawCoil(x1,y1,x2,y2,wd);
  2421.         END;
  2422.         5:x1:=x0+LCW;
  2423.         y1:=y0+D/2;
  2424.         x2:=x1-P/2;
  2425.         y2:=y0-D/2;
  2426.         DrawCoil(x1,y1,x2,y2,wd);
  2427.     END;
  2428.     IF Type < 3 THEN DrawEnds(Type);
  2429.  
  2430.     FOR k:=1 TO NCoils DO
  2431.     BEGIN
  2432.         IF (k>s) AND (k<n) THEN GOTO 20;
  2433.         IF ((k=s)OR(k=NCoils)) OR (WL=FL) THEN GOTO 10;
  2434.         x1:=x0+k*P;
  2435.         y1:=y0-D/2;
  2436.         x2:=x0+(k+1/2)*P;
  2437.         y2:=y0+D/2;
  2438.         DrawCoil(x1,y1,x2,y2,wd);
  2439.         10:x1:=x0+(k-1/2)*P;
  2440.         y1:=y0+D/2;
  2441.         x2:=x0+k*P;
  2442.         y2:=y0-D/2;
  2443.         DrawCoil(x1,y1,x2,y2,wd);
  2444.     20:END;
  2445.  
  2446.     IF ShowAllCoils THEN GOTO 30;
  2447.     Absolute;
  2448.     MoveTo((x0+(s-1/2)*P), y0+OD/2);
  2449.     PenPat(PP1);
  2450.     Relative;
  2451.     LineTo((NCoils-2*s+1)*P, 0);
  2452.     Move(wd/2,-OD);
  2453.     LineTo(-(NCoils-2*s+1)*P, 0);
  2454.  
  2455.     30:PopAttrs;
  2456.     IF Type > 2 THEN DrawEnds(Type);
  2457.     Group;
  2458. 99:END;    {of ExtensionSprings}
  2459.  
  2460.  
  2461. Procedure MainDialog;
  2462. {
  2463. This procedure defines the main dialog box.
  2464. }
  2465. VAR
  2466.     Width,x1,y1,x2,y2,px1,px2,px3,px4,py1,py2,py3,py4 : INTEGER;
  2467.  
  2468. Procedure AlignScr(Width:INTEGER; VAR x1,x2:INTEGER);
  2469. VAR
  2470.     scrx1,scry1,scrx2,scry2:INTEGER;
  2471.  
  2472. BEGIN
  2473.     GetScreen(scrx1,scry1,scrx2,scry2);
  2474.     x1:=((scrx1+scrx2) div 2)-(Width div 2);
  2475.     x2:=x1+Width; 
  2476. END;
  2477.  
  2478. Procedure LocateButtons(DialogType,scnh,scnw : INTEGER);
  2479. {
  2480. This procedure locates the 'OK' and 'Cancel' buttons.
  2481. }
  2482. VAR
  2483.     v1,v2,v3,v4 : INTEGER;
  2484.     Mac : BOOLEAN;
  2485.  
  2486. Procedure Swap(VAR  m1,m2,m3,m4 : INTEGER);
  2487. VAR
  2488.     Temp : INTEGER;
  2489. BEGIN
  2490.     Temp:=m1;
  2491.     m1:=m3;
  2492.     m3:=Temp;
  2493.     Temp:=m2;
  2494.     m2:=m4;
  2495.     m4:=Temp;
  2496. END;        {of Swap}
  2497.  
  2498. BEGIN
  2499.     Mac:=FALSE;
  2500.     GetVersion(v1,v2,v3,v4);
  2501.     IF v4 = 1 THEN Mac:=TRUE;
  2502.  
  2503.     IF DialogType = 1 THEN
  2504.     BEGIN
  2505.         px1:=(scnw DIV 2) - 80;
  2506.         px2:=(scnw DIV 2) - 10;
  2507.         px3:=(scnw DIV 2) + 10;
  2508.         px4:=(scnw DIV 2) + 80;
  2509.         IF Mac THEN SWAP(px1,px2,px3,px4);
  2510.  
  2511.         py1:=scnh-40;
  2512.         py2:=scnh-20;
  2513.         py3:=py1;
  2514.         py4:=py2;
  2515.     END ELSE IF DialogType = 2 THEN
  2516.     BEGIN
  2517.         px1:=scnw - 180;
  2518.         px2:=scnw - 110;
  2519.         px3:=scnw - 90;
  2520.         px4:=scnw - 20;
  2521.         IF Mac THEN SWAP(px1,px2,px3,px4);
  2522.  
  2523.         py1:=scnh-40;
  2524.         py2:=scnh-20;
  2525.         py3:=py1;
  2526.         py4:=py2;
  2527.     END ELSE
  2528.     BEGIN
  2529.         px1:=scnw - 90;
  2530.         px2:=scnw - 20;
  2531.         px3:=px1;
  2532.         px4:=px2;
  2533.  
  2534.         py1:=scnh -70;
  2535.         py2:=scnh - 50;
  2536.         py3:=scnh - 40;
  2537.         py4:=scnh - 20;
  2538.         IF Mac THEN SWAP(py1,py2,py3,py4);
  2539.     END;
  2540. END;        {of Locate Buttons}
  2541.  
  2542. Procedure MakeDialog6;
  2543.  
  2544. CONST
  2545.     y1=100;
  2546.     scnw = 250;
  2547.     scnh = 200;
  2548.     DialogType = 1;
  2549.  
  2550. VAR
  2551.     h : INTEGER;
  2552.  
  2553. BEGIN
  2554.     AlignScr(scnw,x1,x2);
  2555.     y2:=y1+scnh;
  2556.     LocateButtons(DialogType,scnh,scnw);
  2557.  
  2558.     BeginDialog(6,1,x1,y1,x2,y2);
  2559.         AddButton('OK',1,1,px1,py1,px2,py2);
  2560.         AddButton('Cancel',2,1,px3,py3,px4,py4);
  2561.  
  2562.         h:=-30;
  2563.         AddField('Type of Spring:',4,1,20,39+h,195,55+h);
  2564.         AddButton('Compression Spring',5,3,20,65+h,220,80+h);    
  2565.         AddButton('Extension Spring',6,3,20,85+h,220,100+h);
  2566.         AddButton('Conical Compression spring',7,3,20,105+h,220,120+h);
  2567.         AddButton('Heavy Duty Die Spring',8,3,20,125+h,220,140+h);
  2568.         {AddButton('Torsion Spring',9,3,20,145+h,220,160+h);}
  2569.     EndDialog;
  2570. END;
  2571.  
  2572. BEGIN
  2573.     MakeDialog6;
  2574. END;
  2575.  
  2576. Procedure GetInfo1;
  2577. {
  2578. This procedure displays the main dialog box and retrieves the information.
  2579. }
  2580. VAR
  2581.     Item:INTEGER;
  2582.     RFlag : ARRAY[1..2] OF INTEGER;
  2583.     Done:BOOLEAN;
  2584.  
  2585. Procedure SetRButton(i,Item : INTEGER);
  2586. BEGIN
  2587.     IF RFlag[i] <> Item THEN BEGIN
  2588.         SetItem(RFlag[i],FALSE);
  2589.         SetItem(Item,TRUE);
  2590.         RFlag[i]:=Item;
  2591.     END;
  2592. END;
  2593.  
  2594. BEGIN
  2595.     Done:=FALSE;
  2596.     Abort:=FALSE;
  2597.     Type:=1;
  2598.     RFlag[1]:=5;
  2599.     GetDialog(6);
  2600.     SetTitle('Springs');
  2601.     SetItem(RFlag[1],TRUE);
  2602.     REPEAT
  2603.         DialogEvent(Item);
  2604.         IF Item=1 THEN
  2605.             Done:=TRUE;
  2606.         IF Item=2 THEN
  2607.         BEGIN
  2608.             Done:=TRUE;
  2609.             Abort:=TRUE;
  2610.         END;
  2611.         IF Item>4 THEN BEGIN
  2612.             SetRButton(1,Item);
  2613.             Type:=Item-4;
  2614.         END;
  2615.     UNTIL DONE;
  2616.     ClrDialog;
  2617. END;
  2618.  
  2619. {
  2620. Main Program.
  2621. }
  2622. BEGIN
  2623.     MainDialog;
  2624.     SetCursor(ArrowC);
  2625.     GetInfo1;
  2626.     IF Abort THEN GOTO 99;
  2627.     If Type=1 THEN CompressionSprings
  2628.     ELSE If Type=2 THEN ExtensionSprings
  2629.     ELSE If Type=3 THEN ConicalCompSprings
  2630.     ELSE If Type=4 THEN DieSprings;
  2631. 99:END;
  2632.  
  2633. RUN(Springs);
  2634.  
  2635.