[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