Zoom without scaling

I am creating a 3D scatterplot of spheres where each sphere might have a different size and spheres could overlap. I have a 2D implementation of this in Qt using circles where as I zoom in, the circles remain a constant size. This has the effect that overlapped circles can be resolved since they appear to “move apart” as the zoom increases.

Is it possible to do the same in vtk? I came across this previous post by Paolo Carvalho which seems similar to what I need:

Will an adaptation of this method do what I need? In his solution, the actor is repeatedly destroyed and recreated during each interaction since it is a pick operation, but I assume I could simply set the actor once it is created to render my spheres and repeatedly rescale it, correct?

Thanks for any advice.

Hi David,

In the method that you refer to the actor is not destroyed and re-created. It is just scaled.

on camera move:

  • loop over all the actors
  • For each actor, calculate the required scale based on the distance to the camera
  • Set the scale

Thanks for the reply.

The code in the post quoted above is basically just the scaling part. In the full implementation by Paolo in gammaray, the actor is destroyed and recreated during handling of the left button up event:

void v3dMouseInteractor::OnLeftButtonUp()
{
    // Don't pick during dragging.
    if( ! m_isDragging ){

        //Remove the marker actor anyway.
        if( m_pickMarkerActor ) {
            this->GetDefaultRenderer()->RemoveActor( m_pickMarkerActor );
            m_pickMarkerActor = nullptr;
        }

 // ...

                    // (Re)create an actor for the pick marker.
                    m_pickMarkerActor = vtkSmartPointer<vtkActor>::New();
                    m_pickMarkerActor->GetProperty()->SetColor(1.0, 0.0, 0.0);
                    m_pickMarkerActor->SetPosition( pos );
                    m_pickMarkerActor->SetMapper(mapper);

                    // Adds the pick marker to the scene.
                    this->GetDefaultRenderer()->AddActor( m_pickMarkerActor );

                    // Rescale the actor so it stays with a constant size with respect to the canvas
                    // independently of zoom.
                    rescalePickMarkerActor();
                }
// ...

But yes, you are correct that I can do what I need with a permanent actor. In the code mentioned, the actor is needed only during the pick operation, so it makes sense to destroy it when no longer needed.

Hi, David,

In GammaRay I only re-create the actor to make sure the actor gets removed if the user picks an empty area. It is not a requirement for the rescalePickMarkerActor() function to work. In your case, you’d have to loop over all your scatter plot sphere actors applying the computation as they are certainly at different distances to the camera.

regards,

Paulo