很高兴在雪易的CSDN遇见你
VTK技术爱好者 QQ:870202403
前言
本文分享vtkCoordinate源码解析,并对VTK中的各种坐标变换进行分析,希望对各位小伙伴有所帮助!
感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!
你的点赞就是我的动力(^U^)ノ~YO
1. vtkCoordinate
在VTK的各种坐标系统中,执行坐标变换,并表示位置(Position)。也可以创建一个相互引用的vtkCoordinate对象。
vtkCoordinate对象允许引用,即一个vtkCoordinate对象A可以引用另一个vtkCoordinate对象B,vtkCoordinate对象B也可以引用其他vtkCoordinate对象,依此类推,但是不能形成自循环。这允许你创建像vtkActor2D这样的组合组,它们的位置相对于另一个。注意,在级联序列中,每个vtkCoordinate对象可以在不同的坐标系中指定!。例如在vtkCaptionActor2D的定义中AttachmentPointCoordinate在WORLD坐标系中指定;PositionCoordinate在DISPLAY坐标系中指定。
VTK中的坐标系统有如下几种:
DISPLAY坐标系统:表示在窗口上的x,y的像素值
最小值:(0, 0)表示左下角的第一个像素。
最大值:(Size,Size)表示右上角的最后一个像素
NORMALIZED DISPLAY坐标系统:表示归一化后的窗口像素值。
最小值:(0, 0)表示左下角的第一个像素。
最大值:(1,1)表示右上角的最后一个像素
VIEWPORT坐标系统:表示Viewport上的x,y像素值
最小值:(0, 0)表示左下角的第一个像素。
最大值:(Size,Size)表示右上角的最后一个像素
NORMALIZED VIEWPORT坐标系统:表示归一化后的Viewport的像素值
最小值:(0, 0)表示左下角的第一个像素。
最大值:(1,1)表示右上角的最后一个像素
POSE坐标系统:WORLD坐标系统相对于相机位置和View方向进行的移动和旋转坐标系统。
VIEW坐标系统:相机所看到的坐标系统,取值为【-1,1】。x,y值表示像平面上的位置,Z值表示到相机的距离。相机负责将WORLD坐标系变换到VIEW坐标系。
WORLD坐标系统:世界坐标系
USERDEFINED坐标系统:表示在用户定义的坐标系统下的值。
2. VTK中各坐标系统关系
Model坐标系统:指定义模型时所采用的坐标系统。
World坐标系统:放置Actor的三维空间系统。
vtkActor负责将模型从Model坐标系转化到World坐标系。
VTK中一个窗口可以放置多个Renderer(即ViewPort)。
renderer1->SetViewport(0.,0.,0.5,0.5);
renderer1->SetViewport(0.,0.5,0.5,1.0);
renderer1->SetViewport(0.5,0.,1.,0.5);
renderer1->SetViewport(0.5,0.5,1.0,1.0);
3. vtkCoordinate重要参数
3.1 设置/获取当前的坐标系统
//@{
/**
* Set/get the coordinate system which this coordinate
* is defined in. The options are Display, Normalized Display,
* Viewport, Normalized Viewport, View, and World.
*/
vtkSetMacro(CoordinateSystem, int);
vtkGetMacro(CoordinateSystem, int);
void SetCoordinateSystemToDisplay() { this->SetCoordinateSystem(VTK_DISPLAY); }
void SetCoordinateSystemToNormalizedDisplay()
{
this->SetCoordinateSystem(VTK_NORMALIZED_DISPLAY);
}
void SetCoordinateSystemToViewport() { this->SetCoordinateSystem(VTK_VIEWPORT); }
void SetCoordinateSystemToNormalizedViewport()
{
this->SetCoordinateSystem(VTK_NORMALIZED_VIEWPORT);
}
void SetCoordinateSystemToView() { this->SetCoordinateSystem(VTK_VIEW); }
void SetCoordinateSystemToPose() { this->SetCoordinateSystem(VTK_POSE); }
void SetCoordinateSystemToWorld() { this->SetCoordinateSystem(VTK_WORLD); }
//@}
const char* GetCoordinateSystemAsString();
3.2 设置/获取坐标值
//@{
/**
* Set/get the value of this coordinate. This can be thought of as
* the position of this coordinate in its coordinate system.
*/
vtkSetVector3Macro(Value, double);
vtkGetVector3Macro(Value, double);
void SetValue(double a, double b) { this->SetValue(a, b, 0.0); }
//@}
3.3 设置/获取参考坐标系
//@{
/**
* If this coordinate is relative to another coordinate,
* then specify that coordinate as the ReferenceCoordinate.
* If this is NULL the coordinate is assumed to be absolute.
* 若该坐标A关联其他坐标B,则将坐标B设置为参考坐标;
* 若参考坐标为孔,则该坐标A是绝对坐标系统下的坐标
*/
virtual void SetReferenceCoordinate(vtkCoordinate*);
vtkGetObjectMacro(ReferenceCoordinate, vtkCoordinate);
//@}
3.4 设置关联的Viewport
//@{
/** 设置关联的viewport
* If you want this coordinate to be relative to a specific
* vtkViewport (vtkRenderer) then you can specify that here.
* NOTE: this is a raw pointer, not a weak pointer nor a reference counted
* object, to avoid reference cycle loop between rendering classes and filter
* classes.
*/
void SetViewport(vtkViewport* viewport);
vtkGetObjectMacro(Viewport, vtkViewport);
//@}
3.5 获取各坐标系下的值
//@{
/**
* Return the computed value in a specified coordinate system.
*/
double* GetComputedWorldValue(vtkViewport*) VTK_SIZEHINT(3);
int* GetComputedViewportValue(vtkViewport*) VTK_SIZEHINT(2);
int* GetComputedDisplayValue(vtkViewport*) VTK_SIZEHINT(2);
int* GetComputedLocalDisplayValue(vtkViewport*) VTK_SIZEHINT(2);
//@}
double* GetComputedDoubleViewportValue(vtkViewport*) VTK_SIZEHINT(2);
double* GetComputedDoubleDisplayValue(vtkViewport*) VTK_SIZEHINT(2);
/**
* GetComputedValue() will return either World, Viewport or
* Display based on what has been set as the coordinate system.
* This is good for objects like vtkLineSource, where the
* user might want to use them as World or Viewport coordinates.
*/
double* GetComputedValue(vtkViewport*) VTK_SIZEHINT(3);
/**
* GetComputedUserDefinedValue() is to be used only when
* the coordinate system is VTK_USERDEFINED. The user
* must subclass vtkCoordinate and override this function,
* when set as the TransformCoordinate in 2D-Mappers, the user
* can customize display of 2D polygons
*/
virtual double* GetComputedUserDefinedValue(vtkViewport*) VTK_SIZEHINT(3) { return this->Value; }
4. vtkViewport进行坐标变换
上面RenderWindow的尺寸为(300,300),白色方框的Display坐标为(150,150),执行下面代码为:
double XF = eventPos[0]; //XF = 150
double YF = eventPos[1]; //YF = 150
// convert to normalized viewport coordinates
this->Renderer->DisplayToNormalizedDisplay(XF, YF); //XF = 150/300.=0.5;YF = 0.5;
this->Renderer->NormalizedDisplayToViewport(XF, YF);//XF = 150;YF=150
this->Renderer->ViewportToNormalizedViewport(XF, YF);//XF=0.5;YF=0.5;
void vtkViewport::DisplayToNormalizedDisplay(double& u, double& v)
{
if (this->VTKWindow)
{
/* get physical window dimensions */
const int* size = this->VTKWindow->GetSize();
if (size && size[0] != 0 && size[1] != 0)
{
u = u / size[0];
v = v / size[1];
}
}
}
//----------------------------------------------------------------------------
void vtkViewport::NormalizedDisplayToViewport(double& u, double& v)
{
if (this->VTKWindow)
{
// get the pixel value for the viewport origin
double vpou, vpov;
vpou = this->Viewport[0];
vpov = this->Viewport[1];
this->NormalizedDisplayToDisplay(vpou, vpov);
// get the pixel value for the coordinate
this->NormalizedDisplayToDisplay(u, v);
// subtract the vpo
u = u - vpou;
v = v - vpov;
}
}
//----------------------------------------------------------------------------
void vtkViewport::ViewportToNormalizedViewport(double& u, double& v)
{
if (this->VTKWindow)
{
/* get physical window dimensions */
/*
double vpsizeu, vpsizev;
const int *size = this->VTKWindow->GetSize();
vpsizeu = size[0]*(this->Viewport[2] - this->Viewport[0]);
vpsizev = size[1]*(this->Viewport[3] - this->Viewport[1]);
u = u/(vpsizeu - 1.0);
v = v/(vpsizev - 1.0);
*/
const int* size = this->GetSize();
if (size && size[0] != 0 && size[1] != 0)
{
u = u / size[0];
v = v / size[1];
}
}
}
结论:
理解坐标变换是VTK用好的基础,小伙伴一定要理解。
感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!
你的赞赏是我的最最最最大的动力(^U^)ノ~YO