ESP32 TFT LCD Help with Arrays

Hello. I'm using the Bresenham Algorithm to plot pixels to be used in the tft.drawLine function.
tft.drawLine needs start and end coordinates which I am storing in Arrays.
I'm computing the coordinates once and storing the data for later use.
So far my code stores each x, y, x0, y0 in separate Arrays. I would like to combine these into 1 or 2 Arrays.
Getting this far has really hurt my brain learning about pointers and Arrays but I just need a little help crossing the line.
Thanks
My Array setup for Start coordinates...

int MyArray_x0[100];
int MyArray_y0[100];
int *myPointer_x0;
int *myPointer_y0;
                                            
int MyArray_x1[100];
int MyArray_y1[100];
int *myPointer_x1;
int *myPointer_y1;

My Plotline code. I have another function that plotsLine_x1_y1 but have left it out to save clutter

void plotLine_x0_y0(int x0, int y0, int x1, int y1)
{  
    int dx =  abs(x1-x0), sx = x0<x1 ? 1 : -1;
    int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1;
    int err = dx+dy, e2;                                  /* error value e_xy */

    for (;;) {                                                        /* loop */
        tft.drawPixel(x0, y0, TFT_YELLOW);// used for testing Line
        UpdateArray_x0_y0(x0, y0);
        e2 = 2*err;
        if (e2 >= dy) {                                       /* e_xy+e_x > 0 */
            if (x0 == x1) break;
            err += dy; x0 += sx;
        }
        if (e2 <= dx) {                                       /* e_xy+e_y < 0 */
            if (y0 == y1) break;
            err += dx; y0 += sy;
        }
    }
}

My Update Array Code

void UpdateArray_x0_y0(int x0, int y0){
  static unsigned int call_count = 0;
  
  myPointer_x0 = &MyArray_x0[call_count];
  myPointer_y0 = &MyArray_y0[call_count];
  *myPointer_x0 = x0;
  *myPointer_y0 = y0;
    call_count++;
  }

void UpdateArray_x1_y1(int y1, int x1){
  static unsigned int call_count = 0;
  
  myPointer_y1 = &MyArray_y1[call_count];
  myPointer_x1 = &MyArray_x1[call_count];
  *myPointer_y1 = y1;
  *myPointer_x1 = x1;

    call_count++;
  }

You don't need to worry about pointers when using arrays, if the indexing is explicit.

Here is what I might do for line drawing, example triangle:

void setup() {
  Serial.begin(115200);
  int lines[][4] = { {0, 0, 0, 1}, {0, 1, 1, 1}, {1, 1, 0, 0} }; // (x0, y0, x1, y1) tuples
  plot (lines, 3);
}
void plot(int lines[][4], int N) {  //N = number of lines to draw
  for (int i = 0; i < N; i++) {
    Serial.print("draw from ");
    Serial.print(lines[i][0]);
    Serial.print(", ");
    Serial.print(lines[i][1]);
    Serial.print(" to ");
    Serial.print(lines[i][2]);
    Serial.print(", ");
    Serial.println(lines[i][3]);
  }
}
void loop() {
}

Output

draw from 0, 0 to 0, 1
draw from 0, 1 to 1, 1
draw from 1, 1 to 0, 0

You might take a look at Adafruit's implementation of the Bresenham algorithm in their GFX library, which is interesting for its simplicity. Takes all octants into account, of course.


/**************************************************************************/
/*!
   @brief    Write a line.  Bresenham's algorithm - thx wikpedia
    @param    x0  Start point x coordinate
    @param    y0  Start point y coordinate
    @param    x1  End point x coordinate
    @param    y1  End point y coordinate
    @param    color 16-bit 5-6-5 Color to draw with
*/
/**************************************************************************/
void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
                             uint16_t color) {
#if defined(ESP8266)
  yield();
#endif
  int16_t steep = abs(y1 - y0) > abs(x1 - x0);
  if (steep) {
    _swap_int16_t(x0, y0);
    _swap_int16_t(x1, y1);
  }

  if (x0 > x1) {
    _swap_int16_t(x0, x1);
    _swap_int16_t(y0, y1);
  }

  int16_t dx, dy;
  dx = x1 - x0;
  dy = abs(y1 - y0);

  int16_t err = dx / 2;
  int16_t ystep;

  if (y0 < y1) {
    ystep = 1;
  } else {
    ystep = -1;
  }

  for (; x0 <= x1; x0++) {
    if (steep) {
      writePixel(y0, x0, color);
    } else {
      writePixel(x0, y0, color);
    }
    err -= dy;
    if (err < 0) {
      y0 += ystep;
      err += dx;
    }
  }
}

Thanks for the reply. Lots of food for thought there..

int MyArray_x0_y0[100][2];

You have given me the idea to test this format and I think it'll help my brain to visualize it better for now. Doing it this way I go from 8 arrays to 4.
Oh this what I'm trying to achieve...

Hud_cropped

That static stuff was easy but animating converging lines turn out to be harder than it looks.

Cheers

For perspective plots like that, Z coordinates on each point are very useful.

Might be worthwhile to put all the coordinates for each line into a struct. Then you could have a 1-D array of those structs.

Thanks I'm reading this article now..
constexpr array in C++

What a rabbit hole I've gotten myself into :smiley:

Here is a small example using two structs, one to define a point, and the other to define a line, with useful functions to get the length and midpoint (it's just an example) : QXuJNa - Online C++ Compiler & Debugging Tool - Ideone.com

Ohh I like the line struct functions in there especially the midpoint one :+1:
That could come very handy'

Thanks

Ok I was given the solution by someone much smarter than myself because after many hours of reading and learning about pointers it appears they were not needed for this application.
My function now is...

void UpdateArray_x0y0(int x0, int y0){
static unsigned int call_count = 0;
arr_x0y0[call_count][0] = x0;
arr_x0y0[call_count][1] = y1;
call_count++;
}

Thank to all for the help

Edited for a typo

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.