对于vtkTransform,前乘设置,或后乘设置对点的映射计算的结果没有影响。
因为对于4*4的矩阵乘法,结果是一样的.
看下面的代码,如果将参数a和参数b换个位置,数组c存储的结果是不会变化的。

//----------------------------------------------------------------------------
// Multiplies matrices a and b and stores the result in c.
inline void vtkMatrix4x4::Multiply4x4(const double a[16], const double b[16],
                                      double c[16])
{
  double tmp[16];

  for (int i = 0; i < 16; i += 4)
  {
    for (int j = 0; j < 4; j++)
    {
      tmp[i + j] = a[i + 0] * b[j + 0] +
                   a[i + 1] * b[j + 4] +
                   a[i + 2] * b[j + 8] +
                   a[i + 3] * b[j + 12];
    }
  }

  for (int k = 0; k < 16; k++)
  {
    c[k] = tmp[k];
  }
}

vtkTransform的一些操作,比如rotate,最终都是调用了该函数:

void vtkTransform::RotateWXYZ(double angle, double x, double y, double z)
=>
void vtkTransformConcatenation::Rotate(double angle, double x, double y, double z)
=>
void vtkTransformConcatenation::Concatenate(const double elements[16])
=>
inline void vtkMatrix4x4::Multiply4x4(const double a[16], const double b[16], double c[16])

实验代码:

#include <stdio.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkPlaneSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkActor2D.h>
#include <vtkTransform.h>

using namespace std;

int main()
{
    setbuf( stdout, NULL );
    vtkSmartPointer<vtkPlaneSource> plane =
            vtkSmartPointer<vtkPlaneSource>::New();

    vtkSmartPointer<vtkPolyDataMapper> mapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection( plane->GetOutputPort() );

    vtkSmartPointer<vtkActor> actor =
            vtkSmartPointer<vtkActor>::New();
    actor->SetMapper( mapper );

    double oldNormal[3] = { 0, -1, 0 };
    printf( "oldNormal: %lf, %lf, %lf\n", oldNormal[0], oldNormal[1], oldNormal[2] );

    vtkSmartPointer<vtkTransform> transform2 =
            vtkSmartPointer<vtkTransform>::New();
    transform2->SetMatrix( actor->GetMatrix() );
    transform2->PostMultiply();
    transform2->RotateZ( -90 );

/*
 * No PreMultiply:
oldNormal: 0.000000, -1.000000, 0.000000
newNormal: -1.000000, -0.000000, 0.000000

Has PreMultiply:
oldNormal: 0.000000, -1.000000, 0.000000
newNormal: -1.000000, -0.000000, 0.000000

Has PostMultiply:
oldNormal: 0.000000, -1.000000, 0.000000
newNormal: -1.000000, -0.000000, 0.000000
*/

    double *newNormal = transform2->TransformDoubleVector( oldNormal );
    printf( "newNormal: %lf, %lf, %lf\n", newNormal[0], newNormal[1], newNormal[2] );

    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->SetBackground( 0, 0, 0 );

    vtkSmartPointer<vtkRenderWindow> renderWindow =
            vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer( renderer );

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow( renderWindow );

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}

分类: C plus plus

发表评论

电子邮件地址不会被公开。 必填项已用*标注