home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / UTILS / FORMLA / CALC.CPP < prev    next >
C/C++ Source or Header  |  1992-11-16  |  5KB  |  196 lines

  1. // Copyright 1992    Mark T. Pflaging
  2.  
  3. // Sorry about the lack of documentation here.
  4. // Change the #defines below to change the output.
  5. // Output will be in formula.plg.
  6. // NOTES: added by Jerry Isdale 11/16/92
  7. //   this program may create non-planar polygons.
  8. //   such polys can cause visibility problems in most renderers
  9. //   To use this program you alter the FORUMLA string for the
  10. //   equation you wish to create.
  11.  
  12. // Can you "guess" which formulae correspond to which .PLG files? :-)
  13. #define FORMULA      z = -10 * (sin(x) * sin(y)) / (x * y)
  14. // #define FORMULA      z = (-12*y)/(x*x + y*y + 1)
  15. // #define FORMULA      z = (sin(x) + sin(y));
  16. #define XRANGE_MIN -10 
  17. #define XRANGE_MAX 10
  18. #define XDIVISIONS 20
  19.  
  20. #define YRANGE_MIN -10 
  21. #define YRANGE_MAX 10
  22. #define YDIVISIONS 20
  23.  
  24. #define TOP_COLOR "0x11FF"
  25. #define BOTTOM_COLOR "0x22AA"
  26.  
  27. #include <math.h>
  28. #include <stdlib.h>
  29. #include <fstream.h>
  30. #include <iomanip.h>
  31.  
  32. class Vertex
  33. {
  34.     double x_val, y_val, z_val;
  35. public:
  36.     Vertex() {}
  37.     Vertex(double xarg, double yarg, double zarg) : x_val(xarg), y_val(yarg), z_val(zarg) {}
  38.     double x() { return x_val; }
  39.     double y() { return y_val; }
  40.     double z() { return z_val; }
  41.     void scale(double factor) {
  42.         x_val *= factor;
  43.         y_val *= factor;
  44.         z_val *= factor;
  45.     }
  46. };
  47.  
  48. ostream & operator << (ostream & s, Vertex & m)
  49. {
  50.     s << (int)(m.x()) << ".0 " << (int)(m.y()) << ".0 " << (int)(m.z()) << ".0" << endl;
  51.     return s;
  52. }
  53.  
  54. typedef enum { False = 0, True } Boolean;
  55.  
  56. class PlgObject
  57. {
  58.     Vertex * data;
  59.     int index;
  60.     int numpoints;
  61.     int xsize;
  62.     int ysize;
  63.  
  64.     void set_xy(int xsize_arg, int ysize_arg){
  65.         xsize = xsize_arg;
  66.         ysize = ysize_arg;
  67.     }
  68.  
  69. public:
  70.     PlgObject(int numpoints_arg) : index(0), numpoints(numpoints_arg) {
  71.         data = new Vertex[numpoints];
  72.     }
  73.     PlgObject(int x_size, int y_size) : index(0), numpoints((x_size + 1) * (y_size + 1)) {
  74.         set_xy(x_size, y_size);
  75.         data = new Vertex[numpoints];
  76.     }
  77.     void add(Vertex & arg) {
  78.         if (index > numpoints) {
  79.             cout << "Out of space!!" << endl;
  80.         }
  81.         data[index] = arg;
  82.         index ++;
  83.     }
  84.     ostream & dump(ostream & where, char *color1, char * color2);
  85. };
  86.  
  87. ostream & PlgObject::dump(ostream & where, char *color1, char * color2) {
  88.     where << "formula " << ((xsize + 1) * (ysize + 1)) << " " << (xsize * ysize * 2) << endl;
  89.     for (int i = 0; i < index; i ++) {
  90.         where << data[i];
  91.     }
  92.     where << endl;
  93.  
  94.     for (int x = 0; x < xsize; x ++) {
  95.         for (int y = 0; y < ysize; y ++) {
  96.             where << color1 << " 4 ";
  97.             int base = x * (xsize + 1) + y;
  98.             where << base + ysize + 1 << " "
  99.                 << base + ysize + 2 << " "
  100.                 << base + 1 << " " << base << endl;
  101.         }
  102.     }
  103.     for (x = 0; x < xsize; x ++) {
  104.         for (int y = 0; y < ysize; y ++) {
  105.             where << color2 << " 4 ";
  106.             int base = x * (xsize + 1) + y;
  107.             where << base << " " << base + 1
  108.                 << " " << base + ysize + 2
  109.                 << " " << base + ysize + 1
  110.                 << endl;
  111.         }
  112.     }
  113.     where << endl;
  114.  
  115.     return where;
  116. }
  117.  
  118. class Range;
  119.  
  120. typedef void (*rangeFunc)(Range &, void *);
  121.  
  122. class Range
  123. {
  124.     int steps;
  125.     double l_min;
  126.     double l_max;
  127.     double stepSize;
  128.     double i;
  129.  
  130. public:
  131.     Range(double minarg, double maxarg, double steparg)
  132.         : steps(steparg), l_min(minarg), l_max(maxarg) {
  133.         stepSize = (l_max-l_min)/((double)steps);
  134.     };
  135.     static void func_do(Range & here, rangeFunc func, void * user_ptr);
  136.     double value() { return i; }
  137. };
  138.  
  139. void Range::func_do(Range & here, rangeFunc func, void * user_ptr)
  140. {
  141.     for (here.i = here.l_min; here.i <= here.l_max; here.i += here.stepSize) {
  142.         func(here, user_ptr);
  143.     }
  144. }
  145.  
  146. class Tuple3 {
  147.     void * first_var, * second_var, * third_var;
  148. public:
  149.     Tuple3(void * first_arg = NULL, void * second_arg = NULL,
  150.         void * third_arg = NULL) :
  151.         first_var(first_arg), second_var(second_arg),
  152.         third_var(third_arg) {}
  153.     void * first() { return first_var; }
  154.     void * second() { return second_var; }
  155.     void * third() { return third_var; }
  156. };
  157.  
  158. void sub_do(Range &here, void *user_ptr)
  159. {
  160. //      double x = here.value();
  161.     Tuple3 * prev = (Tuple3 *)user_ptr;
  162.     double temp = here.value();
  163.     Tuple3 aux((void *)(&temp), prev->third(), user_ptr);
  164.     Range::func_do(*((Range *)(prev->first())), (rangeFunc)(prev->second()), (void *)(&aux));
  165. }
  166.  
  167. void formula(Range &here, void *user_ptr)
  168. {
  169.     Tuple3 & aux = *((Tuple3 *) user_ptr);
  170.     Tuple3 & main_user_ptr = *((Tuple3 *)aux.third());
  171.     PlgObject &result = *((PlgObject *)main_user_ptr.third());
  172.     double x = *((double *)(aux.first()));
  173.     double y = here.value();
  174.     if (x == 0.0) x = 0.001;
  175.     if (y == 0.0)
  176.         y = 0.001;
  177.  
  178.     double FORMULA;
  179.     Vertex one_point(x, y, z);
  180.     one_point.scale(100);
  181.     result.add(one_point);
  182. //      result.dump(cout);
  183. }
  184.  
  185. main()
  186. {
  187.     ofstream myout("formula.plg");
  188.     Range Xrange(XRANGE_MIN, XRANGE_MAX, XDIVISIONS);
  189.     Range Yrange(YRANGE_MIN, YRANGE_MAX, YDIVISIONS);
  190.     PlgObject result(XDIVISIONS, YDIVISIONS);
  191.     Tuple3 container ((void *)&Yrange, formula, (void *)&result);
  192.     Range::func_do(Xrange, sub_do, (void *)(&container));
  193.     result.dump(myout, TOP_COLOR, BOTTOM_COLOR);
  194.     return 0;
  195. }
  196.