1. class MyRubberBand : public vtkInteractorStyleRubberBand2D 
  2. public: 
  3.     static MyRubberBand* New(); 
  4.     vtkTypeMacro(MyRubberBand, vtkInteractorStyleRubberBand2D); 
  5.  
  6.     virtual void OnLeftButtonDown() 
  7.     { 
  8.         vtkInteractorStyleRubberBand2D::OnLeftButtonDown(); //必须有这一句
  9.         startPosition[0] = this->GetInteractor()->GetEventPosition()[0]; 
  10.         startPosition[1] = this->GetInteractor()->GetEventPosition()[1]; 
  11.         startPosition[2] = 0; 
  12.     } 
  13.     virtual void OnLeftButtonUp()  
  14.     { 
  15.         vtkInteractorStyleRubberBand2D::OnLeftButtonUp(); //必须有这一句
  16.         endPosition[0] = this->GetInteractor()->GetEventPosition()[0]; 
  17.         endPosition[1] = this->GetInteractor()->GetEventPosition()[1]; 
  18.         endPosition[2] = 0; 
  19.         std::cout<<"Position"<<endPosition[0]<<"  "<<endPosition[1]<<std::endl
  20.  
  21.         this->viewer->GetRenderer()->SetDisplayPoint(startPosition); 
  22.         this->viewer->GetRenderer()->DisplayToView(); 
  23.         this->viewer->GetRenderer()->ViewToWorld(); 
  24.  
  25.         double start[4]; 
  26.         this->viewer->GetRenderer()->GetWorldPoint(start); 
  27.  
  28.  
  29.         this->viewer->GetRenderer()->SetDisplayPoint(endPosition); 
  30.         this->viewer->GetRenderer()->DisplayToView(); 
  31.         this->viewer->GetRenderer()->ViewToWorld(); 
  32.  
  33.         double end[4]; 
  34.         this->viewer->GetRenderer()->GetWorldPoint(end); 
  35.  
  36.  
  37.         double point1[3]; 
  38.         double point2[3]; 
  39.         double point3[3]; 
  40.         double point4[3]; 
  41.  
  42.         double left[2]; 
  43.         double right[2]; 
  44.  
  45.         left[0] = start[0]<=end[0] ? start[0] : end[0]; 
  46.         left[1] = start[1]<=end[1] ? start[1] : end[1]; 
  47.  
  48.         right[0] = start[0]>end[0] ? start[0] : end[0]; 
  49.         right[1] = start[1]>end[1] ? start[1] : end[1]; 
  50.  
  51.         point1[0] = left[0];  point1[1] = left[1];  point1[2] = 0; 
  52.         point2[0] = left[0];  point2[1] = right[1]; point2[2] = 0; 
  53.         point3[0] = right[0]; point3[1] = right[1]; point3[2] = 0; 
  54.         point4[0] = right[0]; point4[1] = left[1];  point4[2] = 0; 
  55.  
  56.         this->SetLine(point1,point2); 
  57.         this->SetLine(point2,point3); 
  58.         this->SetLine(point3,point4); 
  59.         this->SetLine(point4,point1); 
  60.  
  61.     } 
  62.     void SetLine(double point1[],double point2[]) 
  63.     { 
  64.         vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New(); 
  65.         lineSource->SetPoint1(point1); 
  66.         lineSource->SetPoint2(point2); 
  67.         lineSource->Update(); 
  68.  
  69.         vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); 
  70.         mapper->SetInputConnection(lineSource->GetOutputPort()); 
  71.         vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); 
  72.         actor->SetMapper(mapper); 
  73.         actor->GetProperty()->SetLineWidth(2); 
  74.         actor->GetProperty()->SetColor(1.0,0.0,0.0); 
  75.  
  76.         this->viewer->GetRenderer()->AddActor(actor); 
  77.         this->viewer->Render(); 
  78.     } 
  79.     vtkImageViewer2* viewer; 
  80. // 
  81. private: 
  82.     double startPosition[3]; 
  83.     double endPosition[3]; 
  84.  
  85. }; 

要点:

1.在重新实现的onLeftButtonDown()函数中,必须调用 vtkInteractorStyleRubberBand2D::OnLeftButtonDown(); 否则无法交互;onLeftButtonUp()函数同理;

2.通过 this->GetInteractor()->GetEventPosition()得到的是屏幕坐标,必须先将其转换成世界坐标,否则矩形位置并不正确;

3.viewer->SetupInteractor(iren)必须置于iren->SetInteractorStyle(style)之前,否者viewer还使用原来的InteractorStyle