Best way to store a collection of 3D Points

Hello All,

I have finished my 8x8x8 3D RGB LED Cube and have been writing software for it. Basic stuff works great. I can turn on/LEDs and change thier colors etc... I have some pretty neat animations going. Now I am looking to do something a little more. I want to create letters and geometric shapes that I can rotate and scale. I figure the best way to do this is storing using vector graphics like points and lines. I want to start with a good foundation but I just can't seem to get an array of structures working to store my points. I understand the theory behind pointers and the concept of an array of pointers pointing to structures but I just can't work out the syntax. Any help would be appreciated.

If I can get this working I plan to create an array of lines as well.

Here is the non working code. How can I successfully define and call the array elements.

/************************************************************
Vector Layer (Commands for drawing vector objects)
************************************************************/
typedef struct Point {
int x;
int y;
int z;
int color;
};

Point VectorPoints = new Point[100];
int NextVectorPoint = 0;

int Point(int x,int y,int color) // (3 bit color 1-red 2-green 4-blue)
{
VectorPoint[NextVectorPoint].x = x;
VectorPoint[NextVectorPoint].y = y;
VectorPoint[NextVectorPoint].z = z;
VectorPoint[NextVectorPoint].color = color;
NextVectorPoint++;
return NextVectorPoint-1;
}

void Drop()
{
for (int t=0; t<NextVectorPoint; t++)
{
VectorPoint[t].z--;
}
}

You don't need a two-byte int to store the coordinate of an LED which presumably has a coordinate between 1 and 8 or 0 and 7.

You can use a single-byte int to store a number that small. In fact, you could use half a byte.

Two store a collection of such points, you have two basic choices. An array, or a linked list. Everything else
is basically a variation of one of those.

@michinyon

Actually I do need more then a value from 0 to 8. For example I may want an entire sentence to scroll by one letter a time like a banner. Rather load one letter at a time I simply build the entire sentence off cube and the move the display area. I am creating a virtual drawing space not just the display space. This is pretty common in graphics programming.

Thanks for the tip about linked lists it led me to some interesting research. I think I will stick with the array of structs or array of points for the sake of iteration speed though.

What I really need is help with the syntax to define and then call the array elements. Everything I try either gives me an error or simply does not work.

Hope someone can help
I'll keep trying things

Still testing but I think I got it...

/************************************************************
Vector Layer (Commands for drawing vector objects)
************************************************************/
typedef struct {
int x;
int y;
int z;
int color;
} VectorPoint;

VectorPoint VectorPoints[5];

int NextVector = 0;

int Point(int x,int y,int color) // (3 bit color 1-red 2-green 4-blue)
{
VectorPoints[NextVector].x = x;
VectorPoints[NextVector].y = y;
VectorPoints[NextVector].z = z;
VectorPoints[NextVector].color = color;
NextVector++;
return NextVector-1;
}

void Drop()
{
for (int t=0; t<NextVector; t++)
{
VectorPoints[t].z--;
}
}

Your "Point" object seems to represent the status of a single point. Not multiple points.
I don't understand your explanation that you would need an address space that requires
an "int" coordinate in each direction.

The code you posted looks reasonable but has quite a lot of typos in. The main problem is that you have defined a function with the same name as your struct.

You could clean this up slightly:

  NextVector++;
  return NextVector-1;

would be better as:

  return NextVector++;

(Post increment operator uses the current value and then increments the variable.)

I don't understand the reason for including a colour in a point. I would have thought it made more sense to define a shape as a sequence of points and colour, thickness, style etc. Having a colour for eahc point only makes sense to me if you expect a vector to colour itself from the end point colours somehow.

The structure you're using seems likely to lead to some fairly big data structures. Have you estimated how much data there will be? Will it be dynamic (in RAM) or constant (in progmem)? If you do end up running out of space, you could consider defining the fields as bitfields rather than ints; that would reduce the storage requirements considerably.

Here's a copy with the typos corrected:

// compiled, untested
/************************************************************
 Vector Layer (Commands for drawing vector objects)
************************************************************/
struct Point {
  int x;
  int y;
  int z;
  int color;
};

Point VectorPoint[100];
int NextVectorPoint = 0;

int addPoint(int x,int y, int z, int color) // (3 bit color 1-red 2-green 4-blue)
{
  VectorPoint[NextVectorPoint].x = x; 
  VectorPoint[NextVectorPoint].y = y;
  VectorPoint[NextVectorPoint].z = z;
  VectorPoint[NextVectorPoint].color = color;
  return NextVectorPoint++; 
}

void dropPoint()
{
  for (int t=0; t<NextVectorPoint; t++)
  {
    VectorPoint[t].z--;
  }
}

Will it be dynamic (in RAM) or constant (in progmem)?

Given that there is an addPoint() function, constant seems unlikely.

PaulS:
Given that there is an addPoint() function, constant seems unlikely.

Yeah, but this code seems to be an initial prototype to prove the concept. It may be that the final solution will use a predefined data set.

Another thought (but I'm not sure if the processing overhead would slow the display down) is to have the virtual display space with all the objects stored on an SD card. (Plenty of shields have SD connectors on them. If the shield was designed properly it communicates with the SD card over ISP on the ICSP header with D4 as chip select, but if designed only for the UNO it may use D11-13 and D4.) Each line of an ASCII file on the SD card would be a 2D array of the next slice of the virtual display space. Only read the lines in as you need to move your physical display area over the virtual display space. Granted, I'm assuming the only translation in your virtual display space will be left-to-right or right-to-left... I suppose you could do something similar and only need to keep one display width's worth of points in SRAM if you want to move the physical display area on multiple axis. Only load slices in as needed... If the physical display width is x, then the amount of SRAM only limits your y and z axis sizes. You can have up to 32GB of x axis... 8) Maybe more, not sure if SDXC cards work on Arduinos... If they do, that would be a theoretical 2TB of x axis... :smiley: well, once cards that big are made... :wink:

But, as I postulated, the amount of time required to read a line of data off the SD card over SPI and then parse the line of characters into an array of values might take longer than you want for smooth scrolling. But it is certainly an interesting avenue to explore.

Another plus is you could change displays simply by changing SD cards, instead of re-flashing the processor.