home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
REND386
/
UTILS
/
FORMLA
/
CALC.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-16
|
5KB
|
196 lines
// Copyright 1992 Mark T. Pflaging
// Sorry about the lack of documentation here.
// Change the #defines below to change the output.
// Output will be in formula.plg.
// NOTES: added by Jerry Isdale 11/16/92
// this program may create non-planar polygons.
// such polys can cause visibility problems in most renderers
// To use this program you alter the FORUMLA string for the
// equation you wish to create.
// Can you "guess" which formulae correspond to which .PLG files? :-)
#define FORMULA z = -10 * (sin(x) * sin(y)) / (x * y)
// #define FORMULA z = (-12*y)/(x*x + y*y + 1)
// #define FORMULA z = (sin(x) + sin(y));
#define XRANGE_MIN -10
#define XRANGE_MAX 10
#define XDIVISIONS 20
#define YRANGE_MIN -10
#define YRANGE_MAX 10
#define YDIVISIONS 20
#define TOP_COLOR "0x11FF"
#define BOTTOM_COLOR "0x22AA"
#include <math.h>
#include <stdlib.h>
#include <fstream.h>
#include <iomanip.h>
class Vertex
{
double x_val, y_val, z_val;
public:
Vertex() {}
Vertex(double xarg, double yarg, double zarg) : x_val(xarg), y_val(yarg), z_val(zarg) {}
double x() { return x_val; }
double y() { return y_val; }
double z() { return z_val; }
void scale(double factor) {
x_val *= factor;
y_val *= factor;
z_val *= factor;
}
};
ostream & operator << (ostream & s, Vertex & m)
{
s << (int)(m.x()) << ".0 " << (int)(m.y()) << ".0 " << (int)(m.z()) << ".0" << endl;
return s;
}
typedef enum { False = 0, True } Boolean;
class PlgObject
{
Vertex * data;
int index;
int numpoints;
int xsize;
int ysize;
void set_xy(int xsize_arg, int ysize_arg){
xsize = xsize_arg;
ysize = ysize_arg;
}
public:
PlgObject(int numpoints_arg) : index(0), numpoints(numpoints_arg) {
data = new Vertex[numpoints];
}
PlgObject(int x_size, int y_size) : index(0), numpoints((x_size + 1) * (y_size + 1)) {
set_xy(x_size, y_size);
data = new Vertex[numpoints];
}
void add(Vertex & arg) {
if (index > numpoints) {
cout << "Out of space!!" << endl;
}
data[index] = arg;
index ++;
}
ostream & dump(ostream & where, char *color1, char * color2);
};
ostream & PlgObject::dump(ostream & where, char *color1, char * color2) {
where << "formula " << ((xsize + 1) * (ysize + 1)) << " " << (xsize * ysize * 2) << endl;
for (int i = 0; i < index; i ++) {
where << data[i];
}
where << endl;
for (int x = 0; x < xsize; x ++) {
for (int y = 0; y < ysize; y ++) {
where << color1 << " 4 ";
int base = x * (xsize + 1) + y;
where << base + ysize + 1 << " "
<< base + ysize + 2 << " "
<< base + 1 << " " << base << endl;
}
}
for (x = 0; x < xsize; x ++) {
for (int y = 0; y < ysize; y ++) {
where << color2 << " 4 ";
int base = x * (xsize + 1) + y;
where << base << " " << base + 1
<< " " << base + ysize + 2
<< " " << base + ysize + 1
<< endl;
}
}
where << endl;
return where;
}
class Range;
typedef void (*rangeFunc)(Range &, void *);
class Range
{
int steps;
double l_min;
double l_max;
double stepSize;
double i;
public:
Range(double minarg, double maxarg, double steparg)
: steps(steparg), l_min(minarg), l_max(maxarg) {
stepSize = (l_max-l_min)/((double)steps);
};
static void func_do(Range & here, rangeFunc func, void * user_ptr);
double value() { return i; }
};
void Range::func_do(Range & here, rangeFunc func, void * user_ptr)
{
for (here.i = here.l_min; here.i <= here.l_max; here.i += here.stepSize) {
func(here, user_ptr);
}
}
class Tuple3 {
void * first_var, * second_var, * third_var;
public:
Tuple3(void * first_arg = NULL, void * second_arg = NULL,
void * third_arg = NULL) :
first_var(first_arg), second_var(second_arg),
third_var(third_arg) {}
void * first() { return first_var; }
void * second() { return second_var; }
void * third() { return third_var; }
};
void sub_do(Range &here, void *user_ptr)
{
// double x = here.value();
Tuple3 * prev = (Tuple3 *)user_ptr;
double temp = here.value();
Tuple3 aux((void *)(&temp), prev->third(), user_ptr);
Range::func_do(*((Range *)(prev->first())), (rangeFunc)(prev->second()), (void *)(&aux));
}
void formula(Range &here, void *user_ptr)
{
Tuple3 & aux = *((Tuple3 *) user_ptr);
Tuple3 & main_user_ptr = *((Tuple3 *)aux.third());
PlgObject &result = *((PlgObject *)main_user_ptr.third());
double x = *((double *)(aux.first()));
double y = here.value();
if (x == 0.0) x = 0.001;
if (y == 0.0)
y = 0.001;
double FORMULA;
Vertex one_point(x, y, z);
one_point.scale(100);
result.add(one_point);
// result.dump(cout);
}
main()
{
ofstream myout("formula.plg");
Range Xrange(XRANGE_MIN, XRANGE_MAX, XDIVISIONS);
Range Yrange(YRANGE_MIN, YRANGE_MAX, YDIVISIONS);
PlgObject result(XDIVISIONS, YDIVISIONS);
Tuple3 container ((void *)&Yrange, formula, (void *)&result);
Range::func_do(Xrange, sub_do, (void *)(&container));
result.dump(myout, TOP_COLOR, BOTTOM_COLOR);
return 0;
}