Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在图形显示上旋转文本_C++_Arduino_Esp8266_Lcd_Arduino Esp8266 - Fatal编程技术网

C++ 在图形显示上旋转文本

C++ 在图形显示上旋转文本,c++,arduino,esp8266,lcd,arduino-esp8266,C++,Arduino,Esp8266,Lcd,Arduino Esp8266,我正在尝试添加这个功能,以在图形显示上旋转文本。我使用的是电子纸显示器,但图书馆支持其他图形显示器。我已经在屏幕上旋转了文本,但我无法确定旋转中心是否正确。通过研究类似的问题,我发现我需要暂时将原点移动到旋转点。但是,我很难看到如何使用此代码实现这一点drawString调用多个函数,直到最后有一个函数来设置像素颜色(在这里我插入了代码来旋转受影响的像素)。我想我需要把旋转方向移向上游 我添加了setxtrotation,它预先计算sin/cos,随后传递到setPixel中的前两行(在下面的代

我正在尝试添加这个功能,以在图形显示上旋转文本。我使用的是电子纸显示器,但图书馆支持其他图形显示器。我已经在屏幕上旋转了文本,但我无法确定旋转中心是否正确。通过研究类似的问题,我发现我需要暂时将原点移动到旋转点。但是,我很难看到如何使用此代码实现这一点
drawString
调用多个函数,直到最后有一个函数来设置像素颜色(在这里我插入了代码来旋转受影响的像素)。我想我需要把旋转方向移向上游

我添加了
setxtrotation
,它预先计算sin/cos,随后传递到
setPixel
中的前两行(在下面的代码块底部)。在上面的第一个链接中可能更容易看到更改。我尝试求解(感谢Wolfram)一个方程组来计算x和y,这将导致
setPixel
函数中旋转的像素与传递给
drawString
的原始x和y具有相同的原点,但没有乐趣。另外,我觉得我把问题严重复杂化了

我不是一个专业的程序员(也不是一个业余爱好者)。对如何进行有什么建议吗

谢谢

相关部分(完整代码见以上链接):

int16\t txtRotation=0;
浮动正弦角=0;
浮动cos_角=1;
void MiniGrafx::setTextRotation(int16\u t r){
int16_t txtAngle=r;
Serial.print(“文本角度=”);
Serial.println(txtAngle);
做
{
如果(txtAngle>=360)txtAngle=txtAngle-360;
Serial.println(txtAngle);
}而(txtAngle>360);
做
{
如果(txtAngle>1;
//失败
案例文本对齐居中:
xMove-=textWidth>>1;//除以2
打破
案例文本\u对齐\u右对齐:
xMove-=文本宽度;
打破
}
//如果不在屏幕上,不要画任何东西。
如果(xMove+textWidth<0 | | xMove>this->width){return;}
如果(yMove+textHeight<0 | | yMove>this->height){return;}
对于(uint16_t j=0;j=firstChar){
字节charCode=代码-第一字符;
//每个字符代码4个字节
字节msbJumpToChar=pgm_read_byte(fontData+JUMPTABLE_START+charCode*JUMPTABLE_BYTES);//MSB\JumpAddress
byte lsbJumpToChar=pgm_read_byte(fontData+JUMPTABLE_START+charCode*JUMPTABLE_BYTES+JUMPTABLE_LSB);//LSB/
byte charByteSize=pgm_read_byte(fontData+JUMPTABLE_START+charCode*JUMPTABLE_BYTES+JUMPTABLE_SIZE);//大小
byte currentCharWidth=pgm_read_byte(fontData+JUMPTABLE_START+charCode*JUMPTABLE_BYTES+JUMPTABLE_WIDTH);//宽度
//测试字符是否可绘制
如果(!(msbJumpToChar==255&&lsbJumpToChar==255)){
//获取字符数据的位置
uint16\u t charDataPosition=JUMPTABLE\u START+sizeOfJumpTable+((msbJumpToChar textAlignment=textAlignment;
}
uint16\u t MiniGrafx::getStringWidth(常量字符*文本,uint16\u t长度){
uint16_t firstChar=pgm_读取字节(fontData+FIRST_CHAR_POS);
uint16\u t stringWidth=0;
uint16\u t最大宽度=0;
while(长度--){
stringWidth+=pgm_读取_字节(fontData+JUMPTABLE_开始+(文本[长度]-firstChar)*JUMPTABLE_字节+JUMPTABLE_宽度);
如果(文本[长度]==10){
maxWidth=最大值(maxWidth,stringWidth);
stringWidth=0;
}
}
返回最大值(maxWidth、stringWidth);
}
void inline MiniGrafx::drawInternal(int16\u t xMove、int16\u t yMove、int16\u t width、int16\u t height、const char*数据、uint16\u t offset、uint16\u t bytesInData){
如果(宽度<0 | |高度<0)返回;
如果(yMove+height<0 | | yMove>this->height)返回;
如果(xMove+width<0 | | xMove>this->width)返回;
uint8_t rasterHeight=1+((高度-1)>>3);//快速单元(高度/8.0)
int8_t yOffset=yMove&7;
bytesInData=bytesInData==0?宽度*光栅高度:bytesInData;
int16_t initYMove=yMove;
int8_t initYOffset=yOffset;
uint8_t arrayHeight=(int)天花板(高度/8.0);
对于(uint16_t i=0;i=width | | newY>=height | | newX<0 | | newY<0 | | color<0 | | color>15 | | color==transparentColor)返回;
uint16_t pos=(newY*宽度+newX)>>位移位;
如果(位置>缓冲区大小){
返回;
}
uint8_t shift=(newX&(pixelsPerByte-1))*比特像素;
uint8\u t掩码=位掩码
int16_t txtRotation=0;
float sin_angle=0;
float cos_angle=1; 

void MiniGrafx::setTextRotation(int16_t r) {
  int16_t txtAngle=r;
  Serial.print ("Text Angle=");
  Serial.println (txtAngle);
  do
  {
    if (txtAngle>=360) txtAngle=txtAngle-360; 
      Serial.println (txtAngle);
  }while (txtAngle>360);
    do
  {
    if (txtAngle<=-360) txtAngle=txtAngle+360; 
      Serial.println (txtAngle);
  }while (txtAngle<-360);
  if (txtAngle<0) txtAngle=360+txtAngle;
    txtRotation=txtAngle;

  switch (txtRotation){
    case 0:
      sin_angle=0;
      cos_angle=1;
    break;
    case 45:
      sin_angle=0.707106781;
      cos_angle=0.707106781;
    break;
    case 90:
      sin_angle=1;
      cos_angle=0;
    break;
    case 135:
      sin_angle=0.707106781;
      cos_angle=-0.707106781;
    break;
    case 180:
      sin_angle=0;
      cos_angle=-1;
    break;
    case 225:
      sin_angle=-0.707106781;
      cos_angle=-0.707106781;
    break;
    case 270:
      sin_angle=-1;
      cos_angle=0;
    break;
    case 315:
      sin_angle=-0.707106781;
      cos_angle=0.707106781;
    break;
    default: //compute sin and cos if not a cardinal direction.
      float angle_rad=0.017453*(float)txtRotation; //convert degrees to radians
      sin_angle = sin (angle_rad);          // Pre-calculate the time consuming sin
      cos_angle = cos (angle_rad);          // Pre-calculate the time consuming cosine
    break;
  }

}

void MiniGrafx::drawString(int16_t xMove, int16_t yMove, String strUser) {
  uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);

  // char* text must be freed!
  char* text = utf8ascii(strUser);

  uint16_t yOffset = 0;
  // If the string should be centered vertically too
  // we need to now how heigh the string is.
  if (textAlignment == TEXT_ALIGN_CENTER_BOTH) {
    uint16_t lb = 0;
    // Find number of linebreaks in text
    for (uint16_t i=0;text[i] != 0; i++) {
      lb += (text[i] == 10);
    }
    // Calculate center
    yOffset = (lb * lineHeight) >> 2;
  }

  uint16_t line = 0;
  char* textPart = strtok(text,"\n");
  while (textPart != NULL) {
    uint16_t length = strlen(textPart);
    drawStringInternal((xMove, yMove - yOffset + (line++) * lineHeight, textPart, length, getStringWidth(textPart, length));
    textPart = strtok(NULL, "\n");
  }
  free(text);
}

void MiniGrafx::drawStringInternal(int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth) {
  uint8_t textHeight       = pgm_read_byte(fontData + HEIGHT_POS);
  uint8_t firstChar        = pgm_read_byte(fontData + FIRST_CHAR_POS);
  uint16_t sizeOfJumpTable = pgm_read_byte(fontData + CHAR_NUM_POS)  * JUMPTABLE_BYTES;

  uint8_t cursorX         = 0;
  uint8_t cursorY         = 0;

  switch (textAlignment) {
    case TEXT_ALIGN_CENTER_BOTH:
      yMove -= textHeight >> 1;
    // Fallthrough
    case TEXT_ALIGN_CENTER:
      xMove -= textWidth >> 1; // divide by 2
      break;
    case TEXT_ALIGN_RIGHT:
      xMove -= textWidth;
      break;
  }

  // Don't draw anything if it is not on the screen.
  if (xMove + textWidth  < 0 || xMove > this->width ) {return;}
  if (yMove + textHeight < 0 || yMove > this->height) {return;}

  for (uint16_t j = 0; j < textLength; j++) {
    int16_t xPos = xMove + cursorX;
    int16_t yPos = yMove + cursorY;

    byte code = text[j];
    if (code >= firstChar) {
      byte charCode = code - firstChar;

      // 4 Bytes per char code
      byte msbJumpToChar    = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES );                  // MSB  \ JumpAddress
      byte lsbJumpToChar    = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_LSB);   // LSB /
      byte charByteSize     = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_SIZE);  // Size
      byte currentCharWidth = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_WIDTH); // Width

      // Test if the char is drawable
      if (!(msbJumpToChar == 255 && lsbJumpToChar == 255)) {
        // Get the position of the char data
        uint16_t charDataPosition = JUMPTABLE_START + sizeOfJumpTable + ((msbJumpToChar << 8) + lsbJumpToChar);
        drawInternal(xPos, yPos, currentCharWidth, textHeight, fontData, charDataPosition, charByteSize);
      }

      cursorX += currentCharWidth;
    }
  }
}

void MiniGrafx::setTextAlignment(TEXT_ALIGNMENT textAlignment) {
  this->textAlignment = textAlignment;
}

uint16_t MiniGrafx::getStringWidth(const char* text, uint16_t length) {
  uint16_t firstChar        = pgm_read_byte(fontData + FIRST_CHAR_POS);

  uint16_t stringWidth = 0;
  uint16_t maxWidth = 0;

  while (length--) {
    stringWidth += pgm_read_byte(fontData + JUMPTABLE_START + (text[length] - firstChar) * JUMPTABLE_BYTES + JUMPTABLE_WIDTH);
    if (text[length] == 10) {
      maxWidth = max(maxWidth, stringWidth);
      stringWidth = 0;
    }
  }
  return max(maxWidth, stringWidth);
}

void inline MiniGrafx::drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *data, uint16_t offset, uint16_t bytesInData) {
  if (width < 0 || height < 0) return;
  if (yMove + height < 0 || yMove > this->height)  return;
  if (xMove + width  < 0 || xMove > this->width)   return;

  uint8_t  rasterHeight = 1 + ((height - 1) >> 3); // fast ceil(height / 8.0)
  int8_t   yOffset      = yMove & 7;

  bytesInData = bytesInData == 0 ? width * rasterHeight : bytesInData;

  int16_t initYMove   = yMove;
  int8_t  initYOffset = yOffset;

  uint8_t arrayHeight = (int) ceil(height / 8.0);
  for (uint16_t i = 0; i < bytesInData; i++) {
    byte currentByte = pgm_read_byte(data + offset + i);

    for (int b = 0; b < 8; b++) {
      if(bitRead(currentByte, b)) {
        uint16_t currentBit = i * 8 + b;
        uint16_t pixelX = (i / arrayHeight);
        uint16_t pixelY = (i % arrayHeight) * 8;
        setPixel(pixelX + xMove, pixelY + yMove + b);
      }
    }
    yield();

  }
}

void MiniGrafx::setPixel(uint16_t x, uint16_t y) {

  uint16_t newX = (int) (((float)x * cos_angle) - ((float)y * sin_angle));
  uint16_t newY = (int) (((float)y * cos_angle) + ((float)x * sin_angle));

  if (newX >= width || newY >= height || newX < 0 || newY < 0 || color < 0 || color > 15 || color == transparentColor) return;
  uint16_t pos = (newY * width + newX) >> bitShift;
  if (pos > bufferSize) {
    return;
  }
  uint8_t shift = (newX & (pixelsPerByte - 1)) * bitsPerPixel;
  uint8_t mask = bitMask << shift;
  uint8_t palColor = color;
  palColor = palColor << shift;
  buffer[pos] = (buffer[pos] & ~mask) | (palColor & mask);
}