# [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

```