home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1990 / 01 / ladd.lst < prev    next >
File List  |  1989-12-08  |  16KB  |  544 lines

  1. _EXAMINING ZORTECH C++ 2.0_
  2. by Scott Robert Ladd
  3.  
  4.  
  5. [LISTIN╟ ONE]
  6.  
  7. //  Header:     Complex
  8. //  Version:    2.00    28-Oct-1989
  9. //  Language:   C++ 2.0;  Environ:  Any;  Compilers: Zortech C++ 2.01
  10. //  Purpose:    Provides the class "Complex" for C++ programs. The majority
  11. //              of the class is implemented inline for efficiency. Only
  12. //              the division, power, and i/o methods are actual functions.
  13. //  Written by: Scott Robert Ladd, 705 West Virginia, Gunnison CO 81230
  14. //              BBS (303)641-6438; FidoNet 1:104/708
  15.  
  16. #if !defined(__COMPLEX_HPP)
  17. #define __COMPLEX_HPP 1
  18. #include "stream.hpp"
  19. #include "math.h"
  20.  
  21. class Complex
  22.     {
  23.     private:
  24.         double Real;   // Real part
  25.         double Imag;   // Imaginary part
  26.         static void (* ErrorHandler)();
  27.     public:
  28.         // constructors
  29.         Complex (void);
  30.         Complex (const Complex & C);
  31.         Complex (double & R, double & I);
  32.         Complex (double & R);
  33.         // method to set error handler function
  34.         static void SetErrorHandler(void (* UserHandler)());
  35.         // value extraction methods
  36.         friend double real(const Complex & C);
  37.         friend double imag(const Complex & C);
  38.         // assignment methods
  39.         void operator = (const Complex & C);
  40.         void operator = (double & R);
  41.         // unary minus method
  42.         Complex operator - ();
  43.         // calculation methods
  44.         friend Complex operator + (const Complex & C1, const Complex &C2);
  45.         friend Complex operator - (const Complex & C1, const Complex &C2);
  46.         friend Complex operator * (const Complex & C1, const Complex &C2);
  47.         friend Complex operator / (const Complex & C1, const Complex &C2);
  48.  
  49.         Complex operator += (const Complex & C);
  50.         Complex operator -= (const Complex & C);
  51.         Complex operator *= (const Complex & C);
  52.         Complex operator /= (const Complex & C);
  53.         // comparison methods
  54.         friend int operator == (const Complex & C1, const Complex & C2);
  55.         friend int operator != (const Complex & C1, const Complex & C2);
  56.         friend int operator <  (const Complex & C1, const Complex & C2);
  57.         friend int operator <= (const Complex & C1, const Complex & C2);
  58.         friend int operator >  (const Complex & C1, const Complex & C2);
  59.         friend int operator >= (const Complex & C1, const Complex & C2);
  60.         // utility methods
  61.         friend double abs(const Complex & C);
  62.         friend double norm(const Complex & C);
  63.         friend double arg(const Complex & C);
  64.         // polar coordinate methods
  65.         friend Complex polar(double Radius, double Theta = 0.0);
  66.         friend Complex conj(const Complex & C);
  67.         // trigonometric methods
  68.         friend Complex cos(const Complex & C);
  69.         friend Complex sin(const Complex & C);
  70.         friend Complex tan(const Complex & C);
  71.         friend Complex cosh(const Complex & C);
  72.         friend Complex sinh(const Complex & C);
  73.         friend Complex tanh(const Complex & C);
  74.         // logarithmic methods
  75.         friend Complex exp(const Complex & C);
  76.         friend Complex log(const Complex & C);
  77.         // "power" methods
  78.         friend Complex pow(const Complex & C, const Complex & Power);
  79.         friend Complex sqrt(const Complex & C);
  80.         // output method
  81.         friend ostream & operator << (ostream & Output, const Complex & C);
  82.         friend istream & operator >> (istream & Input,  Complex & C);
  83.     };
  84. // constructors
  85. inline Complex::Complex (void)
  86.     {
  87.     Real = 0.0;
  88.     Imag = 0.0;
  89.     }
  90. inline Complex::Complex (const Complex & C)
  91.     {
  92.     Real = C.Real;
  93.     Imag = C.Imag;
  94.     }
  95. inline Complex::Complex (double & R, double & I)
  96.     {
  97.     Real = R;
  98.     Imag = I;
  99.     }
  100. inline Complex::Complex (double & R)
  101.     {
  102.     Real = R;
  103.     Imag = 0.0;
  104.     }
  105. inline void Complex::SetErrorHandler(void (* UserHandler)())
  106.     {
  107.     ErrorHandler = UserHandler;
  108.     }
  109. // value extraction methods
  110. inline double real (const Complex & C)
  111.     {
  112.     return C.Real;
  113.     }
  114. inline double imag (const Complex & C)
  115.     {
  116.     return C.Imag;
  117.     }
  118.  
  119. // assignment method
  120. inline void Complex::operator = (const Complex & C)
  121.     {
  122.     Real = C.Real;
  123.     Imag = C.Imag;
  124.     }
  125. inline void Complex::operator = (double & R)
  126.     {
  127.     Real = R;
  128.     Imag = 0.0;
  129.     }
  130. // unary minus method
  131. inline Complex Complex::operator - ()
  132.     {
  133.     Complex Result;
  134.     Result.Real = -Real;
  135.     Result.Imag = -Imag;
  136.     return Result;
  137.     }
  138. // calculation methods
  139. inline Complex operator + (const Complex & C1, const Complex &C2)
  140.     {
  141.     Complex Result;
  142.     Result.Real = C1.Real + C2.Real;
  143.     Result.Imag = C1.Imag + C2.Imag;
  144.     return Result;
  145.     }
  146. inline Complex operator - (const Complex & C1, const Complex &C2)
  147.     {
  148.     Complex Result;
  149.     Result.Real = C1.Real - C2.Real;
  150.     Result.Imag = C1.Imag - C2.Imag;
  151.     return Result;
  152.     }
  153. inline Complex operator * (const Complex & C1, const Complex &C2)
  154.     {
  155.     Complex Result;
  156.     Result.Real = (C1.Real * C2.Real) - (C1.Imag * C2.Imag);
  157.     Result.Imag = (C1.Real * C2.Imag) + (C1.Imag * C2.Real);
  158.     return Result;
  159.     }
  160. inline Complex Complex::operator += (const Complex &C)
  161.     {
  162.     Real += C.Real;
  163.     Imag += C.Imag;
  164.     return *this;
  165.     }
  166. inline Complex Complex::operator -= (const Complex &C)
  167.     {
  168.     Real -= C.Real;
  169.     Imag -= C.Imag;
  170.     return *this;
  171.     }
  172. inline Complex Complex::operator *= (const Complex &C)
  173.     {
  174.     double OldReal;
  175.     OldReal = Real; // save old Real value
  176.     Real = (Real * C.Real) - (Imag * C.Imag);
  177.     Imag = (OldReal * C.Imag) + (Imag * C.Real);
  178.     return *this;
  179.     }
  180. // comparison methods
  181. inline int operator == (const Complex & C1, const Complex & C2)
  182.     {
  183.     return (C1.Real == C2.Real) && (C1.Imag == C2.Imag);
  184.     }
  185. inline int operator != (const Complex & C1, const Complex & C2)
  186.     {
  187.     return (C1.Real != C2.Real) || (C1.Imag != C2.Imag);
  188.     }
  189. inline int operator <  (const Complex & C1, const Complex & C2)
  190.     {
  191.     return abs(C1) < abs(C2);
  192.     }
  193. inline int operator <= (const Complex & C1, const Complex & C2)
  194.     {
  195.     return abs(C1) <= abs(C2);
  196.     }
  197. inline int operator >  (const Complex & C1, const Complex & C2)
  198.     {
  199.     return abs(C1) > abs(C2);
  200.     }
  201. inline int operator >= (const Complex & C1, const Complex & C2)
  202.     {
  203.     return abs(C1) >= abs(C2);
  204.     }
  205. // utility methods
  206. inline double abs(const Complex & C)
  207.     {
  208.     double Result;
  209.     Result = sqrt(C.Real * C.Real + C.Imag * C.Imag);
  210.     return Result;
  211.     }
  212. inline double norm(const Complex & C)
  213.     {
  214.     double Result;
  215.     Result = (C.Real * C.Real) + (C.Imag * C.Imag);
  216.     return Result;
  217.     }
  218. inline double arg(const Complex & C)
  219.     {
  220.     double Result;
  221.     Result = atan2(C.Imag, C.Real);
  222.     return Result;
  223.     }
  224. // polar coordinate methods
  225. inline Complex polar(double Radius, double Theta)
  226.     {
  227.     Complex Result;
  228.     Result.Real = Radius * cos(Theta);
  229.     Result.Imag = Radius * sin(Theta);
  230.     return Result;
  231.     }
  232. inline Complex conj(const Complex & C)
  233.     {
  234.     Complex Result;
  235.     Result.Real =  C.Real;
  236.     Result.Imag = -C.Imag;
  237.     return Result;
  238.     }
  239. // trigonometric methods
  240. inline Complex cos(const Complex & C)
  241.     {
  242.     Complex Result;
  243.     Result.Real =  cos(C.Real) * cosh(C.Imag);
  244.     Result.Imag = -sin(C.Real) * sinh(C.Imag);
  245.     return Result;
  246.     }
  247. inline Complex sin(const Complex & C)
  248.     {
  249.     Complex Result;
  250.     Result.Real = sin(C.Real) * cosh(C.Imag);
  251.     Result.Imag = cos(C.Real) * sinh(C.Imag);
  252.     return Result;
  253.     }
  254. inline Complex tan(const Complex & C)
  255.     {
  256.     Complex Result;
  257.     Result = sin(C) / cos(C);
  258.     return Result;
  259.     }
  260. inline Complex cosh(const Complex & C)
  261.     {
  262.     Complex Result;
  263.     Result = cos(C.Imag) * cosh(C.Real);
  264.     Result = sin(C.Imag) * sinh(C.Real);
  265.     return Result;
  266.     }
  267. inline Complex sinh(const Complex & C)
  268.     {
  269.     Complex Result;
  270.     Result.Real = cos(C.Imag) * sinh(C.Real);
  271.     Result.Imag = sin(C.Imag) * cosh(C.Real);
  272.     return Result;
  273.     }
  274. inline Complex tanh(const Complex & C)
  275.     {
  276.     Complex Result;
  277.     Result = sinh(C) / cosh(C);
  278.     return Result;
  279.     }
  280. // logarithmic methods
  281. inline Complex exp(const Complex & C)
  282.     {
  283.     Complex Result;
  284.     double X = exp(C.Real);
  285.     Result.Real = X * cos(C.Imag);
  286.     Result.Imag = X * sin(C.Imag);
  287.     return Result;
  288.     }
  289. inline Complex log(const Complex & C)
  290.     {
  291.     Complex Result;
  292.     double Hypot = abs(C);
  293.     if (Hypot > 0.0)
  294.         {
  295.         Result.Real = log(Hypot);
  296.         Result.Imag = atan2(C.Imag, C.Real);
  297.         }
  298.     else
  299.         Complex::ErrorHandler();
  300.     return Result;
  301.     }
  302. #endif // __Complex_HPP
  303.  
  304.  
  305.  
  306. [LISTI╬╟ TWO]
  307.  
  308. //  Module:     Complex
  309. //  Version:    2.00    28-Oct-1989
  310. //  Language:   C++ 2.0;  Environ:    Any;  Compilers:  Zortech C++ 2.01
  311. //  Purpose:    Provides the class "Complex" for C++ programs. The majority
  312. //              of the class is implemented inline for efficiency. Only
  313. //              the division, power, and i/o methods are actual functions.
  314. //  Written by: Scott Robert Ladd, 705 West Virginia, Gunnison CO 81230
  315. //              BBS (303)641-6438; FidoNet 1:104/708
  316.  
  317. #include "math.h"
  318. #include "stdlib.h"
  319. #include "Complex.hpp"
  320. #include "stream.hpp"
  321.  
  322. static void DefaultHandler();
  323. void (* Complex::ErrorHandler)() = DefaultHandler;
  324. static void DefaultHandler()
  325.     {
  326.     cout << "\aERROR in complex object: DIVIDE BY ZERO\n";
  327.     exit(1);
  328.     }
  329. // division methods
  330. Complex operator / (const Complex & C1, const Complex & C2)
  331.     {
  332.     Complex Result;
  333.     double Den;
  334.     Den = norm(C2);
  335.     if (Den != 0.0)
  336.         {
  337.         Result.Real = (C1.Real * C2.Real + C1.Imag * C2.Imag) / Den;
  338.         Result.Imag = (C1.Imag * C2.Real - C1.Real * C2.Imag) / Den;
  339.         }
  340.     else
  341.         Complex::ErrorHandler();
  342.     return Result;
  343.     }
  344. Complex Complex::operator /= (const Complex & C)
  345.     {
  346.     double Den, OldReal;
  347.     Den = norm(C);
  348.     if (Den != 0.0)
  349.         {
  350.         OldReal = Real;
  351.         Real = (Real * C.Real + Imag * C.Imag) / Den;
  352.         Imag = (Imag * C.Real - OldReal * C.Imag) / Den;
  353.         }
  354.     else
  355.         Complex::ErrorHandler();
  356.     return *this;
  357.     }
  358. // "power" methods
  359. Complex pow(const Complex & C, const Complex & Power)
  360.     {è    Complex Result;
  361.     if (Power.Real == 0.0 && Power.Imag == 0.0)
  362.         {
  363.         Result.Real = 1.0;
  364.         Result.Imag = 0.0;
  365.         }
  366.     else
  367.         {
  368.         if (C.Real != 0.0 || C.Imag != 0.0)
  369.             Result = exp(log(C) * Power);
  370.         else
  371.             Complex::ErrorHandler();
  372.         }
  373.     return Result;
  374.     }
  375. Complex sqrt(const Complex & C)
  376.     {
  377.     Complex Result;
  378.     double r, i, ratio, w;
  379.     if (C.Real != 0.0 || C.Imag != 0.0)
  380.         {
  381.         r = C.Real < 0.0 ? -C.Real : C.Real;
  382.         i = C.Imag < 0.0 ? -C.Imag : C.Imag;
  383.         if (r > i)
  384.             {
  385.             ratio = i / r;
  386.             w = sqrt(r) * sqrt(0.5 * (1.0 + sqrt(1.0 + ratio * ratio)));
  387.             }
  388.         else
  389.             {
  390.             ratio = r / i;
  391.             w = sqrt(i) * sqrt(0.5 * (ratio + sqrt(1.0 + ratio * ratio)));
  392.             }
  393.         if (C.Real > 0)
  394.             {
  395.             Result.Real = w;
  396.             Result.Imag = C.Imag / (2.0 * w);
  397.             }
  398.         else
  399.             {
  400.             Result.Imag = (C.Imag > 0.0) ? w : - w;
  401.             Result.Real = C.Imag / (2.0 * Result.Imag);
  402.             }
  403.         }
  404.     else
  405.         Complex::ErrorHandler();
  406.     return Result;
  407.     }
  408. // output method
  409. ostream & operator << (ostream & Output, const Complex & C)
  410.     {
  411.     Output << form("(%+1g%+1gi)",C.Real,C.Imag);
  412.     return Output;
  413.     }
  414. istream & operator >> (istream & Input, Complex & C)è    {
  415.     char Ch;
  416.     C.Real = 0.0;
  417.     C.Imag = 0.0;
  418.     Input >> Ch;
  419.     if (Ch == '(')
  420.         {
  421.         Input >> C.Real >> Ch;
  422.         if (Ch == ',')
  423.             Input >> C.Imag >> Ch;
  424.         if (Ch != ')')
  425.             Input.clear(_bad);
  426.         }
  427.     else
  428.         {
  429.         Input.putback(Ch);
  430.         Input >> C.Real;
  431.         }
  432.     return Input;
  433.     }
  434.  
  435.  
  436. [LISTING THREE]
  437.  
  438. //  Program:    Biomorph    (Generate non-standard fractals)
  439. //  Version:    1.01        31-Oct-1989
  440. //  Language:   C++ 2.0;  Environ:  Any;  Compilers:  Zortech C++ 2.01
  441. //  Purpose:    Generates fractals based on complex number formula iterations
  442. //  Written by: Scott Robert Ladd, 705 West Virginia, Gunnison CO 81230
  443. //              BBS (303)641-6438;  FidoNet 1:104/708
  444.  
  445. #include "conio.h"
  446. #include "zg_lwlvl.h"
  447. #include "complex.hpp"
  448.  
  449. Complex C, Z, Power;
  450. double Range, Xinc, Yinc, Xmax, Ymax, Xorig, Yorig;
  451. int X, Y, I, Iterations, Species;
  452.  
  453. void GetParams();
  454. int  main();
  455.  
  456. void GetParams()
  457.     {
  458.     cout << "Biomorph 1.01 -- a complex-plane fractal generator\n";
  459.     cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
  460.  
  461.     cout << "This program generates these species of biomorphs...\n";
  462.     cout << "  Species 0: Z^X + C         Species 1: sin(Z) + exp(Z) + C\n";
  463.     cout << "  Species 2: Z^Z + Z^X + C   Species 3: sin(Z) + Z^X + C\n\n";
  464.     do  {
  465.         cout << "What species of biomorph do you want (0..3)? ";
  466.         cin  >> Species;
  467.         }
  468.     while ((Species < 0) || (Species > 3));
  469.     cout << "\nNow we need one or two complex numbers. These can be entered\n";
  470.     cout << "in the following formats (where 'f' indicates a floating-point\n";
  471.     cout << "value:\n";
  472.     cout << "   f -or- (f) (just a real number)\n";
  473.     cout << "   (f,f)      (entering both the real and imaginary parts)\n\n";
  474.     if (Species != 1)
  475.         {
  476.         cout << "Enter the complex power applied to Z: ";
  477.         cin  >> Power;
  478.         }
  479.     cout << "Enter the complex constant C: ";
  480.     cin  >> C;
  481.     cout << "\nNext two numbers are floating point values representing the\n";
  482.     cout << "origin point on the complex plane of the area being viewed.\n\n";
  483.     cout << "Enter the X location of the center of the picture: ";
  484.     cin  >> Xorig;
  485.     cout << "Enter the Y location of the center of the picture: ";
  486.     cin  >> Yorig;
  487.     cout << "\nNext number represents the distance the graph extends away\n";
  488.     cout << "from the above origin.\n\n";
  489.     cout << "Enter the range of the graph: ";
  490.     cin  >> Range;
  491.     cout << "\nFinally, how many iterations should the program perform? ";
  492.     cin  >> Iterations;
  493.     }
  494.  
  495. int main()
  496.     {
  497.     GetParams();
  498.     if (ZG_Init()) return 1;
  499.     if (ZG_SetMode(ZG_MOD_BESTRES)) return 2;
  500.     Ymax  = ZG_VideoInfo.Ylength;
  501.     Xmax  = Ymax / (1.33333333 * Ymax / ZG_VideoInfo.Xwidth);
  502.     Xinc  = 2.0 * Range / Xmax;
  503.     Yinc  = 2.0 * Range / Ymax;
  504.     Range = -Range;
  505.     for (X = 0; X < Xmax; ++X)
  506.         {
  507.         for (Y = 0; Y < Ymax; ++Y)
  508.             {
  509.             Z = Complex((Range + Xinc * X + Xorig),(Range + Yinc * Y + Yorig));
  510.             for (I = 0; I < Iterations; ++I)
  511.                 {
  512.                 switch (Species)
  513.                     {
  514.                     case 0 :
  515.                         Z = pow(Z,Power) + C;
  516.                         break;
  517.                     case 1:
  518.                         Z = sin(Z) + exp(Z) + C;
  519.                         break;
  520.                     case 2:
  521.                         Z = pow(Z,Z) + pow(Z,Power) + C;
  522.                         break;
  523.                     case 3:
  524.                         Z = sin(Z) + pow(Z,Power) + C;
  525.                         break;
  526.                     }
  527.                 if ((abs(real(Z)) >= 10.0) || (abs(imag(Z)) >= 10.0)
  528.                 || (norm(Z) >= 100.0))
  529.                     break;
  530.                 }
  531.             if ((abs(real(Z)) < 10.0) ||  (abs(imag(Z)) < 10.0))
  532.                 ZG_PlotPixel(X,Y,0);
  533.             else
  534.                 ZG_PlotPixel(X,Y,ZG_VideoInfo.NoColors - 1);
  535.             if (kbhit()) break;
  536.             }
  537.         if (kbhit()) break;
  538.         }
  539.     while (!kbhit()) ;
  540.     if (!getch()) getch();
  541.     ZG_Done();
  542.     return 0;
  543.     }
  544.