鼠标交互事件:点两个点形成一条线
通过鼠标点两个点,同时标记这两个点,形成一条线。(只有一条线,并不是每次点两个点都会新出现一条线)
这个版本是个初级版本,(后面我也实现了任意拖动一个点,直线会相应发生变化,以及两点在Z轴上的变动,线也会同步更新)。代码太多所以我也没有贴上来,有需要了我会发出来!
double point1[3]{ 0 };double point2[3]{ 0 };double point3[3]{ 0 };double p[3]{ 0 };
double WorldPointbegin[3]{ 0 };double WorldPointend[3]{ 0 };
int *clickPosbegin;int *clickPosend;int *click;
class customMouseInteractorStyle : public vtkInteractorStyleTrackballCamera{
public:
static customMouseInteractorStyle* New();
vtkTypeMacro(customMouseInteractorStyle, vtkInteractorStyleTrackballCamera);
protected:
;
public:
vtkPolyDataMapper *lineMapper = vtkPolyDataMapper::New();
vtkSmartPointer<vtkActor> lineActor=vtkSmartPointer<vtkActor>::New();
vtkSmartPointer<vtkLineSource> lineSource= vtkSmartPointer<vtkLineSource>::New();
virtual void OnLeftButtonDown(){
if(i==0){
//打印鼠标左键像素位置
clickPosbegin = this->Interactor->GetEventPosition();
point1[0]=clickPosbegin[0];
point1[1]=clickPosbegin[1];
std::cout << "clickPosbegin: " << this->Interactor->GetEventPosition()[0]
<< " " << this->Interactor->GetEventPosition()[1] << std::endl;
//注册拾取点函数
this->Interactor->GetPicker()->Pick(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1], 0, // always zero.
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
//打印拾取点空间位置
this->Interactor->GetPicker()->GetPickPosition(WorldPointbegin);
std::cout << "WorldPointbegin :" << WorldPointbegin[0] << "," << WorldPointbegin[1] << "," << WorldPointbegin[2] << std::endl;
//对拾取点进行标记
sphereSourcebegin->Update();
mapperbegin->SetInputConnection(sphereSourcebegin->GetOutputPort());
actorbegin->SetMapper(mapperbegin);
actorbegin->SetPosition(WorldPointbegin);
actorbegin->SetScale(4);
actorbegin->GetProperty()->SetColor(1.0, 0.0, 1.0);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actorbegin);
renderer->GetRenderWindow()->GetInteractor()->Initialize();
renderer->GetRenderWindow()->GetInteractor()->Render();
i=1;
}
else if(i==1)
{
//打印鼠标左键像素位置
clickPosend = this->Interactor->GetEventPosition();
point2[0]=clickPosend[0];
point2[1]=clickPosend[1];
std::cout << "clickPosend: " << this->Interactor->GetEventPosition()[0]
<< " " << this->Interactor->GetEventPosition()[1] << std::endl;
//注册拾取点函数
this->Interactor->GetPicker()->Pick(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1], 0, // always zero.
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
//打印拾取点空间位置
this->Interactor->GetPicker()->GetPickPosition(WorldPointend);
std::cout << "WorldPointend : " << WorldPointend[0] << " " << WorldPointend[1] << " " << WorldPointend[2] << std::endl;
//对拾取点进行标记
sphereSourcend->Update();
mapperend->SetInputConnection(sphereSourcend->GetOutputPort());
actorend->SetMapper(mapperend);
actorend->SetPosition(WorldPointend);
actorend->SetScale(4);
actorend->GetProperty()->SetColor(0.0, 1.0, 1.0);
Point_in_Tube_function(pointsPolydata);
lineSource->SetPoint1(WorldPointbegin);
lineSource->SetPoint2(WorldPointend);//两点确定一条直线
lineSource->Update();
lineMapper->SetInputConnection(lineSource->GetOutputPort());
lineMapper->ScalarVisibilityOff();
lineActor->SetMapper(lineMapper);
lineActor->GetProperty()->SetColor(0, 0, 0);//线的颜色设置
lineActor->GetProperty()->SetOpacity(1);//0是透明
/*
*
*这里可以添加图像与直线的交互过程
*
*/
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actorend);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(lineActor);
i=0;
renderer->GetRenderWindow()->GetInteractor()->Initialize();
renderer->GetRenderWindow()->GetInteractor()->Render();
}
}
{ vtkInteractorStyleTrackballCamera::OnLeftButtonUp();}
};
vtkStandardNewMacro(customMouseInteractorStyle);
更新:这个是鼠标拖动begin 和end 中的任意一点,直线随即更新。可以看到其中有很多代码是重复的,我在实际用的时候重复的做成函数调用,因为放这函数多了显得乱,我就直接贴上来了。如果有问题,可以及时沟通!
其中:point1和point2始终是 begin和end 的鼠标点的二维坐标(后面转化为3维),通过判断point3与她们两个的位置关系,判断当前操作的点。
virtual void OnMiddleButtonDown()
{
click = this->GetInteractor()->GetEventPosition();
point3[0] = click[0];
point3[1] = click[1];
if(abs(point3[0]-point1[0])<50 && abs(point3[1]-point1[1])<50)
beginOrend = 1;
else if (abs(point3[0]-point2[0])<50 && abs(point3[1]-point2[1])<50)
beginOrend = 2;
else
beginOrend = 0;
}
virtual void OnMiddleButtonUp()
{
if(beginOrend == 1){ //操作的是第一个点
clickPosbegin = this->Interactor->GetEventPosition();
point1[0]=clickPosbegin[0];
point1[1]=clickPosbegin[1];
std::cout << "clickPosbegin: " << this->Interactor->GetEventPosition()[0]
<< " " << this->Interactor->GetEventPosition()[1] << std::endl;
//注册拾取点函数
this->Interactor->GetPicker()->Pick(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1], 0, // always zero.
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
//打印拾取点空间位置
this->Interactor->GetPicker()->GetPickPosition(WorldPointbegin);
std::cout << "WorldPointbegin :" << WorldPointbegin[0] << "," << WorldPointbegin[1] << "," << WorldPointbegin[2] << std::endl;
//对拾取点进行标记
sphereSourcebegin->Update();
mapperbegin->SetInputConnection(sphereSourcebegin->GetOutputPort());
actorbegin->SetMapper(mapperbegin);
actorbegin->SetPosition(WorldPointbegin);
actorbegin->SetScale(4);
actorbegin->GetProperty()->SetColor(1.0, 0.0, 1.0);
lineSource->SetPoint1(WorldPointbegin);
lineSource->SetPoint2(WorldPointend);
lineSource->Update();
lineMapper->SetInputConnection(lineSource->GetOutputPort());
lineMapper->ScalarVisibilityOff();
lineActor->SetMapper(lineMapper);
lineActor->GetProperty()->SetColor(0, 0, 0);
lineActor->GetProperty()->SetOpacity(1);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actorbegin);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(lineActor);
renderer->GetRenderWindow()->GetInteractor()->Initialize();
renderer->GetRenderWindow()->GetInteractor()->Render();
}
else if (beginOrend == 2) //操作的是第二个点
{
//打印鼠标左键像素位置
clickPosend = this->Interactor->GetEventPosition();
point2[0]=clickPosend[0];
point2[1]=clickPosend[1];
std::cout << "clickPosend: " << this->Interactor->GetEventPosition()[0]
<< " " << this->Interactor->GetEventPosition()[1] << std::endl;
//注册拾取点函数
this->Interactor->GetPicker()->Pick(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1], 0, // always zero.
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
//打印拾取点空间位置
this->Interactor->GetPicker()->GetPickPosition(WorldPointend);
std::cout << "WorldPointend : " << WorldPointend[0] << " " << WorldPointend[1] << " " << WorldPointend[2] << std::endl;
//对拾取点进行标记
sphereSourcend->Update();
mapperend->SetInputConnection(sphereSourcend->GetOutputPort());
actorend->SetMapper(mapperend);
actorend->SetPosition(WorldPointend);
actorend->SetScale(4);
actorend->GetProperty()->SetColor(0.0, 1.0, 1.0);
Point_in_Tube_function(pointsPolydata);
lineSource->SetPoint1(WorldPointbegin);
lineSource->SetPoint2(WorldPointend);//两点确定一条直线
lineSource->Update();
lineMapper->SetInputConnection(lineSource->GetOutputPort());
lineMapper->ScalarVisibilityOff();
lineActor->SetMapper(lineMapper);
lineActor->GetProperty()->SetColor(0, 0, 0);//线的颜色设置
lineActor->GetProperty()->SetOpacity(1);//0是透明
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actorend);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(lineActor);
renderer->GetRenderWindow()->GetInteractor()->Initialize();
renderer->GetRenderWindow()->GetInteractor()->Render();
}
else {beginOrend = 0;}
}