两点间测距

一种绘制双端箭头和一条线的方法

    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);    //p4、p5是箭头两端的点

        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 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);
    }

一种测量两点之间距离,并绘制矩形的方法

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();
}
Table of Contents