[vtkusers] Question about surface normal
David Doria
daviddoria+vtk at gmail.com
Thu Nov 5 09:16:46 EST 2009
On Thu, Nov 5, 2009 at 9:07 AM, Luca Pamparana <luca.pamparana at gmail.com> wrote:
> Hello everyone,
>
> Started playing with vtk recently and have a simple code that simply
> draws a 2D plane in 3D space. I am using vtkPolyData class and using a
> vtkActor to render it.
>
> This might be more of a geometry question. So, what I want to do is
> have the surface normal point to a given point in 3D space. For
> example, I might want the normal to point to the origin of my 3D
> scene. Does anyone know how I might be able to calculate that.
>
> Here is the bit of code that I have so far, which I have hacked
> together after looking at some VTK examples.
>
>
> // Code starts
> #include "vtkPoints.h"
> #include "vtkCellArray.h"
> #include "vtkPolyData.h"
> #include "vtkPolyDataMapper.h"
> #include "vtkActor.h"
> #include "vtkRenderWindow.h"
> #include "vtkRenderWindowInteractor.h"
> #include "vtkRenderer.h"
> #include "vtkProperty.h"
>
>
> int main()
> {
> vtkPolyData * geometry = vtkPolyData::New();
> vtkPoints * testPoints = vtkPoints::New();
> testPoints->Allocate(4);
> vtkCellArray *testPolys = vtkCellArray::New();
> testPolys->Allocate(testPolys->EstimateSize(1,4));
> double x[3];
> vtkIdType pts[4];
> x[0] = -2.5;
> x[1] = -2.5;
> x[2] = -2.5;
> testPoints->InsertNextPoint(x);
> x[0] = 2.5;
> x[1] = -2.5;
> x[2] = -2.5;
> testPoints->InsertNextPoint(x);
> x[0] = -2.5;
> x[1] = 2.5;
> x[2] = -2.5;
> testPoints->InsertNextPoint(x);
> x[0] = 2.5;
> x[1] = 2.5;
> x[2] = -2.5;
> testPoints->InsertNextPoint(x);
>
> pts[0] = 0; pts[1] = 2; pts[2] = 3; pts[3] = 1;
> testPolys->InsertNextCell(4,pts);
> geometry->SetPoints(testPoints);
> testPoints->Delete();
> testPolys->Squeeze();
> geometry->SetPolys(testPolys);
> testPolys->Delete();
>
> vtkRenderer *renderer = vtkRenderer::New();
> vtkRenderWindow *renWin = vtkRenderWindow::New();
> renWin->AddRenderer(renderer);
> vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
> iren->SetRenderWindow(renWin);
>
> vtkPolyDataMapper * testMapper = vtkPolyDataMapper::New();
> testMapper->SetInput(geometry);
>
> vtkActor * testActor = vtkActor::New();
> testActor->SetMapper(testMapper);
> testActor->GetProperty()->SetColor(1, 0, 0);
> renderer->AddActor(testActor);
> renderer->SetBackground(1,1,1);
> renWin->SetSize(300,300);
>
> renWin->Render();
>
> iren->Start();
>
> testActor->Delete();
> testMapper->Delete();
> iren->Delete();
> renWin->Delete();
> renderer->Delete();
> return 0;
> }
> // Code ends
>
> Looking forward to your help.
>
> Sincerely,
>
> Luc
Luc
In this simple case, could you consider using a plane? Then you can
specify the normal directly
http://www.vtk.org/Wiki/Plane
See this example for a little bit cleaner way of adding points/cells
to a polydata. It also demonstrates the vtkSmartPointer so you don't
have to do your own memory management.
http://www.vtk.org/Wiki/Polygon
This could also be a very helpful function for you (maybe we can add
this to vtkMath or somewhere?). It takes two vectors and finds the
transformation that brings the first to the second using a landmark
transform:
vtkTransform* AlignRays(double* Ray1, double* Ray2)
{
//This function takes two rays and finds the matrix M between them
(from Ray1 to Ray2)
vtkMath::Normalize(Ray1);
vtkMath::Normalize(Ray2);
vtkLandmarkTransform* LandmarkTransform = vtkLandmarkTransform::New();
vtkPoints* SourcePoints = vtkPoints::New();
vtkPoints* TargetPoints = vtkPoints::New();
double Origin[3] = {0.0, 0.0, 0.0};
//setup ray 1
SourcePoints->InsertNextPoint(Origin);
SourcePoints->InsertNextPoint(Ray1);
TargetPoints->InsertNextPoint(Origin);
TargetPoints->InsertNextPoint(Ray2);
LandmarkTransform->SetSourceLandmarks(SourcePoints);
LandmarkTransform->SetTargetLandmarks(TargetPoints);
LandmarkTransform->SetModeToRigidBody();
LandmarkTransform->Update();
vtkMatrix4x4* M = LandmarkTransform->GetMatrix();
vtkTransform* Transform = vtkTransform::New();
Transform->SetMatrix(M);
//clean up
SourcePoints->Delete();
TargetPoints->Delete();
LandmarkTransform->Delete();
return Transform;
}
Good luck.
David
More information about the vtkusers
mailing list