【VTK】vtkTextActor位置設置問題

在之前的文章【vtk】獲取vtkTextActor的長和寬 中我們知道了如何獲取text的長和寬。
本文討論vtkTextActor的size在變寬後,它的位置問題。
在vtkTextActor中,有提供SetPosition方法,從註釋可以看出,它的參數對應着actor的左下角座標。

/**
* Get the PositionCoordinate instance of vtkCoordinate.
* This is used for for complicated or relative positioning.
* The position variable controls the lower left corner of the Actor2D
*/
vtkViewportCoordinateMacro(Position);


#define vtkViewportCoordinateMacro(name) \
virtual vtkCoordinate *Get##name##Coordinate () \
{ \
    vtkDebugMacro(<< this->GetClassName() << " (" << this << "): returning " #name "Coordinate address " << this->name##Coordinate ); \
    return this->name##Coordinate; \
} \
virtual void Set##name(double x[2]) {this->Set##name(x[0],x[1]);} \
virtual void Set##name(double x, double y) \
{ \
    this->name##Coordinate->SetValue(x,y); \
} \
virtual double *Get##name() \
{ \
    return this->name##Coordinate->GetValue(); \
}

來看一個實驗:https://github.com/theArcticOcean/CLib/tree/master/VTKLearn/textActor
這個工程顯示了cone和text,紅色的text在window的左下角。
接着在PushButton的click函數中寫入這樣的功能:

void Widget::on_pushButton_clicked()
{
    textActor->SetInput( "hello\nworld\nmac" );

    double size[2];
    vtkRendererCollection *rendererCollection = ui->qvtkWidget->GetRenderWindow()->GetRenderers();
    vtkRenderer *renderer = rendererCollection->GetFirstRenderer();
    textActor->GetSize( renderer, size );
    printf( "size: %lf, %lf\n", size[0], size[1] );
    //renderer->Render();
    ui->qvtkWidget->GetRenderWindow()->Render();
}

在button click事件中,再增添兩行文字。
然後,重新獲取size數據,我們發現,textActor的確變寬了。但是它的位置並沒有變化,文字區域在向上伸展。

在這裏插入圖片描述

注意刷新方式:不要使用 renderer->Render(),而要 ui->qvtkWidget->GetRenderWindow()->Render(); (這裏的qvtkWidget是QVTKOpenGLWidget對象)
textActor默認的座標系是什麼?
不幸的是,我們不能用3D actor的方法來獲取默認座標系的信息:

vtkCoordinate *cd = textActor->GetMapper()->GetTransformCoordinate(); 
assert( nullptr != cd ); 
printf( "GetCoordinateSystemAsString: %s\n", cd->GetCoordinateSystemAsString() );

不過vtkActor2D有類似的方法:

  /**
   * Return the actual vtkCoordinate reference that the mapper should use
   * to position the actor. This is used internally by the mappers and should
   * be overridden in specialized subclasses and otherwise ignored.
   */
  virtual vtkCoordinate *GetActualPositionCoordinate(void)
    { return this->PositionCoordinate; }

然後通過

vtkCoordinate *cd = textActor->GetActualPositionCoordinate();
assert( nullptr != cd );
printf( "GetCoordinateSystemAsString: %s\n", cd->GetCoordinateSystemAsString() );

我們得到:GetCoordinateSystemAsString: Viewport
即, vtkActor2D默認的座標系統是viewport
但textActor->SetPosition2函數註釋,我們得知右上角點的座標是歸一化viewport座標,這一點值得注意。

  /**
   * Access the Position2 instance variable. This variable controls
   * the upper right corner of the Actor2D. It is by default
   * relative to Position and in normalized viewport coordinates.
   * Some 2D actor subclasses ignore the position2 variable
   */
  vtkViewportCoordinateMacro(Position2);

但是,如果textActor有設置對齊,比如豎直居中,從左到右顯示等,那麼SetPosition的作用點就 不是整片文字區域的左下角了
比如:

textActor->GetTextProperty()->SetJustificationToLeft();
textActor->GetTextProperty()->SetVerticalJustificationToCentered();

三行文字的顯示:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章