M5Core2 icon indicating copy to clipboard operation
M5Core2 copied to clipboard

BUG: PointAndZone.cpp -> Zone::rotate()

Open FerNadal opened this issue 4 years ago • 1 comments

In the calculation of inv_x and inv_y, TFT_WIDTH and TFT_HEIGHT must be interchanged according to the rotation of the screen. Otherwise, the resulting coordinates of the Zone :: rotate () function are wrong and do not correspond to the physical locations of buttons A, B, and C.

Demonstration:

M5.Lcd.setRotation(2);
...
BtnA(10,240,110,40..);

Inside Zone :: rotate ():

inv_x = TFT_WIDTH - 1 - x - w (= 240 - 1 - 10 - 110 = 119 -> Wrong!!)
...
switch (m) {
...
  case 2:
    x = normal_y;
    y = inv_x;
    break;
...

The zone corresponding to button A would have the coordinates (240,119,280,229), overlapping with the real button B (240,130,280,200).

Correct value:

When the rotation is 2, the screen has a resolution of 240(280)x320 in the rotated x and y directions, so:

inv_x = TFT_WIDTH - 1 - x - w (= 320 - 1 - 10 - 110 = 199 - > Correct !!)

Fixed function:

void Zone::rotate(uint8_t m) {
  if (m == 1) return;

  int16_t tftW = TFT_WIDTH;
  int16_t tftH = TFT_HEIGHT;
  
  switch (m) {
    case 0:
      tftW = TFT_HEIGHT;
      tftH = TFT_WIDTH;
      break;
    case 2:
      tftW = TFT_HEIGHT;
      tftH = TFT_WIDTH;
      break;
    case 3:
      tftW = TFT_WIDTH;
      tftH = TFT_HEIGHT;
      break;
    // rotations 4-7 are mirrored
    case 4:
      tftW = TFT_HEIGHT;
      tftH = TFT_WIDTH;
      break;
    case 5:
      tftW = TFT_WIDTH;
      tftH = TFT_HEIGHT;
      break;
    case 6:
      tftW = TFT_HEIGHT;
      tftH = TFT_WIDTH;
      break;
    case 7:
      tftW = TFT_WIDTH;
      tftH = TFT_HEIGHT;
      break;
  }

  int16_t normal_x = x;
  int16_t normal_y = y;
  int16_t inv_x = tftW - 1 - x - w;
  int16_t inv_y = tftH - 1 - y - h;
...

There are no changes from this line to the end of the function.

FerNadal avatar Jul 19 '21 19:07 FerNadal

Thx a lot for this issue. It helped me to find out, why my M5Stack Core2 didn't work properly with rotation. But in the section "case 3" is still a mistake.

The right variables are the following:

case 3:
      tftW = TFT_HEIGHT;
      tftH = TFT_WIDTH;
      break;

Then it works as expected: The buttons (aka the small red circles) are on the top and they react now.

digi-thomas2003 avatar Jan 14 '23 23:01 digi-thomas2003