irregular shaped led matrix help

i am currently working on an urregularly shaped matrix that in set up in a serpentine column format.
the ws2812b leds start on the top left and progress to the right i have attached my code as well as a break down of the exact layout of the leds by placement and number.
the issue i am currently having is i cannot get a strait line to render.

this is the code

#include <FastLED.h>

#define LED_PIN  6

#define COLOR_ORDER GRB
#define CHIPSET     WS2812

#define BRIGHTNESS 25

const uint8_t kMatrixWidth = 17;
const uint8_t kMatrixHeight = 26;

const bool    kMatrixSerpentineLayout = true;

uint16_t XY( uint8_t x, uint8_t y)
{
  uint16_t i;
  
  if( kMatrixSerpentineLayout == false) {
    i = (y * kMatrixWidth) + x;
  }

  if( kMatrixSerpentineLayout == true) {
    if( y & 0x01) {
      // Odd rows run backwards
      uint8_t reverseX = (kMatrixWidth - 1) - x;
      i = (y * kMatrixWidth) + reverseX;
    } else {
      // Even rows run forwards
      i = (y * kMatrixWidth) + x;
    }
  }
  
  return i;
}



#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
CRGB* const leds( leds_plus_safety_pixel + 1);

uint16_t XYsafe( uint8_t x, uint8_t y)
{
  if( x >= kMatrixWidth) return -1;
  if( y >= kMatrixHeight) return -1;
  return XY(x,y);
}



void loop()
{

  
    uint32_t ms = millis();
    int32_t yHueDelta32 = ((int32_t)cos16( ms * (8/1) ) * (1400 / kMatrixWidth));
    int32_t xHueDelta32 = ((int32_t)cos16( ms * (14/1) ) * (1240 / kMatrixHeight));
    DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);
    if( ms < 5000 ) {
      FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));
    } else {
      FastLED.setBrightness(BRIGHTNESS);
    }
    FastLED.show();
}

void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
{
  byte lineStartHue = startHue8;
  for( byte y = 0; y < kMatrixHeight; y++) {
    lineStartHue += yHueDelta8;
    byte pixelHue = lineStartHue;      
    for( byte x = 0; x < kMatrixWidth; x++) {
      pixelHue += xHueDelta8;
      leds[ XY(x, y)]  = CHSV( pixelHue, 255, 255);
    }
  }
}


void setup() {
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  FastLED.setBrightness( BRIGHTNESS );
}


The reason you can't render a straight line is because the information shown above is nowhere in your code!

You need to make a 2D array and put those numbers in it. Then, you can replace the XY() function with a look-up into the array.

uint16_t matrixLayout[kMatrixHeight][kMatrixWidth] = 
{
  { 1, 20, 21, ... },
  { 2, 19, 22, ... },
  ...
  { -1, -1, -1,... }
};

uint16_t XY( uint8_t x, uint8_t y)
{
  return matrixLayout[y][x];
};

But there is a problem with this idea. What kind of Arduino do you plan to use? The fastLED object for a 333 led strip will take up almost 1K of RAM memory, and the new 2D array will also take up nearly 1K. Uno/Nano/Pro Mini only have 2K.

So you may need an Arduino with more memory, or find a way to put the 2D array into PROGMEM.

thank you for the info i have been working almost non stop on this and have a new updated code.
currently i have 2 boards available to me one is the Arduino nano which is what i am working on now and i have a board that my brother sent me its a nled pixel controller electron and i dont think i can put the Arduino ide on it. i believe its a proprietary board for northern lights electronics design.
below is the new code. also any suggestions on boards? i have been seriously considering the Trinket M0 from Adafruit. its only $9 and seems like it would have what i need.

#include <FastLED.h>

#define LED_PIN  6

#define COLOR_ORDER GRB
#define CHIPSET     WS2812

#define BRIGHTNESS 25

// Params for width and height
const uint8_t kMatrixWidth = 26;
const uint8_t kMatrixHeight = 17;

#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
CRGB leds[ NUM_LEDS ];
#define LAST_VISIBLE_LED 332
uint16_t XY (uint16_t x, uint16_t y) {
  // any out of bounds address maps to the first hidden pixel
  if ( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) {
    return (LAST_VISIBLE_LED + 1);
  }


  const uint16_t XYTable[] = {
     0,  19,  20,  38,  39,  56,  57, 384,  77, 399,  78,  95,  96, 113, 114, 132, 133,
     1,  18,  21,  37,  40,  55,  58, 383,  76, 398,  79,  94,  97, 112, 115, 131, 134,
     2,  17,  22,  36,  41,  54,  59, 382,  75, 397,  80,  93,  98, 111, 116, 130, 135,
     3,  16,  23,  35,  42,  53,  60, 381,  74, 396,  81,  92,  99, 110, 117, 129, 136,
     4,  15,  24,  34,  43,  52,  61, 380,  73, 395,  82,  91, 100, 109, 118, 128, 137,
     5,  14,  25,  33,  44,  51,  62, 379,  72, 394,  83,  90, 101, 108, 119, 127, 138,
     6,  13,  26,  32,  45,  50,  63, 378,  71, 393,  84,  89, 102, 107, 120, 126, 139,
     7,  12,  27,  31,  46,  49,  64, 377,  70, 392,  85,  88, 103, 106, 121, 125, 140,
     8,  11,  28,  30,  47,  48,  65, 376,  69, 391,  86,  87, 104, 105, 122, 124, 141,
     9,  10,  29, 353, 354, 367, 368, 375,  68, 390, 400, 411, 412, 425, 426, 123, 142,
   322, 342, 343, 352, 355, 366, 369, 374,  67, 389, 401, 410, 413, 424, 427, 436, 143,
   323, 321, 344, 351, 356, 365, 370, 373,  66, 388, 402, 409, 414, 423, 165, 164, 144,
   324, 320, 300, 299, 356, 364, 371, 256, 385, 231, 403, 408, 415, 185, 166, 163, 145,
   325, 319, 301, 298, 179, 278, 257, 255, 386, 230, 206, 205, 186, 184, 167, 162, 146,
   326, 318, 302, 297, 280, 277, 258, 254, 387, 229, 207, 204, 187, 183, 168, 161, 147,
   327, 317, 303, 296, 281, 276, 259, 253, 232, 228, 208, 203, 188, 182, 169, 160, 148,
   328, 316, 304, 295, 282, 275, 260, 252, 233, 227, 209, 202, 189, 181, 170, 159, 149,
   329, 315, 305, 294, 283, 274, 261, 251, 234, 226, 210, 201, 190, 180, 171, 158, 150,
   330, 314, 306, 293, 284, 273, 262, 250, 235, 225, 211, 200, 191, 179, 172, 157, 151,
   331, 313, 307, 292, 285, 272, 263, 249, 236, 224, 212, 199, 192, 178, 173, 156, 152,
   332, 312, 308, 291, 286, 271, 264, 248, 237, 223, 213, 198, 193, 177, 174, 155, 153,
   333, 311, 309, 290, 287, 270, 265, 247, 238, 222, 214, 197, 194, 176, 175, 154, 437,
   334, 341, 310, 289, 288, 269, 266, 246, 239, 221, 215, 196, 195, 422, 428, 435, 438,
   335, 340, 345, 350, 358, 363, 267, 245, 240, 220, 216, 407, 416, 421, 429, 434, 439,
   336, 339, 346, 349, 359, 362, 268, 244, 241, 219, 217, 406, 417, 420, 430, 433, 440,
   337, 338, 347, 348, 360, 361, 372, 243, 242, 218, 404, 405, 418, 419, 431, 432, 441,
  };



  uint16_t i = (y * kMatrixWidth) + x;
  uint16_t j = XYTable[i];
  return j;
}



void loop() {
  // put your main code here, to run repeatedly:
      uint32_t ms = millis();
    int32_t yHueDelta32 = ((int32_t)cos16( ms * (8/1) ) * (1400 / kMatrixWidth));
    int32_t xHueDelta32 = ((int32_t)cos16( ms * (14/1) ) * (1240 / kMatrixHeight));
    DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);
    if( ms < 5000 ) {
      FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));
    } else {
      FastLED.setBrightness(BRIGHTNESS);
    }
    FastLED.show();
}

void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
{
  byte lineStartHue = startHue8;
  for( byte y = 0; y < kMatrixHeight; y++) {
    lineStartHue += yHueDelta8;
    byte pixelHue = lineStartHue;      
    for( byte x = 0; x < kMatrixWidth; x++) {
      pixelHue += xHueDelta8;
      leds[ XY(x, y)]  = CHSV( pixelHue, 255, 255);
    }
  }

}

void setup() {
  // put your setup code here, to run once:
    FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  FastLED.setBrightness( BRIGHTNESS );

}

The Trinket M0 sounds an interesting little board I had not come across before. You should not have any memory problems with that.

It’s a shame they did not make a few more pins available, such as SPI, which would have made it useful for some projects I have in mind. The full size Feather M0 is too large and considerably more expensive.

EDIT: AdaFruit make another board, in-between the Trinket M0 and the Feather M0. Only a couple of dollars more than the Trinket. Could be the “Golilocks” board I was hoping for.