[ILUG] Data structures, typedefs, arrays and OpenGL?
David Neary
dneary at wanadoo.fr
Wed May 29 22:09:03 IST 2002
John Gay wrote:
[snip 50 lines or so]
> Lets get the basis of my requirements laid out first:
That's some definition of first ;-)
> I'm trying to create data structures that can contain a full description of
> an N-Dimensional object. The data structures need to be recursive and dynamic
> so that the objects can be combined into higher dimensional objects. To
> illustrate this, I'll start from the bottom-up.
OK - it's a fairly complicated idea but I see where you're going.
> N = an unknown number of dimensions.
>
> Where N = 0, I.E. 0-Dimensional objects, we have the vertices, defined as an
> array of GLfloats. The size of the array depends, of course, on how many
> dimensions the final object is.
You can have a k-dimensional object in N dimensional space where
k<N (say, a plane in 3-D space, or a line in 4-D space) - so it
depends more on how many dimensions the space is. But that's
neither here nor there :)
For something of variable size, an array is a bad idea (imho). OK
variable length arrays are defined in the newest C standard, but
they're not in common use. The normal way to do this would be to
either dynamically allocate the space, or use a list.
> Where N = 2 we have 2-D surfaces. A 2-D surface has to point to a random
> number of lines that outline the surface. It would be simple if the lines
> arranged the vertices in a counter-clockwise order, but this is not possible
> unless we define each line twice to allow for either direction and that would
> result in not only excess data, but twice the processing as well.
A 2d plane is defined by 3 p[oints, as long as they're not
colinear. But if you also want shapes, then you're into more
complicated stuff. Scary, in fact :) Easier if it's a list of
vertices where the last vertex points at the first - in that way,
you're extending the idea of a line, and keeping wor down for
yourself. For example, the unit square on the plane would be just
(0,0)->(1,0)->(1,1)->(0,1)->(0,0) (or just ->NULL to show you're
finished).
Ah. Just realised that when you're talking about lines, you're
really talking about line segments. Right.
> Where N = 3 we have 3-D surfaces. A 3-D surface has to point to a random
> number of 2-D surfaces that outline the 3-D surface. You can see that as we
> go high in dimensions, this description becomes recursive.
Extending the "list of vertices" we can go into N dimensions -
all we need to do is have a path around the object which visits
every vertex, and crosses every edge. (OK, when I say "all we
need to do", I'm simplifying). I have trouble seeing how your
scheme can describe any 3-d object. How would you d4escribe the
unit cube in 3d space, for example?
> As a (possibly false) start, using my references I tried to get an idea of
> how the definitions would go.
>
> typedef GLfloat Vertice4[4];
>
> struct line {
> Veritce4 *left;
> Vertice4 *right;
> };
>
> typedef struct line Line;
> typedef Line *LinePtr;
I would advise against this one strongly - the pointer
indirection is useful in the declaration of a variable. There's
no problem with declaring something as
Line *myline;
instead of
LinePtr myline;
in fact, doing so saves typing, and is clearer (to my mind). No
need to pollute the namespace.
> So, I typedef Vertice4 as an array of 4 GLfloats,
> I create a structure, line that can point to two Vertice4's,
> I typedef Line as a struct line and LinePtr as a pointer to a line struct.
How about something along the lines of the following -
struct vertex {
int dim;
GLFloat *coord;
};
typedef struct vertex Vertex; /* If you really wanted to */
which would have an init function something like this...
Vertex *vertex_new(int dim, ...)
{
Vertex *vertex;
int i;
va_list varargs;
va_start(varargs, dim);
vertex = malloc(sizeof (Vertex));
vertex->dim = dim;
vertex->coords = malloc(dim*sizeof(GLFloat)
for( i=0; i<dim; i++)
{
vertex->coords[i] = va_arg(varags, GLFloat);
}
return vertex;
}
which you'd use pretty much as you'd expect -
Vertex *v;
v = vertex_new(3, 1.0, 1.0, 1.0); /* For point (1,1,1) in 3d
* space */
and moves nicely up to the next dimension, as you say -
struct line {
Vertex *vertices; /* Array of vertices */
};
and surfaces
struct surface {
Vertex *vertices; /* Bounding vertices */
};
But I see that you want to go the iterative route - a line
defined by 2 points, a shape defined by a number of lines, a
space defined by a number of surfaces, and so on... I think
something like this might work. I haven't thought about it at
all, though. And to be this generic you have to be horribly hard
to program :)
struct object {
int dim; /* Current dimension of object - 1 for line, 2 for
surface, etc */
union {
struct object *subobjects; /* list of n-1 dim objects for n>=1 */
Vertex *vertices; /* vertices for n=0 */
} data;
};
This is a horrible thing to manage though. I can't see how you'd
allocate space for them, never mind manipulate them. Being honest
I didn't really follow your requirements, and this has been kind
of stream-of-consciousness stuff, but worse than Joyce. I hope
there's something useful in it, at least.
Cheers,
Dave.
--
David Neary,
Marseille, France
E-Mail: bolsh at gimp.org
More information about the ILUG
mailing list