- class MyRubberBand : public vtkInteractorStyleRubberBand2D
- {
- public:
- static MyRubberBand* New();
- vtkTypeMacro(MyRubberBand, vtkInteractorStyleRubberBand2D);
- virtual void OnLeftButtonDown()
- {
- vtkInteractorStyleRubberBand2D::OnLeftButtonDown(); //必须有这一句
- startPosition[0] = this->GetInteractor()->GetEventPosition()[0];
- startPosition[1] = this->GetInteractor()->GetEventPosition()[1];
- startPosition[2] = 0;
- }
- virtual void OnLeftButtonUp()
- {
- vtkInteractorStyleRubberBand2D::OnLeftButtonUp(); //必须有这一句
- endPosition[0] = this->GetInteractor()->GetEventPosition()[0];
- endPosition[1] = this->GetInteractor()->GetEventPosition()[1];
- endPosition[2] = 0;
- std::cout<<"Position"<<endPosition[0]<<" "<<endPosition[1]<<std::endl;
- this->viewer->GetRenderer()->SetDisplayPoint(startPosition);
- this->viewer->GetRenderer()->DisplayToView();
- this->viewer->GetRenderer()->ViewToWorld();
- double start[4];
- this->viewer->GetRenderer()->GetWorldPoint(start);
- this->viewer->GetRenderer()->SetDisplayPoint(endPosition);
- this->viewer->GetRenderer()->DisplayToView();
- this->viewer->GetRenderer()->ViewToWorld();
- double end[4];
- this->viewer->GetRenderer()->GetWorldPoint(end);
- double point1[3];
- double point2[3];
- double point3[3];
- double point4[3];
- double left[2];
- double right[2];
- left[0] = start[0]<=end[0] ? start[0] : end[0];
- left[1] = start[1]<=end[1] ? start[1] : end[1];
- right[0] = start[0]>end[0] ? start[0] : end[0];
- right[1] = start[1]>end[1] ? start[1] : end[1];
- point1[0] = left[0]; point1[1] = left[1]; point1[2] = 0;
- point2[0] = left[0]; point2[1] = right[1]; point2[2] = 0;
- point3[0] = right[0]; point3[1] = right[1]; point3[2] = 0;
- point4[0] = right[0]; point4[1] = left[1]; point4[2] = 0;
- this->SetLine(point1,point2);
- this->SetLine(point2,point3);
- this->SetLine(point3,point4);
- this->SetLine(point4,point1);
- }
- void SetLine(double point1[],double point2[])
- {
- vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
- lineSource->SetPoint1(point1);
- lineSource->SetPoint2(point2);
- lineSource->Update();
- vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
- mapper->SetInputConnection(lineSource->GetOutputPort());
- vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
- actor->SetMapper(mapper);
- actor->GetProperty()->SetLineWidth(2);
- actor->GetProperty()->SetColor(1.0,0.0,0.0);
- this->viewer->GetRenderer()->AddActor(actor);
- this->viewer->Render();
- }
- vtkImageViewer2* viewer;
- //
- private:
- double startPosition[3];
- double endPosition[3];
- };
要点:
1.在重新实现的onLeftButtonDown()函数中,必须调用 vtkInteractorStyleRubberBand2D::OnLeftButtonDown(); 否则无法交互;onLeftButtonUp()函数同理;
2.通过 this->GetInteractor()->GetEventPosition()得到的是屏幕坐标,必须先将其转换成世界坐标,否则矩形位置并不正确;
3.viewer->SetupInteractor(iren)必须置于iren->SetInteractorStyle(style)之前,否者viewer还使用原来的InteractorStyle。