need help with arrays

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pereges

    need help with arrays

    Ok, I have some problem with arrays which i want to use for storing
    rays in my ray tracing project. please have a little patience to read.

    I need to fire rays from a a rectangular plane. The rays are parallel
    to each other so their direction is same but they differ in their
    origin points or source location. I tried to determine the source
    location by creating a grid of the rectangular plane. The rays are
    going to be spaced from each other at some distance lets say incr. The
    rectangular plane is going to be divided into small squares each of
    length incr.


    unsigned long int numberofrays;

    so

    incr = sqrt(l * b / numberofrays)

    now lets say the plane is represented by four corners:

    xmin, ymin
    xmax, ymin
    xmin, ymax
    xmax, ymax

    all are doubles

    My ray data structure is :

    typedef struct ray_struct
    {

    double ox, oy, oz; // ray origin or source represented by the
    3 x, y, z coordinates
    double t; //distance travelled
    double dx, dy, dz; // ray direction represented by 3 x, y, z
    coordinates

    }ray;

    Now, this is what I did to create the list of rays:

    ray *ray_list;

    ray_list = calloc(sizeof(r ay), numberofrays);

    Then, I try to store the rays:

    double xcord, ycord; // represents the origin of a random ray
    int i = 0;

    for(ycord = ymin; ycord <= ymax; ycord += incr)
    {
    for(xcord = xmin; xcord<= xmax; xcord+= incr)
    {
    ray_list[i].ox = x;
    ray_list[i].oy = y;
    ray_list[i].oz = 1000;
    ray_list[i].dx = 0; // all rays parallel to each other and
    travelling in +z direction
    ray_list[i].dy = 0;
    ray_list[i].dz = 1;
    ray_list[i].t = DBL_MAX; // rays go till infinity
    i++;
    }

    }



    Unfortunately, with this approach I am getting a segfault error.

    Also, when I entered the ray number as 20,000 actually there were
    20164 rays getting created which means I had crossed the array bounds.
    I could store these rays in a link list or a file but I think it is
    not a good idea at all. Also, what I could do is ask the user to enter
    incr first and based on that apply the above loop to calculate the
    number of rays and then using that number i allocate an array of rays
    and then add data sequentially. This approach is seeming too naive to
    me and also does not allow user to enter number of rays.

    One other problem I have is that in my project, it is possible that a
    ray hits an object and a reflected ray is generated and this
    reflected ray hits the object again and spawns a new ray. I need it
    for some energy calculations and this allows me to traverse the entire
    optical path of a ray. I was wondering if it is ok to have child
    pointer to solve this problem :

    typedef struct ray_struct
    {
    ........
    ........
    struct ray_struct ray *child;

    }

    IF a ray does not intersect the object then it spawns no rays and
    child is set to NULL


    I also want to ask, how useful is it to have doubles in a numerical
    simulation program(high accuracy is desired) ? Or is it ok to use
    floats instead ? Using doubles has really slowed down my program.
    Another thing I have noted is that its best to have variables with
    scopes as small as possible. I still wonder why many people prefer to
    use :

    extern const double PI = 3.14

    over

    #define PI 3.14


    shouldn't the second option be more efficient ?
  • pereges

    #2
    Re: need help with arrays

    sorry l and b are the length and breadth of the rectangular plane.

    Comment

    • Ben Bacarisse

      #3
      Re: need help with arrays

      pereges <Broli00@gmail. comwrites:
      Ok, I have some problem with arrays which i want to use for storing
      rays in my ray tracing project. please have a little patience to read.
      <snip>
      unsigned long int numberofrays;
      >
      so
      >
      incr = sqrt(l * b / numberofrays)
      >
      >
      now lets say the plane is represented by four corners:
      >
      xmin, ymin
      xmax, ymin
      xmin, ymax
      xmax, ymax
      >
      all are doubles
      >
      My ray data structure is :
      >
      typedef struct ray_struct
      {
      >
      double ox, oy, oz; // ray origin or source represented by the
      3 x, y, z coordinates
      double t; //distance travelled
      double dx, dy, dz; // ray direction represented by 3 x, y, z
      coordinates
      >
      }ray;
      >
      Now, this is what I did to create the list of rays:
      >
      ray *ray_list;
      >
      ray_list = calloc(sizeof(r ay), numberofrays);
      Better use malloc. There is no advantage in zeroing (arithmetically )
      the pointers.
      Then, I try to store the rays:
      >
      double xcord, ycord; // represents the origin of a random ray
      int i = 0;
      >
      for(ycord = ymin; ycord <= ymax; ycord += incr)
      {
      for(xcord = xmin; xcord<= xmax; xcord+= incr)
      {
      ray_list[i] does not point anywhere. You need to either malloc a ray
      structure for each one, or use a 2D array in the first place.
      ray_list[i].ox = x;
      ray_list[i].oy = y;
      ray_list[i].oz = 1000;
      ray_list[i].dx = 0; // all rays parallel to each other and
      travelling in +z direction
      ray_list[i].dy = 0;
      ray_list[i].dz = 1;
      ray_list[i].t = DBL_MAX; // rays go till infinity
      i++;
      }
      >
      }
      Also, watch our for you <=. Take a 3 x 4 rectangle with 48 rays and
      incr = 0.5. If you go <= you get both an extra row and ne more ray
      per row:

      X--X--X--X--X--X--X--X--X
      | | | | |
      X X X X X X X X X
      | | | | |
      X--X--X--X--X--X--X--X--X
      | | | | |
      X X X X X X X X X
      | | | | |
      X--X--X--X--X--X--X--X--X
      | | | | |
      X X X X X X X X X
      | | | | |
      X--X--X--X--X--X--X--X--X

      That is 63 rays, not 48!

      <snip>
      One other problem I have is that in my project, it is possible that a
      ray hits an object and a reflected ray is generated and this
      reflected ray hits the object again and spawns a new ray. I need it
      for some energy calculations and this allows me to traverse the entire
      optical path of a ray. I was wondering if it is ok to have child
      pointer to solve this problem :
      >
      typedef struct ray_struct
      {
      ........
      ........
      struct ray_struct ray *child;
      struct ray_struct *child;

      Yes, that is OK. But remember to allocate space for it.
      }
      I also want to ask, how useful is it to have doubles in a numerical
      simulation program(high accuracy is desired) ? Or is it ok to use
      floats instead ? Using doubles has really slowed down my program.
      There is no general rule. If you replace all your doubles with a
      typedef name you can test the difference when you are done with a
      single change.
      Another thing I have noted is that its best to have variables with
      scopes as small as possible. I still wonder why many people prefer to
      use :
      >
      extern const double PI = 3.14
      >
      over
      >
      #define PI 3.14
      >
      shouldn't the second option be more efficient ?
      See recent discussion of const.

      --
      Ben.

      Comment

      • pereges

        #4
        Re: need help with arrays

        On Apr 29, 9:50 pm, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
        <snip>
        Better use malloc. There is no advantage in zeroing (arithmetically )
        the pointers.
        How is malloc any different ? Both will achieve same purpose ?

        <snip>
        Also, watch our for you <=. Take a 3 x 4 rectangle with 48 rays and
        incr = 0.5. If you go <= you get both an extra row and ne more ray
        per row:
        >
        X--X--X--X--X--X--X--X--X
        | | | | |
        X X X X X X X X X
        | | | | |
        X--X--X--X--X--X--X--X--X
        | | | | |
        X X X X X X X X X
        | | | | |
        X--X--X--X--X--X--X--X--X
        | | | | |
        X X X X X X X X X
        | | | | |
        X--X--X--X--X--X--X--X--X
        >
        That is 63 rays, not 48!
        >

        I have changed my approach a little bit for generating points on the
        grid.

        /*************** *************** *************** *************** *****/

        #include <stdio.h>
        #include <math.h>
        #include <stdlib.h>

        int main(void)
        {
        long int numpoints;
        printf("Enter num of points\n");
        scanf("%d", &numpoints);
        long int numpointsx = sqrt((double)nu mpoints); //num of points
        along x
        long int numpointsy = sqrt((double)nu mpoints); // num of
        points along y
        numpoints = numpointsx * numpointsy; // total no of points for
        which i will allocate memory
        int i = 0;
        typedef struct point //temproray ds for point (just experimenting)
        {
        float x, y;

        } point;
        point *pointinarray;

        pointinarray = calloc(sizeof(p oint), numpoints); //new array with
        numpoints
        float xlength, ylength; //length and breadth
        xlength = ylength = 20;
        float xmin, ymin;
        xmin = ymin = -10;
        float xmax, ymax;
        xmax = ymax = 10;
        float xsize = xlength / numpointsx; //calculating increments
        along x and y
        float ysize = ylength / numpointsy;

        for (int yi = 0; yi < numpointsy; ++yi)
        {
        for (int xi = 0; xi < numpointsx; ++xi)
        {
        pointinarray[i].x = xmin + xi * xsize;
        pointinarray[i].y = ymin + yi * ysize;
        ++i;
        }
        }

        printf("i: %d xmax: %f ymax: %f\n",i, pointinarray[i-1].x,
        pointinarray[i-1].y);
        return 0;

        }

        /
        *************** *************** *************** *************** *************** **************/


        With this approach there seems to be no problem except 1.

        I checked out the last entry of pointsinarray[] which should
        correspond to xmax and ymax (10 and 10 respectively) and the values i
        get are:

        9.83509
        9.83509

        You can verify by running the above program yourself and checking o/p.

        Also, I noticed that when I entered 14000 as number of rays, The total
        number of rays actually taken into consideration for calculation of
        grid were only 13924. This problem arises when number of rays is not a
        perfect square.
        i believe problems are occuring because numpointsx and numpointsy are
        getting truncated to smaller values. For eg. in c, the integer square
        root of 5 is 2. I think if I can tweak it to some higher integer
        value, problem will be solved. I believe there is a function in math.h
        which does that.

        Comment

        • pereges

          #5
          Re: need help with arrays

          Ok solved.

          float xsize = xlength / (numpointsx - 1);
          float ysize = ylength / (numpointsy - 1);

          and use <= in both loops.

          With this approach, now i have extra points:

          For eg. numpoints = 14000 //entered by user

          actual numpoints = 14161 //161 extra

          xmax = 10.170940 ( actual xmax)
          ymax = 10.170940 ( actual ymax)

          but i don't mind really

          what i will do is that i am doing actual calculations, i will simply
          not consider points where:

          x xmax || y ymax

          x or y cannot be less than xmin, ymin anyway

          Comment

          • Ben Bacarisse

            #6
            Re: need help with arrays

            pereges <Broli00@gmail. comwrites:
            On Apr 29, 9:50 pm, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
            <snip>
            >
            >Better use malloc. There is no advantage in zeroing (arithmetically )
            >the pointers.
            >
            How is malloc any different ? Both will achieve same purpose ?
            There was no point in zeroing the array, that is all. It is sometimes
            useful and sometimes not.

            --
            Ben.

            Comment

            • Barry Schwarz

              #7
              Re: need help with arrays

              On Tue, 29 Apr 2008 10:20:23 -0700 (PDT), pereges <Broli00@gmail. com>
              wrote:



              snip 30+ obsolete lines
              >I have changed my approach a little bit for generating points on the
              >grid.
              Then please don't quote irrelevant material.
              >
              >/*************** *************** *************** *************** *****/
              >
              >#include <stdio.h>
              >#include <math.h>
              >#include <stdlib.h>
              >
              >int main(void)
              >{
              > long int numpoints;
              > printf("Enter num of points\n");
              > scanf("%d", &numpoints);
              This invokes undefined behavior. The %d promises scanf that the
              corresponding argument will be an int*. It is obviously a long int*.
              The fact that it appears to work on your system is just bad luck.
              long int numpointsx = sqrt((double)nu mpoints); //num of points
              >along x
              The cast serves no purpose.

              If you want people to test your code, then this is one reason why you
              should not use // style comments.
              long int numpointsy = sqrt((double)nu mpoints); // num of
              >points along y
              numpoints = numpointsx * numpointsy; // total no of points for
              >which i will allocate memory
              int i = 0;
              Unless you have C99, declarations and definitions need to precede
              executable statements.
              > typedef struct point //temproray ds for point (just experimenting)
              {
              > float x, y;
              >
              } point;
              > point *pointinarray;
              >
              > pointinarray = calloc(sizeof(p oint), numpoints); //new array with
              >numpoints
              > float xlength, ylength; //length and breadth
              > xlength = ylength = 20;
              > float xmin, ymin;
              xmin = ymin = -10;
              > float xmax, ymax;
              > xmax = ymax = 10;
              float xsize = xlength / numpointsx; //calculating increments
              >along x and y
              float ysize = ylength / numpointsy;
              >
              > for (int yi = 0; yi < numpointsy; ++yi)
              Defining a variable this way is an extension.
              {
              for (int xi = 0; xi < numpointsx; ++xi)
              {
              pointinarray[i].x = xmin + xi * xsize;
              pointinarray[i].y = ymin + yi * ysize;
              ++i;
              }
              }
              >
              printf("i: %d xmax: %f ymax: %f\n",i, pointinarray[i-1].x,
              >pointinarray[i-1].y);
              return 0;
              >
              >}
              >
              >/
              >************** *************** *************** *************** *************** ***************/
              >
              >
              >With this approach there seems to be no problem except 1.
              >
              >I checked out the last entry of pointsinarray[] which should
              >correspond to xmax and ymax (10 and 10 respectively) and the values i
              >get are:
              >
              >9.83509
              What value did you enter for numpoints?
              >9.83509
              >
              >You can verify by running the above program yourself and checking o/p.
              >
              >Also, I noticed that when I entered 14000 as number of rays, The total
              >number of rays actually taken into consideration for calculation of
              >grid were only 13924. This problem arises when number of rays is not a
              >perfect square.
              >i believe problems are occuring because numpointsx and numpointsy are
              >getting truncated to smaller values. For eg. in c, the integer square
              >root of 5 is 2. I think if I can tweak it to some higher integer
              >value, problem will be solved. I believe there is a function in math.h
              >which does that.
              If you use an integer higher that the sqrt you will have the same
              problem but in the opposite direction. WHY are you converting the
              sqrt to integer? The only way to get a square grid with the number of
              points you specify is to specify a perfect square.


              Remove del for email

              Comment

              Working...