home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TRIG.ZIP / TRIG.PAS
Encoding:
Pascal/Delphi Source File  |  1987-11-23  |  14.8 KB  |  487 lines

  1. unit Trig;
  2.  
  3. (*  TRIG  -  Supplies missing trigonometric functions for Turbo Pascal 4.0
  4.  *           Also provides hyperbolic, logarithmic, power, and root functions.
  5.  *           All trig functions accessible by radians, decimal degrees,
  6.  *           degrees-minutes-seconds, and a global DegreeType.  Conversions
  7.  *           between these are supplied.
  8.  *
  9.  *  Written November 23, 1987 by Hugo Hemmerich, Refined Technologies.
  10.  *  All code granted to the public domain.
  11.  *
  12.  *  Questions and comments to CompuServe account number 72376,3505
  13.  *)
  14.  
  15. interface
  16.  
  17. type
  18.   DegreeType =  record
  19.                   Degrees, Minutes, Seconds : real;
  20.                 end;
  21. const
  22.   Infinity = 9.9999999999E+37;
  23.  
  24. {  Radians  }
  25. { sin, cos, and arctan are predefined }
  26.  
  27. function Tan( Radians : real ) : real;
  28. function ArcSin( InValue : real ) : real;
  29. function ArcCos( InValue : real ) : real;
  30.  
  31. {  Degrees, expressed as a real number  }
  32.  
  33. function DegreesToRadians( Degrees : real ) : real;
  34. function RadiansToDegrees( Radians : real ) : real;
  35. function Sin_Degree( Degrees : real ) : real;
  36. function Cos_Degree( Degrees : real ) : real;
  37. function Tan_Degree( Degrees : real ) : real;
  38. function ArcSin_Degree( Degrees : real ) : real;
  39. function ArcCos_Degree( Degrees : real ) : real;
  40. function ArcTan_Degree( Degrees : real ) : real;
  41.  
  42. {  Degrees, in Degrees, Minutes, and Seconds, as real numbers  }
  43.  
  44. function DegreePartsToDegrees( Degrees, Minutes, Seconds : real ) : real;
  45. function DegreePartsToRadians( Degrees, Minutes, Seconds : real ) : real;
  46. procedure DegreesToDegreeParts( DegreesIn : real;
  47.                                 var Degrees, Minutes, Seconds : real );
  48. procedure RadiansToDegreeParts( Radians : real;
  49.                                 var Degrees, Minutes, Seconds : real );
  50. function Sin_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  51. function Cos_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  52. function Tan_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  53. function ArcSin_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  54. function ArcCos_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  55. function ArcTan_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  56.  
  57. {  Degrees, expressed as DegreeType ( reals in record ) }
  58.  
  59. function DegreeTypeToDegrees( DegreeVar : DegreeType ) : real;
  60. function DegreeTypeToRadians( DegreeVar : DegreeType ) : real;
  61. procedure DegreeTypeToDegreeParts( DegreeVar : DegreeType;
  62.                                    var Degrees, Minutes, Seconds : real );
  63. procedure DegreesToDegreeType( Degrees : real; var DegreeVar : DegreeType );
  64. procedure RadiansToDegreeType( Radians : real; var DegreeVar : DegreeType );
  65. procedure DegreePartsToDegreeType( Degrees, Minutes, Seconds : real;
  66.                                    var DegreeVar : DegreeType );
  67. function Sin_DegreeType( DegreeVar : DegreeType ) : real;
  68. function Cos_DegreeType( DegreeVar : DegreeType ) : real;
  69. function Tan_DegreeType( DegreeVar : DegreeType ) : real;
  70. function ArcSin_DegreeType( DegreeVar : DegreeType ) : real;
  71. function ArcCos_DegreeType( DegreeVar : DegreeType ) : real;
  72. function ArcTan_DegreeType( DegreeVar : DegreeType ) : real;
  73.  
  74. {  Hyperbolic functions  }
  75.  
  76. function Sinh( Invalue : real ) : real;
  77. function Cosh( Invalue : real ) : real;
  78. function Tanh( Invalue : real ) : real;
  79. function Coth( Invalue : real ) : real;
  80. function Sech( Invalue : real ) : real;
  81. function Csch( Invalue : real ) : real;
  82. function ArcSinh( Invalue : real ) : real;
  83. function ArcCosh( Invalue : real ) : real;
  84. function ArcTanh( Invalue : real ) : real;
  85. function ArcCoth( Invalue : real ) : real;
  86. function ArcSech( Invalue : real ) : real;
  87. function ArcCsch( Invalue : real ) : real;
  88.  
  89. {  Logarithms, Powers, and Roots  }
  90.  
  91. { e to the x  is  exp() }
  92. { natural log is  ln()  }
  93. function Log10( InNumber : real ) : real;
  94. function Log( Base, InNumber : real ) : real;  { log of any base }
  95. function Power( InNumber, Exponent : real ) : real;
  96. function Root( InNumber, TheRoot : real ) : real;
  97.  
  98. {----------------------------------------------------------------------}
  99. implementation
  100.  
  101. const
  102.   RadiansPerDegree =  0.017453292520;
  103.   DegreesPerRadian = 57.295779513;
  104.   MinutesPerDegree =   60.0;
  105.   SecondsPerDegree = 3600.0;
  106.   SecondsPerMinute = 60.0;
  107.   LnOf10 = 2.3025850930;
  108.  
  109. {-----------}
  110. {  Radians  }
  111. {-----------}
  112.  
  113. { sin, cos, and arctan are predefined }
  114.  
  115. function Tan { ( Radians : real ) : real };
  116.   { note: returns Infinity where appropriate }
  117.   var
  118.     CosineVal : real;
  119.     TangentVal : real;
  120.   begin
  121.   CosineVal := cos( Radians );
  122.   if CosineVal = 0.0 then
  123.     Tan := Infinity
  124.   else
  125.     begin
  126.     TangentVal := sin( Radians ) / CosineVal;
  127.     if ( TangentVal < -Infinity ) or ( TangentVal > Infinity ) then
  128.       Tan := Infinity
  129.     else
  130.       Tan := TangentVal;
  131.     end;
  132.   end;
  133.  
  134. function ArcSin{ ( InValue : real ) : real };
  135.   { notes: 1) exceeding input range of -1 through +1 will cause runtime error }
  136.   {        2) only returns principal values                                   }
  137.   {             ( -pi/2 through pi/2 radians ) ( -90 through +90 degrees )    }
  138.   begin
  139.   if abs( InValue ) = 1.0 then
  140.     ArcSin := pi / 2.0
  141.   else
  142.     ArcSin := arctan( InValue / sqrt( 1 - InValue * InValue ) );
  143.   end;
  144.  
  145. function ArcCos{ ( InValue : real ) : real };
  146.   { notes: 1) exceeding input range of -1 through +1 will cause runtime error }
  147.   {        2) only returns principal values                                   }
  148.   {             ( 0 through pi radians ) ( 0 through +180 degrees )           }
  149.   var
  150.     Result : real;
  151.   begin
  152.   if InValue = 0.0 then
  153.     ArcCos := pi / 2.0
  154.   else
  155.     begin
  156.     Result := arctan( sqrt( 1 - InValue * InValue ) / InValue );
  157.     if InValue < 0.0 then
  158.       ArcCos := Result + pi
  159.     else
  160.       ArcCos := Result;
  161.     end;
  162.   end;
  163.  
  164. {---------------------------------------}
  165. {  Degrees, expressed as a real number  }
  166. {---------------------------------------}
  167.  
  168. function DegreesToRadians{ ( Degrees : real ) : real };
  169.   begin
  170.   DegreesToRadians := Degrees * RadiansPerDegree;
  171.   end;
  172.  
  173. function RadiansToDegrees{ ( Radians : real ) : real };
  174.   begin
  175.   RadiansToDegrees := Radians * DegreesPerRadian;
  176.   end;
  177.  
  178. function Sin_Degree{ ( Degrees : real ) : real };
  179.   begin
  180.   Sin_Degree := sin( DegreesToRadians( Degrees ) );
  181.   end;
  182.  
  183. function Cos_Degree{ ( Degrees : real ) : real };
  184.   begin
  185.   Cos_Degree := cos( DegreesToRadians( Degrees ) );
  186.   end;
  187.  
  188. function Tan_Degree{ ( Degrees : real ) : real };
  189.   begin
  190.   Tan_Degree := Tan( DegreesToRadians( Degrees ) );
  191.   end;
  192.  
  193. function ArcSin_Degree{ ( Degrees : real ) : real };
  194.   begin
  195.   ArcSin_Degree := ArcSin( DegreesToRadians( Degrees ) );
  196.   end;
  197.  
  198. function ArcCos_Degree{ ( Degrees : real ) : real };
  199.   begin
  200.   ArcCos_Degree := ArcCos( DegreesToRadians( Degrees ) );
  201.   end;
  202.  
  203. function ArcTan_Degree{ ( Degrees : real ) : real };
  204.   begin
  205.   ArcTan_Degree := arctan( DegreesToRadians( Degrees ) );
  206.   end;
  207.  
  208. {--------------------------------------------------------------}
  209. {  Degrees, in Degrees, Minutes, and Seconds, as real numbers  }
  210. {--------------------------------------------------------------}
  211.  
  212. function DegreePartsToDegrees{ ( Degrees, Minutes, Seconds : real ) : real };
  213.   begin
  214.   DegreePartsToDegrees := Degrees + ( Minutes / MinutesPerDegree ) +
  215.                                        ( Seconds / SecondsPerDegree );
  216.   end;
  217.  
  218. function DegreePartsToRadians{ ( Degrees, Minutes, Seconds : real ) : real };
  219.   begin
  220.   DegreePartsToRadians := DegreesToRadians( DegreePartsToDegrees( Degrees,
  221.                                                         Minutes, Seconds ) );
  222.   end;
  223.  
  224. procedure DegreesToDegreeParts{ ( DegreesIn : real;
  225.                                   var Degrees, Minutes, Seconds : real ) };
  226.   begin
  227.   Degrees := int( DegreesIn );
  228.   Minutes := ( DegreesIn - Degrees ) * MinutesPerDegree;
  229.   Seconds := frac( Minutes );
  230.   Minutes := int( Minutes );
  231.   Seconds := Seconds * SecondsPerMinute;
  232.   end;
  233.  
  234. procedure RadiansToDegreeParts{ ( Radians : real;
  235.                                   var Degrees, Minutes, Seconds : real ) };
  236.   begin
  237.   DegreesToDegreeParts( RadiansToDegrees( Radians ),
  238.                           Degrees, Minutes, Seconds );
  239.   end;
  240.  
  241. function Sin_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  242.   begin
  243.   Sin_DegreeParts := sin( DegreePartsToRadians( Degrees, Minutes, Seconds ) );
  244.   end;
  245.  
  246. function Cos_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  247.   begin
  248.   Cos_DegreeParts := cos( DegreePartsToRadians( Degrees, Minutes, Seconds ) );
  249.   end;
  250.  
  251. function Tan_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  252.   begin
  253.   Tan_DegreeParts := Tan( DegreePartsToRadians( Degrees, Minutes, Seconds ) );
  254.   end;
  255.  
  256. function ArcSin_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  257.   begin
  258.   ArcSin_DegreeParts := ArcSin( DegreePartsToRadians( Degrees,
  259.                                                       Minutes, Seconds ) );
  260.   end;
  261.  
  262. function ArcCos_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  263.   begin
  264.   ArcCos_DegreeParts := ArcCos( DegreePartsToRadians( Degrees,
  265.                                                       Minutes, Seconds ) );
  266.   end;
  267.  
  268. function ArcTan_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  269.   begin
  270.   ArcTan_DegreeParts := arctan( DegreePartsToRadians( Degrees,
  271.                                                       Minutes, Seconds ) );
  272.   end;
  273.  
  274. {-------------------------------------------------------}
  275. {  Degrees, expressed as DegreeType ( reals in record ) }
  276. {-------------------------------------------------------}
  277.  
  278. function DegreeTypeToDegrees{ ( DegreeVar : DegreeType ) : real };
  279.   begin
  280.   DegreeTypeToDegrees := DegreePartsToDegrees( DegreeVar.Degrees,
  281.                                        DegreeVar.Minutes, DegreeVar.Seconds );
  282.   end;
  283.  
  284. function DegreeTypeToRadians{ ( DegreeVar : DegreeType ) : real };
  285.   begin
  286.   DegreeTypeToRadians := DegreesToRadians( DegreeTypeToDegrees( DegreeVar ) );
  287.   end;
  288.  
  289. procedure DegreeTypeToDegreeParts{ ( DegreeVar : DegreeType;
  290.                                      var Degrees, Minutes, Seconds : real ) };
  291.   begin
  292.   Degrees := DegreeVar.Degrees;
  293.   Minutes := DegreeVar.Minutes;
  294.   Seconds := DegreeVar.Seconds;
  295.   end;
  296.  
  297. procedure DegreesToDegreeType{ ( Degrees : real; var DegreeVar : DegreeType )};
  298.   begin
  299.   DegreesToDegreeParts( Degrees, DegreeVar.Degrees,
  300.                         DegreeVar.Minutes, DegreeVar.Seconds );
  301.   end;
  302.  
  303. procedure RadiansToDegreeType{ ( Radians : real; var DegreeVar : DegreeType )};
  304.   begin
  305.   DegreesToDegreeParts( RadiansToDegrees( Radians ), DegreeVar.Degrees,
  306.                         DegreeVar.Minutes, DegreeVar.Seconds );
  307.   end;
  308.  
  309. procedure DegreePartsToDegreeType{ ( Degrees, Minutes, Seconds : real;
  310.                                      var DegreeVar : DegreeType ) };
  311.   begin
  312.   DegreeVar.Degrees := Degrees;
  313.   DegreeVar.Minutes := Minutes;
  314.   DegreeVar.Seconds := Seconds;
  315.   end;
  316.  
  317. function Sin_DegreeType{ ( DegreeVar : DegreeType ) : real };
  318.   begin
  319.   Sin_DegreeType := sin( DegreeTypeToRadians( DegreeVar ) );
  320.   end;
  321.  
  322. function Cos_DegreeType{ ( DegreeVar : DegreeType ) : real };
  323.   begin
  324.   Cos_DegreeType := cos( DegreeTypeToRadians( DegreeVar ) );
  325.   end;
  326.  
  327. function Tan_DegreeType{ ( DegreeVar : DegreeType ) : real };
  328.   begin
  329.   Tan_DegreeType := Tan( DegreeTypeToRadians( DegreeVar ) );
  330.   end;
  331.  
  332. function ArcSin_DegreeType{ ( DegreeVar : DegreeType ) : real };
  333.   begin
  334.   ArcSin_DegreeType := ArcSin( DegreeTypeToRadians( DegreeVar ) );
  335.   end;
  336.  
  337. function ArcCos_DegreeType{ ( DegreeVar : DegreeType ) : real };
  338.   begin
  339.   ArcCos_DegreeType := ArcCos( DegreeTypeToRadians( DegreeVar ) );
  340.   end;
  341.  
  342. function ArcTan_DegreeType{ ( DegreeVar : DegreeType ) : real };
  343.   begin
  344.   ArcTan_DegreeType := arctan( DegreeTypeToRadians( DegreeVar ) );
  345.   end;
  346.  
  347. {------------------------}
  348. {  Hyperbolic functions  }
  349. {------------------------}
  350.  
  351. function Sinh{ ( Invalue : real ) : real };
  352.   const
  353.     MaxValue = 88.029691931;  { exceeds standard turbo precision }
  354.   var
  355.     Sign : real;
  356.   begin
  357.   Sign := 1.0;
  358.   if Invalue < 0 then
  359.     begin
  360.     Sign := -1.0;
  361.     Invalue := -Invalue;
  362.     end;
  363.   if Invalue > MaxValue then
  364.     Sinh := Infinity
  365.   else
  366.     Sinh := ( exp( Invalue ) - exp( -Invalue ) ) / 2.0 * Sign;
  367.   end;
  368.  
  369. function Cosh{ ( Invalue : real ) : real };
  370.   const
  371.     MaxValue = 88.029691931;  { exceeds standard turbo precision }
  372.   begin
  373.   Invalue := abs( Invalue );
  374.   if Invalue > MaxValue then
  375.     Cosh := Infinity
  376.   else
  377.     Cosh := ( exp( Invalue ) + exp( -Invalue ) ) / 2.0;
  378.   end;
  379.  
  380. function Tanh{ ( Invalue : real ) : real };
  381.   begin
  382.   Tanh := Sinh( Invalue ) / Cosh( Invalue );
  383.   end;
  384.  
  385. function Coth{ ( Invalue : real ) : real };
  386.   begin
  387.   Coth := Cosh( Invalue ) / Sinh( Invalue );
  388.   end;
  389.  
  390. function Sech{ ( Invalue : real ) : real };
  391.   begin
  392.   Sech := 1.0 / Cosh( Invalue );
  393.   end;
  394.  
  395. function Csch{ ( Invalue : real ) : real };
  396.   begin
  397.   Csch := 1.0 / Sinh( Invalue );
  398.   end;
  399.  
  400. function ArcSinh{ ( Invalue : real ) : real };
  401.   var
  402.     Sign : real;
  403.   begin
  404.   Sign := 1.0;
  405.   if Invalue < 0 then
  406.     begin
  407.     Sign := -1.0;
  408.     Invalue := -Invalue;
  409.     end;
  410.   ArcSinh := ln( Invalue + sqrt( Invalue*Invalue + 1 ) ) * Sign;
  411.   end;
  412.  
  413. function ArcCosh{ ( Invalue : real ) : real };
  414.   var
  415.     Sign : real;
  416.   begin
  417.   Sign := 1.0;
  418.   if Invalue < 0 then
  419.     begin
  420.     Sign := -1.0;
  421.     Invalue := -Invalue;
  422.     end;
  423.   ArcCosh := ln( Invalue + sqrt( Invalue*Invalue - 1 ) ) * Sign;
  424.   end;
  425.  
  426. function ArcTanh{ ( Invalue : real ) : real };
  427.   var
  428.     Sign : real;
  429.   begin
  430.   Sign := 1.0;
  431.   if Invalue < 0 then
  432.     begin
  433.     Sign := -1.0;
  434.     Invalue := -Invalue;
  435.     end;
  436.   ArcTanh := ln( ( 1 + Invalue ) / ( 1 - Invalue ) ) / 2.0 * Sign;
  437.   end;
  438.  
  439. function ArcCoth{ ( Invalue : real ) : real };
  440.   begin
  441.   ArcCoth := ArcTanh( 1.0 / Invalue );
  442.   end;
  443.  
  444. function ArcSech{ ( Invalue : real ) : real };
  445.   begin
  446.   ArcSech := ArcCosh( 1.0 / Invalue );
  447.   end;
  448.  
  449. function ArcCsch{ ( Invalue : real ) : real };
  450.   begin
  451.   ArcCsch := ArcSinh( 1.0 / Invalue );
  452.   end;
  453.  
  454. {---------------------------------}
  455. {  Logarithms, Powers, and Roots  }
  456. {---------------------------------}
  457.  
  458. { e to the x  is  exp() }
  459. { natural log is  ln()  }
  460.  
  461. function Log10{ ( InNumber : real ) : real };
  462.   begin
  463.   Log10 := ln( InNumber ) / LnOf10;
  464.   end;
  465.  
  466. function Log{ ( Base, InNumber : real ) : real };  { log of any base }
  467.   begin
  468.   Log := ln( InNumber ) / ln( Base );
  469.   end;
  470.  
  471. function Power{ ( InNumber, Exponent : real ) : real };
  472.   begin
  473.   if InNumber > 0.0 then
  474.     Power := exp( Exponent * ln( InNumber ) )
  475.   else if InNumber = 0.0 then
  476.     Power := 1.0
  477.   else { force runtime error }
  478.     Power := InNumber / 0.0;
  479.   end;
  480.  
  481. function Root{ ( InNumber, TheRoot : real ) : real };
  482.   begin
  483.   Root := Power( InNumber, ( 1.0 / TheRoot ) );
  484.   end;
  485.  
  486. end. { unit Trig }
  487.