static Double3 projection(Double3 p, Double3 center, Double3 direction)
{
Double3 projection;
Double3 vectorPl;
vtkMath::Subtract(p.data(), center.data(), vectorPl.data());
double t = vtkMath::Dot(vectorPl.data(), direction.data()) / vtkMath::Dot(direction.data(), direction.data());
for(int i=0; i<3; i++){
projection[i] = center[i] + t*direction[i];
}
return projection;
}
void NoteViewerDistanceItem::computePosition()
{
Double3 direction;
vtkMath::Subtract(m_point2.data(), m_point1.data(), direction.data());
vtkMath::Normalize(direction.data());
p4 = projection(m_point1, m_position, direction);
p5 = projection(m_point2, m_position, direction);
}
void NoteViewerDistanceItem::sigMouseMoved(Double3 pos, int specialKey)
{
Q_UNUSED(pos)
Q_UNUSED(specialKey)
//在按住的过程中重绘制
if(!catchActor)
return;
m_position = pos;
computePosition();
{
auto points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(m_point1[0], m_point1[1], 0.);
points->InsertNextPoint(m_point2[0], m_point2[1], 0.);
m_polyData = nullptr;
m_polyData = vtkSmartPointer<vtkPolyData>::New();
m_polyData->SetPoints(points);
auto filter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
filter->SetInputData(m_polyData);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(filter->GetOutputPort());
m_viewer->getRenderer()->RemoveActor(m_pointsActor);
m_pointsActor = vtkSmartPointer<vtkActor>::New();
m_pointsActor->SetMapper(mapper);
m_pointsActor->GetProperty()->SetPointSize(10);
m_viewer->getRenderer()->AddActor(m_pointsActor);
}
{
auto lineSource = vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(p4[0], p4[1], 0.001);
lineSource->SetPoint2(p5[0], p5[1], 0.001);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
m_viewer->getRenderer()->RemoveActor(m_lineActor);
m_lineActor = vtkSmartPointer<vtkActor>::New();
m_lineActor->SetMapper(mapper);
m_viewer->getRenderer()->AddActor(m_lineActor);
}
{
auto lineSource = vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(m_point1[0], m_point1[1], 0.001);
lineSource->SetPoint2(p4[0], p4[1], 0.001);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
m_viewer->getRenderer()->RemoveActor(m_lineActor1);
m_lineActor1 = vtkSmartPointer<vtkActor>::New();
m_lineActor1->SetMapper(mapper);
m_lineActor1->GetProperty()->SetLineWidth(0.5);
m_lineActor1->GetProperty()->SetLineStipplePattern(0xFF00);
m_lineActor1->GetProperty()->SetLineStippleRepeatFactor(1);
m_viewer->getRenderer()->AddActor(m_lineActor1);
}
{
auto lineSource = vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(m_point2[0], m_point2[1], 0.001);
lineSource->SetPoint2(p5[0], p5[1], 0.001);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
m_viewer->getRenderer()->RemoveActor(m_lineActor2);
m_lineActor2 = vtkSmartPointer<vtkActor>::New();
m_lineActor2->SetMapper(mapper);
m_lineActor2->GetProperty()->SetLineWidth(0.5);
m_lineActor2->GetProperty()->SetLineStipplePattern(0xFF00);
m_lineActor2->GetProperty()->SetLineStippleRepeatFactor(1);
m_viewer->getRenderer()->AddActor(m_lineActor2);
}
{
auto lineSource = vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(m_point1[0], m_point1[1], 0.001);
lineSource->SetPoint2(m_point2[0], m_point2[1], 0.001);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
m_viewer->getRenderer()->RemoveActor(m_lineActorBase);
m_lineActorBase = vtkSmartPointer<vtkActor>::New();
m_lineActorBase->SetMapper(mapper);
m_lineActorBase->GetProperty()->SetLineWidth(0.5);
m_lineActorBase->GetProperty()->SetLineStipplePattern(0xFF00);
m_lineActorBase->GetProperty()->SetLineStippleRepeatFactor(1);
//m_lineActorBase->GetProperty()->SetColor(1, 0, 0);
m_viewer->getRenderer()->AddActor(m_lineActorBase);
}
Double3 direction;
vtkMath::Subtract(m_point2.data(), m_point1.data(), direction.data());
vtkMath::Normalize(direction.data());
double angle = vtkMath::DegreesFromRadians(std::atan2(direction[1], direction[0]));
{
m_arrow1 = vtkSmartPointer<vtkGlyphSource2D>::New();
m_arrow1->SetGlyphTypeToArrow();
m_arrow1->SetFilled(false);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(m_arrow1->GetOutputPort());
m_viewer->getRenderer()->RemoveActor(m_arrowActor1);
m_arrowActor1 = vtkSmartPointer<vtkActor>::New();
m_arrowActor1->SetMapper(mapper);
m_arrowActor1->SetPosition(-0.5, 0, 0);
auto transform = vtkSmartPointer<vtkTransform>::New();
transform->Translate(p4[0], p4[1], 0.001);
transform->RotateZ(angle + 180);
transform->Scale(0.5,0.5,1.0);
m_arrowActor1->SetUserTransform(transform);
m_viewer->getRenderer()->AddActor(m_arrowActor1);
}
{
m_arrow2 = nullptr;
m_arrow2 = vtkSmartPointer<vtkGlyphSource2D>::New();
m_arrow2->SetGlyphTypeToArrow();
m_arrow2->SetFilled(false);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(m_arrow2->GetOutputPort());
m_viewer->getRenderer()->RemoveActor(m_arrowActor2);
m_arrowActor2 = vtkSmartPointer<vtkActor>::New();
m_arrowActor2->SetMapper(mapper);
m_arrowActor2->SetPosition(-0.5, 0, 0);
auto transform = vtkSmartPointer<vtkTransform>::New();
transform->Translate(p5[0], p5[1], 0.001);
transform->RotateZ(angle);
transform->Scale(0.5,0.5,1.0);
m_arrowActor2->SetUserTransform(transform);
m_viewer->getRenderer()->AddActor(m_arrowActor2);
}
{
auto length = std::sqrt(vtkMath::Distance2BetweenPoints(p4.data(), p5.data()));
Double3 pos = {
(p4[0] + p5[0]) / 2.0,
(p4[1] + p5[1]) / 2.0,
(p4[2] + p5[2]) / 2.0,
};
m_viewer->getRenderer()->RemoveActor(m_lengthText);
m_lengthText = createTextActor(QString::number(length, 'f', 2), pos);
m_viewer->getRenderer()->AddActor(m_lengthText);
}
m_lineActor->GetProperty()->SetColor(1, 0, 0);
m_lengthText->GetTextProperty()->SetColor(1, 0, 0);
m_arrow2->SetColor(1, 0, 0);
m_arrow1->SetColor(1, 0, 0);
m_viewer->updateRender();
}