_EXAMINING ZORTECH C++ 2.0_ by Scott Robert Ladd [LISTINÇ ONE] // Header: Complex // Version: 2.00 28-Oct-1989 // Language: C++ 2.0; Environ: Any; Compilers: Zortech C++ 2.01 // Purpose: Provides the class "Complex" for C++ programs. The majority // of the class is implemented inline for efficiency. Only // the division, power, and i/o methods are actual functions. // Written by: Scott Robert Ladd, 705 West Virginia, Gunnison CO 81230 // BBS (303)641-6438; FidoNet 1:104/708 #if !defined(__COMPLEX_HPP) #define __COMPLEX_HPP 1 #include "stream.hpp" #include "math.h" class Complex { private: double Real; // Real part double Imag; // Imaginary part static void (* ErrorHandler)(); public: // constructors Complex (void); Complex (const Complex & C); Complex (double & R, double & I); Complex (double & R); // method to set error handler function static void SetErrorHandler(void (* UserHandler)()); // value extraction methods friend double real(const Complex & C); friend double imag(const Complex & C); // assignment methods void operator = (const Complex & C); void operator = (double & R); // unary minus method Complex operator - (); // calculation methods friend Complex operator + (const Complex & C1, const Complex &C2); friend Complex operator - (const Complex & C1, const Complex &C2); friend Complex operator * (const Complex & C1, const Complex &C2); friend Complex operator / (const Complex & C1, const Complex &C2); Complex operator += (const Complex & C); Complex operator -= (const Complex & C); Complex operator *= (const Complex & C); Complex operator /= (const Complex & C); // comparison methods friend int operator == (const Complex & C1, const Complex & C2); friend int operator != (const Complex & C1, const Complex & C2); friend int operator < (const Complex & C1, const Complex & C2); friend int operator <= (const Complex & C1, const Complex & C2); friend int operator > (const Complex & C1, const Complex & C2); friend int operator >= (const Complex & C1, const Complex & C2); // utility methods friend double abs(const Complex & C); friend double norm(const Complex & C); friend double arg(const Complex & C); // polar coordinate methods friend Complex polar(double Radius, double Theta = 0.0); friend Complex conj(const Complex & C); // trigonometric methods friend Complex cos(const Complex & C); friend Complex sin(const Complex & C); friend Complex tan(const Complex & C); friend Complex cosh(const Complex & C); friend Complex sinh(const Complex & C); friend Complex tanh(const Complex & C); // logarithmic methods friend Complex exp(const Complex & C); friend Complex log(const Complex & C); // "power" methods friend Complex pow(const Complex & C, const Complex & Power); friend Complex sqrt(const Complex & C); // output method friend ostream & operator << (ostream & Output, const Complex & C); friend istream & operator >> (istream & Input, Complex & C); }; // constructors inline Complex::Complex (void) { Real = 0.0; Imag = 0.0; } inline Complex::Complex (const Complex & C) { Real = C.Real; Imag = C.Imag; } inline Complex::Complex (double & R, double & I) { Real = R; Imag = I; } inline Complex::Complex (double & R) { Real = R; Imag = 0.0; } inline void Complex::SetErrorHandler(void (* UserHandler)()) { ErrorHandler = UserHandler; } // value extraction methods inline double real (const Complex & C) { return C.Real; } inline double imag (const Complex & C) { return C.Imag; } // assignment method inline void Complex::operator = (const Complex & C) { Real = C.Real; Imag = C.Imag; } inline void Complex::operator = (double & R) { Real = R; Imag = 0.0; } // unary minus method inline Complex Complex::operator - () { Complex Result; Result.Real = -Real; Result.Imag = -Imag; return Result; } // calculation methods inline Complex operator + (const Complex & C1, const Complex &C2) { Complex Result; Result.Real = C1.Real + C2.Real; Result.Imag = C1.Imag + C2.Imag; return Result; } inline Complex operator - (const Complex & C1, const Complex &C2) { Complex Result; Result.Real = C1.Real - C2.Real; Result.Imag = C1.Imag - C2.Imag; return Result; } inline Complex operator * (const Complex & C1, const Complex &C2) { Complex Result; Result.Real = (C1.Real * C2.Real) - (C1.Imag * C2.Imag); Result.Imag = (C1.Real * C2.Imag) + (C1.Imag * C2.Real); return Result; } inline Complex Complex::operator += (const Complex &C) { Real += C.Real; Imag += C.Imag; return *this; } inline Complex Complex::operator -= (const Complex &C) { Real -= C.Real; Imag -= C.Imag; return *this; } inline Complex Complex::operator *= (const Complex &C) { double OldReal; OldReal = Real; // save old Real value Real = (Real * C.Real) - (Imag * C.Imag); Imag = (OldReal * C.Imag) + (Imag * C.Real); return *this; } // comparison methods inline int operator == (const Complex & C1, const Complex & C2) { return (C1.Real == C2.Real) && (C1.Imag == C2.Imag); } inline int operator != (const Complex & C1, const Complex & C2) { return (C1.Real != C2.Real) || (C1.Imag != C2.Imag); } inline int operator < (const Complex & C1, const Complex & C2) { return abs(C1) < abs(C2); } inline int operator <= (const Complex & C1, const Complex & C2) { return abs(C1) <= abs(C2); } inline int operator > (const Complex & C1, const Complex & C2) { return abs(C1) > abs(C2); } inline int operator >= (const Complex & C1, const Complex & C2) { return abs(C1) >= abs(C2); } // utility methods inline double abs(const Complex & C) { double Result; Result = sqrt(C.Real * C.Real + C.Imag * C.Imag); return Result; } inline double norm(const Complex & C) { double Result; Result = (C.Real * C.Real) + (C.Imag * C.Imag); return Result; } inline double arg(const Complex & C) { double Result; Result = atan2(C.Imag, C.Real); return Result; } // polar coordinate methods inline Complex polar(double Radius, double Theta) { Complex Result; Result.Real = Radius * cos(Theta); Result.Imag = Radius * sin(Theta); return Result; } inline Complex conj(const Complex & C) { Complex Result; Result.Real = C.Real; Result.Imag = -C.Imag; return Result; } // trigonometric methods inline Complex cos(const Complex & C) { Complex Result; Result.Real = cos(C.Real) * cosh(C.Imag); Result.Imag = -sin(C.Real) * sinh(C.Imag); return Result; } inline Complex sin(const Complex & C) { Complex Result; Result.Real = sin(C.Real) * cosh(C.Imag); Result.Imag = cos(C.Real) * sinh(C.Imag); return Result; } inline Complex tan(const Complex & C) { Complex Result; Result = sin(C) / cos(C); return Result; } inline Complex cosh(const Complex & C) { Complex Result; Result = cos(C.Imag) * cosh(C.Real); Result = sin(C.Imag) * sinh(C.Real); return Result; } inline Complex sinh(const Complex & C) { Complex Result; Result.Real = cos(C.Imag) * sinh(C.Real); Result.Imag = sin(C.Imag) * cosh(C.Real); return Result; } inline Complex tanh(const Complex & C) { Complex Result; Result = sinh(C) / cosh(C); return Result; } // logarithmic methods inline Complex exp(const Complex & C) { Complex Result; double X = exp(C.Real); Result.Real = X * cos(C.Imag); Result.Imag = X * sin(C.Imag); return Result; } inline Complex log(const Complex & C) { Complex Result; double Hypot = abs(C); if (Hypot > 0.0) { Result.Real = log(Hypot); Result.Imag = atan2(C.Imag, C.Real); } else Complex::ErrorHandler(); return Result; } #endif // __Complex_HPP [LISTIÎÇ TWO] // Module: Complex // Version: 2.00 28-Oct-1989 // Language: C++ 2.0; Environ: Any; Compilers: Zortech C++ 2.01 // Purpose: Provides the class "Complex" for C++ programs. The majority // of the class is implemented inline for efficiency. Only // the division, power, and i/o methods are actual functions. // Written by: Scott Robert Ladd, 705 West Virginia, Gunnison CO 81230 // BBS (303)641-6438; FidoNet 1:104/708 #include "math.h" #include "stdlib.h" #include "Complex.hpp" #include "stream.hpp" static void DefaultHandler(); void (* Complex::ErrorHandler)() = DefaultHandler; static void DefaultHandler() { cout << "\aERROR in complex object: DIVIDE BY ZERO\n"; exit(1); } // division methods Complex operator / (const Complex & C1, const Complex & C2) { Complex Result; double Den; Den = norm(C2); if (Den != 0.0) { Result.Real = (C1.Real * C2.Real + C1.Imag * C2.Imag) / Den; Result.Imag = (C1.Imag * C2.Real - C1.Real * C2.Imag) / Den; } else Complex::ErrorHandler(); return Result; } Complex Complex::operator /= (const Complex & C) { double Den, OldReal; Den = norm(C); if (Den != 0.0) { OldReal = Real; Real = (Real * C.Real + Imag * C.Imag) / Den; Imag = (Imag * C.Real - OldReal * C.Imag) / Den; } else Complex::ErrorHandler(); return *this; } // "power" methods Complex pow(const Complex & C, const Complex & Power) { Š Complex Result; if (Power.Real == 0.0 && Power.Imag == 0.0) { Result.Real = 1.0; Result.Imag = 0.0; } else { if (C.Real != 0.0 || C.Imag != 0.0) Result = exp(log(C) * Power); else Complex::ErrorHandler(); } return Result; } Complex sqrt(const Complex & C) { Complex Result; double r, i, ratio, w; if (C.Real != 0.0 || C.Imag != 0.0) { r = C.Real < 0.0 ? -C.Real : C.Real; i = C.Imag < 0.0 ? -C.Imag : C.Imag; if (r > i) { ratio = i / r; w = sqrt(r) * sqrt(0.5 * (1.0 + sqrt(1.0 + ratio * ratio))); } else { ratio = r / i; w = sqrt(i) * sqrt(0.5 * (ratio + sqrt(1.0 + ratio * ratio))); } if (C.Real > 0) { Result.Real = w; Result.Imag = C.Imag / (2.0 * w); } else { Result.Imag = (C.Imag > 0.0) ? w : - w; Result.Real = C.Imag / (2.0 * Result.Imag); } } else Complex::ErrorHandler(); return Result; } // output method ostream & operator << (ostream & Output, const Complex & C) { Output << form("(%+1g%+1gi)",C.Real,C.Imag); return Output; } istream & operator >> (istream & Input, Complex & C) Š { char Ch; C.Real = 0.0; C.Imag = 0.0; Input >> Ch; if (Ch == '(') { Input >> C.Real >> Ch; if (Ch == ',') Input >> C.Imag >> Ch; if (Ch != ')') Input.clear(_bad); } else { Input.putback(Ch); Input >> C.Real; } return Input; } [LISTING THREE] // Program: Biomorph (Generate non-standard fractals) // Version: 1.01 31-Oct-1989 // Language: C++ 2.0; Environ: Any; Compilers: Zortech C++ 2.01 // Purpose: Generates fractals based on complex number formula iterations // Written by: Scott Robert Ladd, 705 West Virginia, Gunnison CO 81230 // BBS (303)641-6438; FidoNet 1:104/708 #include "conio.h" #include "zg_lwlvl.h" #include "complex.hpp" Complex C, Z, Power; double Range, Xinc, Yinc, Xmax, Ymax, Xorig, Yorig; int X, Y, I, Iterations, Species; void GetParams(); int main(); void GetParams() { cout << "Biomorph 1.01 -- a complex-plane fractal generator\n"; cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; cout << "This program generates these species of biomorphs...\n"; cout << " Species 0: Z^X + C Species 1: sin(Z) + exp(Z) + C\n"; cout << " Species 2: Z^Z + Z^X + C Species 3: sin(Z) + Z^X + C\n\n"; do { cout << "What species of biomorph do you want (0..3)? "; cin >> Species; } while ((Species < 0) || (Species > 3)); cout << "\nNow we need one or two complex numbers. These can be entered\n"; cout << "in the following formats (where 'f' indicates a floating-point\n"; cout << "value:\n"; cout << " f -or- (f) (just a real number)\n"; cout << " (f,f) (entering both the real and imaginary parts)\n\n"; if (Species != 1) { cout << "Enter the complex power applied to Z: "; cin >> Power; } cout << "Enter the complex constant C: "; cin >> C; cout << "\nNext two numbers are floating point values representing the\n"; cout << "origin point on the complex plane of the area being viewed.\n\n"; cout << "Enter the X location of the center of the picture: "; cin >> Xorig; cout << "Enter the Y location of the center of the picture: "; cin >> Yorig; cout << "\nNext number represents the distance the graph extends away\n"; cout << "from the above origin.\n\n"; cout << "Enter the range of the graph: "; cin >> Range; cout << "\nFinally, how many iterations should the program perform? "; cin >> Iterations; } int main() { GetParams(); if (ZG_Init()) return 1; if (ZG_SetMode(ZG_MOD_BESTRES)) return 2; Ymax = ZG_VideoInfo.Ylength; Xmax = Ymax / (1.33333333 * Ymax / ZG_VideoInfo.Xwidth); Xinc = 2.0 * Range / Xmax; Yinc = 2.0 * Range / Ymax; Range = -Range; for (X = 0; X < Xmax; ++X) { for (Y = 0; Y < Ymax; ++Y) { Z = Complex((Range + Xinc * X + Xorig),(Range + Yinc * Y + Yorig)); for (I = 0; I < Iterations; ++I) { switch (Species) { case 0 : Z = pow(Z,Power) + C; break; case 1: Z = sin(Z) + exp(Z) + C; break; case 2: Z = pow(Z,Z) + pow(Z,Power) + C; break; case 3: Z = sin(Z) + pow(Z,Power) + C; break; } if ((abs(real(Z)) >= 10.0) || (abs(imag(Z)) >= 10.0) || (norm(Z) >= 100.0)) break; } if ((abs(real(Z)) < 10.0) || (abs(imag(Z)) < 10.0)) ZG_PlotPixel(X,Y,0); else ZG_PlotPixel(X,Y,ZG_VideoInfo.NoColors - 1); if (kbhit()) break; } if (kbhit()) break; } while (!kbhit()) ; if (!getch()) getch(); ZG_Done(); return 0; }