POV-Ray : Newsgroups : povray.programming : Array pointers Server Time
5 Jul 2024 16:00:35 EDT (-0400)
  Array pointers (Message 1 to 10 of 17)  
Goto Latest 10 Messages Next 7 Messages >>>
From: Reusser
Subject: Array pointers
Date: 16 Jan 2003 19:45:04
Message: <160120031840217575%reu1000@chorus.net>
Sorry since I already know this is not the best place to be posting
questions like this, but it should be relatively simple.
   I had an interpolation macro for a grid of points all set up in POV,
and I'm working on translating it into C++.   Needless to say, it
doesn't work like POV.  What is the most efficient (or at least
somewhat straightforward) way to pass any array[x][y][z] into the
function where it can be referenced like array[a][b][c] or
array[a+1][b][c]?  It works but doesn't seem efficient to just use a
pointer and &*pointer++; within the function.
   (Also, why does the line, double N = 1/3; give me .333...?  Is there
a way to accomplish this without double N = pow(3,-1);?)

 - Ricky


Post a reply to this message

From: Warp
Subject: Re: Array pointers
Date: 16 Jan 2003 20:14:43
Message: <3e275903@news.povray.org>
Reusser <reu### [at] chorusnet> wrote:
> What is the most efficient (or at least
> somewhat straightforward) way to pass any array[x][y][z] into the
> function where it can be referenced like array[a][b][c] or
> array[a+1][b][c]?

  This depends on whether x and y are compiler-time constants or not.
If they are compiler-time constants, let's say for example 5 and 8, then
you can define your function like:

void Function(type array[5][8][])
{
    array[1][2][3] = 4;
}

  However, if they are not constants then there's no way which would
be at the same time simple and efficient (mostly memory-wise, perhaps
a bit speed-wise as well).
  In this case you have to decide whether you want it to be efficient in
memory usage or if you want it to be simple.
  (In fact, it's simple only from the point of view of the function; it's
not that simple from the point of view of *creating* the array.)

  I suppose that what you want is efficiency. It's not that bad from the
point of view of the syntax.
  What you have to do is to use it simply as a 1-dimensional array and
give the dimensions as separate variables, like this:

void Function(type* array, unsigned x, unsigned y)
{
    array[x*y*1+y*2+3] = 4;
}

  The memory-wise less efficient way is to use an array of pointers to
arrays of pointers to arrays.

>    (Also, why does the line, double N = 1/3; give me .333...?  Is there
> a way to accomplish this without double N = pow(3,-1);?)

  You mean it *doesn't* give that, right?

  1 is an integer. 3 is an integer. 1/3 is thus an integer division. The
result of the integer division 1/3 is 0. As it should.
  You don't want integer division. You want floating point division.
1.0 is a floating point number, as well as 3.0. 1.0/3.0 is a floating
point division.

-- 
plane{-x+y,-1pigment{bozo color_map{[0rgb x][1rgb x+y]}turbulence 1}}
sphere{0,2pigment{rgbt 1}interior{media{emission 1density{spherical
density_map{[0rgb 0][.5rgb<1,.5>][1rgb 1]}turbulence.9}}}scale
<1,1,3>hollow}text{ttf"timrom""Warp".1,0translate<-1,-.1,2>}//  - Warp -


Post a reply to this message

From: Vadim Sytnikov
Subject: amalloc() (long post)
Date: 16 Jan 2003 20:31:22
Message: <3e275cea$1@news.povray.org>
"Reusser" <reu### [at] chorusnet> wrote:
> What is the most efficient (or at least
> somewhat straightforward) way to pass any array[x][y][z] into the
> function where it can be referenced like array[a][b][c] or
> array[a+1][b][c]?

IMHO the absolutely best way is to use something like the amalloc()
function; see below.

/* +++Date last modified: 05-Jul-1997 */

/*

AMALLOC - multi-dimensional malloc()

Allocates a multidimensional array dynamically, at runtime, so that
  1: its elements can be accessed using multiple indirection
  2: it can be deallocated using a call to the standard free() function
Note: On PC's the max array size is 64K

Paul Schlyter, 1992-02-09.  Released to the public domain.

*/

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "snparray.h"


#define MAXDIMS  5              /* Defines the maximum number of dimensions
*/
#define MAXSIZE  ((size_t) -1L) /* Maximum size of array */


void *amalloc( int esiz, void *initval, int dims, ... )
/*
 *  Input:   esiz     size of each array elements, as given by sizeof
 *           initval  pointer to initial value. NULL ==> zero fill
 *           dims     number of dimensions: 1..MAXDIMS (5)
 *           ...      number of elements in each dimension (int's)
 *
 *  Returns:  NULL    error: out of memory, or illegal parameters
 *                    otherwise base pointer to array
 */
{
      unsigned int dim[MAXDIMS], accdim[MAXDIMS];
      va_list ap;
      int i, j;
      long int totsiz;
      void **q;
      char *p, *r, *s;

      if (dims < 1  ||  dims > MAXDIMS)
            return NULL;

      memset(dim, 0, sizeof(dim));          /* Read dimension numbers */
      memset(accdim, 0, sizeof(accdim));
      va_start(ap, dims);
      dim[0] = accdim[0] = va_arg(ap,int);
      for (i = 1; i < dims; i++)
      {
            dim[i] = va_arg(ap,int);
            accdim[i] = accdim[i-1] * dim[i];
      }
      va_end(ap);

                                            /* Compute total array size */
      totsiz = esiz * accdim[dims-1];       /* Data size */

      for (i = 0; i < dims - 1; i++ )       /* Add space for pointers */
            totsiz += sizeof(void *) * accdim[i];

      if (totsiz > MAXSIZE)                 /* Exit if totsiz too large */
            return NULL;

      p = malloc((size_t) totsiz);          /* Allocate memory */
      if (p == NULL)                        /* Out-of-memory   */
            return NULL;
      memset(p, 0, (unsigned int) totsiz);  /* Zero out allocated memory */
      q = (void **) p;

      if (dims == 1)
            r = (char *) q + esiz * accdim[0];

      for (i = 1; i < dims; i++)            /* Fill in pointers */
      {
            int siz;
            int accd = accdim[i-1], d = dim[i];

            siz =  i == dims-1 ? esiz : sizeof(void *);

            r = (char *) q + sizeof(void *) * accd;
            for (j = 0; j < accd; j++)
            {
                  *q++ = r;
                  r += siz * d;
            }
      }

      if (initval != NULL)
      {
            for (s = (char *) q; s < r; s += esiz)
                  memcpy(s, initval, esiz);
      }

      return p;

}  /* amalloc */


#ifdef TEST   /* Test program */

#include <stdio.h>

main()
{
      static char init_d[8] = { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF };
      int init_i = 0x1111;
      double *a   = amalloc( sizeof(double), init_d, 1, 4 );
      double **b  = amalloc( sizeof(double), init_d, 2, 4, 5 );
      double ***c = amalloc( sizeof(double), init_d, 3, 4, 5, 6 );
      int ***d = amalloc( sizeof(int), &init_i, 3, 4, 5, 6 );
      int i, j, k;

      for (i = 0; i < 4; i++)
            for (j = 0; j < 5; j++ )
                  for (k = 0; k < 6; k++ )
                        d[i][j][k] = (i * 256) + (j * 16) + k;

      a = a, b = b, c = c;

      return 0;
}

#endif /* TEST */


Post a reply to this message

From: Edward Coffey
Subject: Re: Array pointers
Date: 16 Jan 2003 20:55:49
Message: <3E276583.6020407@alphalink.com.au>
Reusser wrote:
...
> What is the most efficient (or at least
> somewhat straightforward) way to pass any array[x][y][z] into the
> function where it can be referenced like array[a][b][c] or
> array[a+1][b][c]?  It works but doesn't seem efficient to just use a
> pointer and &*pointer++; within the function

I assume when you say "any array[x][y][z]" you mean that you don't want 
to hardcode the dimensions of the array into your program. If I'm wrong 
about that, the answer is straightforward, declare your function with 
the dimensions of the array hardcoded:
void fn(int ar[5][5][5]);
On the other hand, you may want more flexibility, so read on.

C++ has lovely 1 dimensional array handling through the 'vector' class. 
Sadly the same cannot be said for n dimensional arrays for n greater 
than 1. You have about three options:

1. Use a vector of vectors of vectors of your datatype. This will eat up 
lots of memory, probably be slow, and not give you most of the benefits 
of the vector class anyway.

2. Do as you say, passing in the base pointer of your array to the 
function, you will also need to pass in the dimensions of the array, as 
C++ isn't going to keep track of them for you. Also, you will need to do 
pointer arithmetic, you won't be able to use the [][][] notation 
Accessing the element array[x][y][z] given the dimensions a, b and c is 
thus:
*(array + x*b*c + y*c + z), you don't need the dimension 'a' in this 
calculation, but you do need it to make sure you don't go out of bounds. 
Note that it is easy to stuff up pointer arithmetic, an I probably have 
here, that's why I tend to steer clear of it. That and the fact that 
it's very ugly. Don't do this, it belongs in a C compiler, your C++ 
compiler will need to be washed thoroughly in warm soapy water after 
processing code like this.

3. The right way. Write your own three dimensional array class 
(actually, the right way is to grab such a class that someone else has 
already written). This class will be a home for the ugly pointer 
arithmetic. You'll still have it in there, but you'll do it once and do 
it right. You will also overload the [] operator to make your 
array[x][y][z] syntax possible. Here's somewhere to help you get started:
http://<site deceased>/articles/2000/0012/0012c/0012c.htm?topic=articles



> (Also, why does the line, double N = 1/3; give me .333...?

What would you expect it to give you?


Post a reply to this message

From: Reusser
Subject: Re: Array pointers
Date: 16 Jan 2003 23:28:39
Message: <160120032223572299%reu1000@chorus.net>
In article <3E2### [at] alphalinkcomau>, Edward Coffey
<eco### [at] alphalinkcomau> wrote:

> I assume when you say "any array[x][y][z]" you mean that you don't want 
> to hardcode the dimensions of the array into your program. If I'm wrong 
> about that, the answer is straightforward, declare your function with 
> the dimensions of the array hardcoded:
> void fn(int ar[5][5][5]);
> On the other hand, you may want more flexibility, so read on.

Indeed :( Flexibility is key.  I thought it would be a simple command
I'm missing, so I'll clarify what it is I need to do.  I'm basically
using C++ to parse instead of POV for obvious speed problems.  I
wouldn't know the first thing about patching POV, but writing a simple
script with output isn't a problem.  This said, I basically specify the
initial conditions of a three-dimensional array of vectors or floats (I
have the vector struct thing under control) and let it fly.  A crucial
part is the interpolation of a vector or float at an arbitrary point
within the array.  This will need to be done thousands of times to say
the least, so yes, flexibility is crucial.

> 1. Use a vector of vectors of vectors of your datatype. This will eat up 
> lots of memory, probably be slow, and not give you most of the benefits 
> of the vector class anyway.

Vector of vectors of vectors?  I wouldn't know quite how to do that,
but that doesn't sound like too much of an issue.

> 2. Do as you say, passing in the base pointer of your array to the 
> function, you will also need to pass in the dimensions of the array, as 
> ...
> compiler will need to be washed thoroughly in warm soapy water after 
> processing code like this.

With plenty of carefully written max() statements for safeguard, I
might try this since it sounds like it might be necessary.  Maybe
*(array + coords(a,b,c)) will get the job done.  Still a little
unsettling though.

> 3. The right way. Write your own three dimensional array class 
> ...
> Here's somewhere to help you get started:
> http://<site deceased>/articles/2000/0012/0012c/0012c.htm?topic=articles

I'll take a look as soon as I have time.  I know *of* the overload and
class idea, but that'll also take a little work to iron out.  I miss
plain old, slow POV...

> > (Also, why does the line, double N = 1/3; give me .333...?
> 
> What would you expect it to give you?

Whoops, I meant *doesn't*, as Warp pointed out, but I understand now. 
I guess that's why all those POV codes had a 'superfluous' 1.0 instead
of 1  (with a period to end the sentence but not to confuse the meaning
of what I said).

Thanks for all your help.  You too, Warp.  I just didn't have time to
reply to both messages tonight.

 - Ricky


Post a reply to this message

From: Edward Coffey
Subject: Re: Array pointers
Date: 17 Jan 2003 01:00:54
Message: <3E279EF5.3080108@alphalink.com.au>
Reusser wrote:
> In article <3E2### [at] alphalinkcomau>, Edward Coffey
> <eco### [at] alphalinkcomau> wrote:
<snip>
>>2. Do as you say, passing in the base pointer of your array to the 
>>function, you will also need to pass in the dimensions of the array, as 
>>...
>>compiler will need to be washed thoroughly in warm soapy water after 
>>processing code like this.
> 
> 
> With plenty of carefully written max() statements for safeguard, I
> might try this since it sounds like it might be necessary.  Maybe
> *(array + coords(a,b,c)) will get the job done.  Still a little
> unsettling though.
> 
> 
>>3. The right way. Write your own three dimensional array class 
>>...
>>Here's somewhere to help you get started:
>>http://<site deceased>/articles/2000/0012/0012c/0012c.htm?topic=articles
> 
> 
> I'll take a look as soon as I have time.  I know *of* the overload and
> class idea, but that'll also take a little work to iron out.  I miss
> plain old, slow POV...
<snip>

It sounds like you're really programming more-or-less in C, perhaps just 
using C++ for convenience, which is fine. I tend to get carried away 
with the distinction sometimes, and when someone says they're using C++ 
I assume they're doing everything in a very object-oriented manner. Your 
coords() function will help keep things a little clearer, but it will 
need to take in the second and third dimensions of your array as well as 
the three coordinates of the point you want.

Without having studied it too closely, I think Vadim's solution may 
prove to be the most convenient. I must confess, as the proud recipient 
of a shiny new Bachelor of Computer Science, this is the first time I've 
come across amalloc. Even when the question of multidimensional arrays 
came up in a C programming class, the lecturer's response was that 
pointer arithmetic was the only way. It seems that universities are so 
caught up in C++, Java and web programming that they're neglecting good 
old C.


Post a reply to this message

From: Warp
Subject: Re: Array pointers
Date: 17 Jan 2003 14:49:08
Message: <3e285e34@news.povray.org>
Reusser <reu### [at] chorusnet> wrote:
> Vector of vectors of vectors?  I wouldn't know quite how to do that,
> but that doesn't sound like too much of an issue.

  If you are really coding in C++ and not C, and you want to use the
array of pointers to arrays of pointers to arrays, then using the std::vector
class is the easiest and *safest* way.

-- 
#macro N(D)#if(D>99)cylinder{M()#local D=div(D,104);M().5,2pigment{rgb M()}}
N(D)#end#end#macro M()<mod(D,13)-6mod(div(D,13)8)-3,10>#end blob{
N(11117333955)N(4254934330)N(3900569407)N(7382340)N(3358)N(970)}//  - Warp -


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: amalloc() (long post)
Date: 17 Jan 2003 15:32:59
Message: <3e28687b@news.povray.org>
In article <3e275cea$1@news.povray.org> , "Vadim Sytnikov" <syt### [at] rucom>
wrote:

> IMHO the absolutely best way is to use something like the amalloc()
> function; see below.

The code, or at least the comments in it are totally outdated.  Obviously it
is meant for DOS:

> /* +++Date last modified: 05-Jul-1997 */
>
> /*
>
> AMALLOC - multi-dimensional malloc()
>
> Allocates a multidimensional array dynamically, at runtime, so that
>   1: its elements can be accessed using multiple indirection
>   2: it can be deallocated using a call to the standard free() function
> Note: On PC's the max array size is 64K
>
> Paul Schlyter, 1992-02-09.  Released to the public domain.



____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trfde

Visit POV-Ray on the web: http://mac.povray.org


Post a reply to this message

From: Vadim Sytnikov
Subject: Re: amalloc() (long post)
Date: 18 Jan 2003 00:36:42
Message: <3e28e7ea$1@news.povray.org>
"Thorsten Froehlich" <tho### [at] trfde> wrote:
>
> The code, or at least the comments in it are totally outdated.

Do you judge books the same way?


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: amalloc() (long post)
Date: 18 Jan 2003 04:58:37
Message: <3e29254d@news.povray.org>
In article <3e28e7ea$1@news.povray.org> , "Vadim Sytnikov" <syt### [at] rucom>
wrote:

>> The code, or at least the comments in it are totally outdated.
>
> Do you judge books the same way?

It depends on the topic - for example I would judge a book on MS-DOS as
outdated, yes.  And even a few chapters in a book on algorithm analysis
might be considered outdated.  The only written works that can never be
outdated are fictional ones.

    Thorsten

____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trfde

Visit POV-Ray on the web: http://mac.povray.org


Post a reply to this message

Goto Latest 10 Messages Next 7 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.