Change coordinate system from right to left-handed (change direction of Z axis)

Hi,

VTK standard coordinate system is right-handed wich means that cross product X * Y gives Z (like in the picture).

image

I’m wondering is there is a way to change the native right-handed VTK coordinate system to left-handed (such that X * Y = -Z)?

I have to notice that this is not a matter of camera position but this rather a question about setting global VTK coordinates directions (set each axis increase and decrease directions).

Also simply renaming names of vtkAxisActor doesn’t solve the problem beacause I have many actors and rotating each of them is a bad idea I think.

If someone has ideas - please share

Regards

This example may help AnatomicalOrientation. The top-left cube is left-handed.

If you are changing the handedness of the data then you need to a apply a transform that either reverses the direction of one of the axes, say Z, or swaps two axes e.g swap X and Y.
For example, look at TransformSphere and change aTransform->Scale(1, 1.5, 2); to aTransform->Scale(1, 1.5, -2); thereby changing the data from RH to LH. Now the image is black since the normals are pointing the wrong way because the surface shading uses the right-hand rule. So you need to apply a reverse sense filter:

  transFilter->SetTransform(aTransform);

  vtkNew<vtkReverseSense> reverse;
  reverse->SetInputConnection(transFilter->GetOutputPort());
  reverse->ReverseNormalsOn();

  vtkNew<vtkElevationFilter> colorIt;
  //colorIt->SetInputConnection(transFilter->GetOutputPort());
  colorIt->SetInputConnection(reverse->GetOutputPort());

Hi @amaclean,

From your post I made one conclusion:

VTK uses Right-Handed coordinate system and we cannot simply change this internal coordinate system. If we need to work with Left-Handed system then we need make some transformations with every displayed VTK object (or actor). Is this true or I misunderstood you?

If this is true then woudn’t it be easier and faster to apply scale to all displayed actors like actor->SetScale(1, 1, -1); and thus making coordinates of those actors LH (including vtkAxisActor)? When I say easier and faster I mean easier and faster compared to transformations on data (in my case vtkImageData).

I’m going to work with quite big vtkImageData of size from N*100 Megabites to 10-20 Gygabite vtkImageData. So the main goal of RH to LH coord. sys. transformation is to decrease CPU load and RAM load.

I don’t have much experience of working with VTK but I could not lauch my vtkImageData with proposed by you vtkReverseSense. I get error (I use Qt):

Here is my code:

    vtkSmartPointer<vtkImageData> image =
            vtkSmartPointer<vtkImageData>::New();
    int nx = 3;
    int ny = 4;
    int nz = 5;
    int N = nx*ny*nz;
    image->SetDimensions(nx, ny, nz);
    image->SetSpacing(1.0, 1.0, 1.0);
    image->SetOrigin(0.0, 0.0, 0.0);

    vtkNew<vtkDoubleArray> array;
    array->SetName("Name");
    for (int i = 0; i < N; i++){
        array->InsertNextValue(i);
    }

    image->GetPointData()->SetScalars(array);

    // Map the scalar values in the image to colors with a lookup table:
    vtkSmartPointer<vtkLookupTable> lut =
            vtkSmartPointer<vtkLookupTable>::New();
    lut->SetNumberOfTableValues(256);
    lut->SetRange(0.0, N-1);
    lut->Build();

    // Pass the original image and the lookup table to a filter to create
    // a color image:
    vtkSmartPointer<vtkImageMapToColors> scalarValuesToColors =
            vtkSmartPointer<vtkImageMapToColors>::New();
    scalarValuesToColors->SetLookupTable(lut);
    scalarValuesToColors->PassAlphaToOutputOn();
    scalarValuesToColors->SetInputData(image);

    /*_____________________*/

    vtkNew<vtkTransform> aTransform;
    aTransform->Scale(1, 1, -1);

    vtkNew<vtkTransformFilter> transFilter;
    transFilter->SetInputData(image);
//    transFilter->SetInputConnection(scalarValuesToColors->GetOutputPort());
    transFilter->SetTransform(aTransform);

    vtkNew<vtkReverseSense> reverse;
    reverse->SetInputConnection(transFilter->GetOutputPort());
    reverse->ReverseNormalsOn();

    vtkNew<vtkElevationFilter> colorIt;
//    colorIt->SetInputConnection(transFilter->GetOutputPort());
    colorIt->SetInputConnection(reverse->GetOutputPort());
    colorIt->SetLowPoint(0, 0, -1);
    colorIt->SetHighPoint(0, 0, 1);

    /*_____________________*/

    vtkSmartPointer<vtkDataSetMapper> mapper =
            vtkSmartPointer<vtkDataSetMapper>::New();
    mapper->SetInputConnection(colorIt->GetOutputPort());

    // Create an image actor
    vtkSmartPointer<vtkActor> actor =
            vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    volumeWidget->vtkWidget->renderWindow()->GetRenderers()->
            GetFirstRenderer()->AddActor(actor);