We want to know the world coordinate of a point on a 3D widget event though we don’t know the widget’s position on the world coordinate system. I get a matrix from an actor and create a temporal vtkTransform object, then the function TransformDoublePoint can give me the real coordinate value of a single point on the 3D model. This is my solution for calculating real coordinate. It’s possible to get an inverse transform if we know coordinates of a point, the direction of the X-axis and the direction of the Y-axis of the 3D model. That means we have a second way to calculate the point’s position. For example, we have point (p0, p1, p2), vector (x0, x1, x2) and vector (y0, y1, y2). The third vector (z0, z1, z2) is the cross product result of vector1 and vector2.

For vtkTransform::Concatenate: In homogeneous matrix notation, M = M*A where M is the current transformation matrix and A is the applied matrix. The default is PreMultiply.

The local matrix can give us information about the coordinate system transform. Let’s read an example.

Before rotating plane:

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.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>
#include <vtkLinearTransform.h>
#include <vtkPlaneSource.h>

#include "tool.h"

using namespace std;

#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

vtkSmartPointer<vtkTransform> CreateLocalTrans(PointStruct origin, PointStruct xDir, PointStruct yDir)
{
    vtkSPtrNew( resultTrans, vtkTransform );
    PointStruct zDir = xDir ^ yDir;
    zDir.Unit();

    double elements1[16] = { xDir[0], xDir[1], xDir[2], 0,
                            yDir[0], yDir[1], yDir[2], 0,
                            zDir[0], zDir[1], zDir[2], 0,
                            0, 0, 0, 1 };

    resultTrans->Concatenate(elements1);     //rotation

    double elements2[16] = { 1, 0, 0, -origin[0],
                             0, 1, 0, -origin[1],
                             0, 0, 1, -origin[2],
                             0, 0, 0, 1 };

    resultTrans->Concatenate(elements2);    //translation
    resultTrans->Update();

    return resultTrans;
}

int main()
{
    setbuf( stdout, nullptr );

    // ============ plane start ================
    vtkSmartPointer<vtkPlaneSource> planeSource =
            vtkSmartPointer<vtkPlaneSource>::New();
    planeSource->SetOrigin( 0, 0, 0 ); //Relative
    planeSource->SetPoint1( 0, 2, 0 );
    planeSource->SetPoint2( 2, 0, 0 );

    vtkSmartPointer<vtkPolyDataMapper> planeMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    planeMapper->SetInputConnection( planeSource->GetOutputPort() );

    vtkSmartPointer<vtkActor> planeActor =
            vtkSmartPointer<vtkActor>::New();
    planeActor->SetMapper( planeMapper );
    //planeActor->SetPosition( 1, 1, 0 );
    // ============ plane end ================

    // ============ sphere start ================
    vtkSmartPointer<vtkSphereSource> sphereSource =
            vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetCenter( 2, 2, 0 );
    sphereSource->SetRadius( 0.1 );

    vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    sphereMapper->SetInputConnection( sphereSource->GetOutputPort() );

    vtkSmartPointer<vtkActor> sphereActor =
            vtkSmartPointer<vtkActor>::New();
    sphereActor->SetMapper( sphereMapper );
    sphereActor->GetProperty()->SetColor( 1, 0, 0 );
    // ============ plane end ================

    // Change actor status.
    planeActor->RotateY( 90 );

    // The first way
    vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
    transform->SetMatrix( planeActor->GetMatrix() );
    double pt1[3] = { 2, 2, 0 };
    double pt2[3] = { 1, 0, 0 };
    double *pt3 = transform->TransformDoublePoint( pt1 );
    printf( "(%lf, %lf, %lf)\n", pt3[0], pt3[1], pt3[2] );
    // (0.000000, 2.000000, -2.000000)

    // The second way
    PointStruct HomePt( 0, 0, 0 );
    PointStruct xPt( 0, 0, -1 );
    PointStruct yPt( 0, 1, 0 );
    vtkSmartPointer<vtkTransform> localTransform = CreateLocalTransform( HomePt, xPt, yPt );
    localTransform->Inverse();  // inverse get matrix's transform
    pt3 = localTransform->TransformDoublePoint( pt2 );
    printf( "(%lf, %lf, %lf)\n", pt3[0], pt3[1], pt3[2] );

    // localTransform
    // x: (0.000000, 0.000000, 1.000000)
    // y: (0.000000, 1.000000, 0.000000)
    // z: (-1.000000, 0.000000, 0.000000)

    // localTransform Inverse
    // x: (0.000000, 0.000000, -1.000000)
    // y: (0.000000, 1.000000, 0.000000)
    // z: (1.000000, 0.000000, 0.000000)

    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor( planeActor );
    renderer->AddActor( sphereActor );
    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;
}

After rotating plane:


0 0 votes
Article Rating
Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
trackback

[…] and at least two axis vectors to construct the transform. The example is similar to the article LOCAL COORDINATE SYSTEM […]

trackback

[…] write an article about how to create a local coordinate system for a dependent 3d model, LOCAL COORDINATE SYSTEM We can get real value in the world coordinate system of vector or point on the 3D model. For […]

Content Summary
: Input your strings, the tool can get a brief summary of the content for you.

X
2
0
Would love your thoughts, please comment.x
()
x