[vtkusers] Drawing a simple line graph (CONTINUES...)

Dean Inglis dean.inglis at camris.ca
Thu Jul 5 14:27:18 EDT 2007


Hi Isidro,

I found a few things that may help.
When you create your sine function
as a line, you should not use vtkLineSource
for this. vtkLineSource is really meant
for straight line segments: SetPoint1, and
SetPoint2 are all you are meant to have,
otherwise, there should be a SetNthPoint method.
The reason for not accessing the points from
the linesource is that in the pipeline, if
a request is made downstream, technically,
the linesource could rebuild itself and thereby
eliminate the point coordinates you set:


vtkLineSource *linea=vtkLineSource::New();
 for(int i=0;i<linea->GetOutput()->GetPoints()->GetNumberOfPoints();i++){
        linea->
         GetOutput()->
          GetPoints()->
           SetPoint(i,
                    i*resolucion,
                    (dim_ven[1]/2)*sin(i*resolucion*delta)+(dim_ven[1]/2),
                    0.0);}

The correct way to do this is to create a vtkPolyData from scratch,
using vtkPoints and vtkCellArray, something like:

    int segmentos = 100;

    int dim_ven[2]={600,400};

    double delta = 2.0*vtkMath::Pi()/((double)segmentos);
    double resolucion= (double)dim_ven[0]/((double)segmentos);

    vtkPoints* pts = vtkPoints::New();
    pts->SetNumberOfPoints(segmentos);

    vtkCellArray* array = vtkCellArray::New();
    array->Allocate( array->EstimateSize( segmentos , 2 ) );
    array->InsertNextCell( segmentos );

    for (int i = 0; i < segmentos; i++ )
      {
      pts->SetPoint(i, i*resolucion, dim_ven[1]*0.5*(sin(i*delta) + 1.0),
0.0);
      array->InsertCellPoint(i);
      }
    vtkPolyData* poly = vtkPolyData::New();
    poly->SetLines(array);
    poly->SetPoints(pts);
    poly->Update();
    array->Delete();
    pts->Delete();

As for the vtkActor2D, since you are setting up points in the
world coord system (no restriction on range/domain), you can do this:

    vtkCoordinate *tcoord = vtkCoordinate::New();
    tcoord->SetCoordinateSystemToWorld();

    vtkPolyDataMapper2D *mapper=vtkPolyDataMapper2D::New();
    mapper->SetInput( poly );
    mapper->ScalarVisibilityOff();
    mapper->SetTransformCoordinate( tcoord );
    tcoord->Delete();

    vtkActor2D *actor=vtkActor2D::New();
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(1.0,0.0,0.0);
    actor->GetProperty()->SetLineWidth( 2 );
    actor->GetPositionCoordinate()->SetCoordinateSystemToWorld();
    actor->GetPosition2Coordinate()->SetCoordinateSystemToWorld();
    actor->GetPosition2Coordinate()->SetReferenceCoordinate(NULL);

    double* bounds = poly->GetBounds();

    actor->GetPositionCoordinate()->SetValue(bounds[0],bounds[2],0);
    actor->GetPosition2Coordinate()->SetValue(bounds[1],bounds[3],0);

However, when I try this, I found it difficult to set up the
camera to correctly point at the actor2D:

    vtkCamera* cam = render->GetActiveCamera();
    cam->ParallelProjectionOn();

cam->SetPosition(0.5*(bounds[1]+bounds[0]),0.5*(bounds[3]+bounds[2]),100);

cam->SetFocalPoint(0.5*(bounds[1]+bounds[0]),0.5*(bounds[3]+bounds[2]),0);
    cam->SetViewUp(0,1,0);

even trying

    render->ResetCamera();
    render->ResetCameraClippingRange();

does not position the actor2D in the center of the viewport/renderer
(it is there, you just have to zoom out and pan to find it).
Why not use a vtkActor and avoid rendering in the overlay plane altogether?

Dean



More information about the vtkusers mailing list