Since we want to compute a surface of revolution by rotating a curve around an axis we have to store at least the curve and the resulting triangulation. Storing the axis instead of using an implicit default axis is a good idea, additionally we will need the angle of rotation and the number of segments that should be created.
There are several ways we can implement this class. First of all we could just use Root as superclass and add a pointer to a Triang2d instance for the surface and two pointers to Triang1d instances for curve and axis to it, but we would have to implement many methods to be able to work with this class. The second possibility is to use Triang1d as superclass, in this case we would emphasize that we are working with a curve. Since we are ultimately interested in the surface we want to create the best way is probably to implement the new class Rot2d as a subclass of Triang2d.
We have added curve, axis, rotation angle, discretization and a variable to store the index of the point we are working on (this will be needed later):
#define ROT2D_STRUCT \ TRIANG2D_STRUCT; /* the superclass is Triang2d */ \ /* ROT2D */ \ TRIANG1D *curve; /* the curve that is rotated */ \ TRIANG1D *axis; /* axis for the rotation */ \ double angle; /* angle of the rotation */ \ int discr; /* number of segments to create */ \ int current /* current point for editing */ typedef struct { ROT2D_STRUCT; } ROT2D;
This definition will be put in the headerfile rot2d.h. This headerfile should include declarations like the one for our new class
and things like prototypes for the new methods and functions.extern CLASS *Rot2d;
Now our new class has to be added to GRAPE's class hierarchy. First of all we need the class pointer for Rot2d, and then we have to call "new-class". We put both into the main program in the file rotate.c (the full listing can be found in section 5.5.7):
As you can see the return value of the GRAPE call is casted to the type of the result. This cast has to be done explicitly because the GRAPE function returns an arbitrary pointer type (this should be void *, but in reality it's a char * so that you cannot ``forget'' the cast).#include <grape.h> #include "rot2d.h" CLASS *Rot2d = NULL; int main() { Rot2d = (CLASS *)GRAPE(Triang2d, "new-class")("Rot2d", sizeof(ROT2D)); ASSURE(Rot2d, "main: can't create class Rot2d", return 5); ... }
The ASSURE macro is used to test if the class could be created, it is provided for error handling and will be described in section 5.4.3.
Copyright © by the Sonderforschungsbereich 256 at the Institut für Angewandte Mathematik, Universität Bonn.