hzeller / rpi-rgb-led-matrix

Controlling up to three chains of 64x64, 32x32, 16x32 or similar RGB LED displays using Raspberry Pi GPIO
GNU General Public License v2.0
3.67k stars 1.16k forks source link

Implementing "S" arrangement transformation #341

Closed chrisoutwright closed 7 years ago

chrisoutwright commented 7 years ago

As the adapter for 3 chains will take some time to ship and mount, I thought about going about the implementation for 9x 32 panel 1-chain "S" square-arrangement, so one additional row which hampers calling the UArrangementTransformer.

As somebody tried it already in this (already closed) issue post, I tried to replicate the issue with it. I posted there a comment as to what is amiss in the display.

Adding If calls would be my first idea to analyse what the (imo relevant fragment) code actually maps:

void SArrangementTransformer::TransformCanvas::SetPixel(
  int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
  if (x < 0 || x >= width_ || y < 0 || y >= height_) return;
  const int slab_height = virtualrows_*panel_height_;   // one folded s-shape
  const int base_y = (y / slab_height) * panel_height_;
  y %= slab_height;
  if (y < panel_height_) {
    x += delegatee_->width() / virtualrows_;
  } 
   if ((y < 2*panel_height_ )and (y >= panel_height_)) {
    x = width_ - x - 1;
    y = slab_height - y - 1;
  }

My question would be if it is only the void SArrangementTransformer::TransformCanvas::SetPixel(...) method needing a fix, or is it more than this in @soyxan's code? I fear it is more that adding IFs.

I would be extremely glad if somebody has an idea about it, or even a other solution except for parallel chains.

chrisoutwright commented 7 years ago

Nearly got there for 3 rows with 3 panels in each, only the last row is now incrementing lines for characters in a wrong way:

void SArrangementTransformer::TransformCanvas::SetPixel(
  int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
  if (x < 0 || x >= width_ || y < 0 || y >= height_) return;
  const int slab_height = virtualrows_*panel_height_;   // one folded s-shape
  const int base_y = (y / slab_height) * panel_height_;
  y %= slab_height;
   if (y < panel_height_) {
   x += delegatee_->width()*2/3 ;

     }
 if ((y < 2*panel_height_ ) && (y >= panel_height_)) {
    x = 2*width_ - x - 1;
    y = slab_height *2/3 - y - 1;
  }

 if  ((y < 3*panel_height_ ) && (y >=2* panel_height_)) {
    x += delegatee_->width()*0;
    y = slab_height  - y - 1;

  }
  delegatee_->SetPixel(x, base_y + y, red, green, blue); }

Somehow in the case:((y < 3*panel_height_ ) && (y >=2* panel_height_)) y should read: y = slab_height*2/3 + y +1; But this wont show anything then. I am at a loss.

Upper row is vertically mirrored and lines adding reversed (note - I am using a reversed formation): 20170613_004554

chrisoutwright commented 7 years ago

For those interested, the now correctly working version for the relevant method (only 3x3 panels are tested and modified for, but can now be easily deduced by my code below for more vertical rows) is:

void SArrangementTransformer::TransformCanvas::SetPixel(
  int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
  if (x < 0 || x >= width_ || y < 0 || y >= height_) return;
  const int slab_height = virtualrows_*panel_height_;   // one folded s-shape
  const int base_y = (y / slab_height) * panel_height_;
  y %= slab_height;
   if (y < panel_height_) {
   x += delegatee_->width()*2/3 ;

     }
 if ((y < 2*panel_height_ ) && (y >= panel_height_)) {
    x = 2*width_ - x - 1;
    y = slab_height *2/3 - y - 1;

  }

 if  ((y < 3*panel_height_ ) && (y >=2* panel_height_)) {

     y =  y - slab_height*2/3 ;

  }
  delegatee_->SetPixel(x, base_y + y, red, green, blue);
}

So the most informative parts are the first and last if cases (it is missing alternatively the other coordinate in declaring, so actually using it as it comes in x=x or y=y):

20170613_110152

soyxan commented 7 years ago

I am trying to use your code for my panel configuration of 3 rows of 10 panels each (32x32), with no luck.

Have you modified the SArrangementTransformer::TransformCanvas::SetDelegatee() function? What I have to modify in your code to get it working?

Thanks in advance!

chrisoutwright commented 7 years ago

Hi soyxan, Are you doing 30 panels in series or 3 parallel rows of 10 each? The code I submitted is intended for 9 panels in square formation on one output line. Concerningparallel=1, the code should work for 9 panels, as my pictures show. One could scale the code for, say, 16 panels, but this would stress the single output line. Doing anything other than square formation with higher than two panel rows (therefore S-Transformer) would require testing and adapting the code to see how to map the pixels. As can be seen from the logic of the code, I would try:

What do you think?