学习VTK的目的和方法

news2024/11/20 12:28:27

1 VTK(Visualization Toolkit)是一个开源的跨平台软件系统,用于三维计算机图形学、图像处理和可视化。学习VTK的主要目的有:

  • 3D可视化: VTK提供了丰富的工具和算法,可以用来可视化各种科学数据,包括医学图像、有限元分析结果、流体模拟数据等。
  • 图像处理: VTK支持多种图像处理操作,如滤波、分割、配准等,可以对医学图像进行预处理和分析。
  • 科学计算可视化: VTK可以与其他科学计算软件(如MATLAB、Python)结合,实现科学计算结果的可视化。
  • 自定义可视化: VTK提供了灵活的接口,可以自定义各种可视化组件和交互方式,满足个性化的需求。

对于有科研需求的小伙伴,可以利用VTK将你的数据和实验结果进行可视化,对数据有一个感官的理解。比如下面的图像就是一个细胞分裂增殖的模拟图像,使用VTK对数据进行了可视化。

                                                          3图1 细胞克隆增殖的模拟

VTK就是一个工具,不用刻意的去学习它。假如你不做数据的显示,也不需要做3D模型的渲染,你就不用去学习它,因为学习任何事物都是需要学习成本的。

2 学习方法

学习VTK的方法有很多种,以下是一些建议:

  • 官方文档: VTK官方文档是学习VTK最权威的资料,提供了详细的类、函数和示例。
  • 教程和书籍: 网上有很多关于VTK的教程和书籍,可以帮助你快速入门。
  • 示例代码: VTK提供了大量的示例代码,可以帮助你理解各种概念和用法。
  • 社区: VTK有一个活跃的社区,你可以通过论坛、邮件列表等方式向其他用户提问和交流。
  • 实践: 最好的学习方式是实践。通过编写自己的代码,尝试实现各种功能,可以加深对VTK的理解。

3 一个比较有意思的例子

我们模拟一下太阳光线照射到地球上,然后有反射的情况,其实就是一个光线追踪算法。

                                                        图2 射线追踪算法

先看代码:

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkOBBTree.h>
#include <vtkMath.h>
#include <vtkTransform.h>
#include <vtkTransformFilter.h>
#include <vtkMatrix4x4.h>
#include <vtkPolyDataNormals.h>
#include <vtkPlaneSource.h>
#include <vtkPoints.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCamera.h>
#include <vtkLight.h>
#include <vtkJPEGReader.h>
#include <vtkTexture.h>
#include <vtkTextureMapToSphere.h>
#include <vtkCellCenters.h>
#include <vtkPolyDataNormals.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkGlyph3D.h>
#include <vtkArrowSource.h>
#include <vtkCellData.h>
#include <vtkPointData.h>
#include <vtkIdList.h>
#include <vtkDoubleArray.h>
#include <vtkLineSource.h>

using namespace std;
vtkSmartPointer<vtkActor> point2Actor(vtkSmartPointer<vtkPoints> points){
    vtkNew<vtkPolyData> polyData;
    polyData->SetPoints(points);
    vtkNew<vtkVertexGlyphFilter> filter;
    filter->SetInputData(polyData);
    filter->Update();
    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputConnection(filter->GetOutputPort());
    vtkSmartPointer<vtkActor> actor=vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
    return actor;
}



int main()
{

    // Sun Options
    // Radius of the sun half-sphere
    double RadiusSun=10.0;
    // Distance of the sun's center from (0,0,0)
    double DistanceSun=50.0;
    // Phi & Theta Resolution of sun
    int ResolutionSun=10;

    // Earth Options
    // Radius of the earth sphere
    double RadiusEarth=150.0;
    // Phi & Theta Resolution of earth
    int ResolutionEarth=120;

    // Ray Options
    double RayCastLength=500.0;

    // Color Options
    double ColorSun[3]={1.0,1.0,0.0};
    double ColorSunEdge[3]={0.0,0.0,0.0};
    double ColorEarthEdge[3]={1.0,1.0,1.0};
    double ColorBackground[]={0.0,0.0,0.0};
    double ColorLight[]={1.0,1.0,0.0};
    double ColorSunPoints[]={1.0,1.0,0.0};
    double ColorSunGlyphs[]={1.0,1.0,0.0};
    double ColorRayHit[]={1.0,1.0,0.0};
    double ColorRayMiss[]={1.0,1.0,1.0};
    double OpacityRayMiss=0.5;
    double ColorEarthGlyphs[]={0.0,0.0,1.0};
    double ColorRayReflected[]={1.0,1.0,0.0};

    // Load a JPEG file with an 'earth' texture
    vtkNew<vtkJPEGReader> reader;
    reader->SetFileName("../data/R-C.jpeg");
    reader->Update();

    vtkNew<vtkSphereSource> sun;
    sun->SetCenter(0.0,DistanceSun,0.0);
    sun->SetRadius(RadiusSun);
    sun->SetThetaResolution(ResolutionSun);
    sun->SetPhiResolution(ResolutionSun);
    sun->SetStartTheta(180);  // create a half-sphere
    // Create mapper
    vtkNew<vtkPolyDataMapper> sunMapper;
    sunMapper->SetInputConnection(sun->GetOutputPort());
    // Create actor
    vtkNew<vtkActor> sunActor;
    sunActor->SetMapper(sunMapper);
    sunActor->GetProperty()->SetColor(ColorSun);
    sunActor->GetProperty()->EdgeVisibilityOn();  // show edges/wireframe
    sunActor->GetProperty()->SetEdgeColor(ColorSunEdge);

    // Create and configure the earth spere
    vtkNew<vtkSphereSource> earth;
    earth->SetCenter(0.0,-RadiusEarth,0.0);
    earth->SetThetaResolution(ResolutionEarth);
    earth->SetPhiResolution(ResolutionEarth);
    earth->SetRadius(RadiusEarth);

    // texture to earth
    vtkNew<vtkTexture> texture;
    texture->SetInputConnection(reader->GetOutputPort());
    texture->Update();

    vtkNew<vtkTextureMapToSphere> map_to_sphere;
    map_to_sphere->SetInputConnection(earth->GetOutputPort());
    map_to_sphere->PreventSeamOn();
    map_to_sphere->Update();


    vtkNew<vtkPolyDataMapper> earthMapper;
    earthMapper->SetInputConnection(map_to_sphere->GetOutputPort());
    vtkNew<vtkActor> earthActor;
    earthActor->SetMapper(earthMapper);
    earthActor->SetTexture(texture);
    earthActor->GetProperty()->EdgeVisibilityOn();
    earthActor->GetProperty()->SetEdgeColor(ColorEarthEdge);

    // Renderer to display
    vtkNew<vtkRenderer> ren;
    ren->AddActor(sunActor);
    ren->AddActor(earthActor);
    ren->SetBackground(ColorBackground);


    vtkNew<vtkCellCenters> cellCenterCalcSun;
    cellCenterCalcSun->SetInputConnection(sun->GetOutputPort());
    cellCenterCalcSun->Update();

    //cellCenterCalcSun->Print(cout);
    //cout<<cellCenterCalcSun->GetOutput()->GetNumberOfPoints()<<endl;
    vtkPoints* pointsInCellCenterCalcSun=cellCenterCalcSun->GetOutput()->GetPoints();
    /*
    for(vtkIdType i=0;i<pointsInCellCenterCalcSun->GetNumberOfPoints();++i){
        double point[3];
        pointsInCellCenterCalcSun->GetPoint(i,point);
        cout<<point[0]<<","<<point[1]<<","<<point[2]<<endl;
    }
    */
    for(vtkIdType i=0;i<cellCenterCalcSun->GetOutput()->GetNumberOfPoints();++i){
        /*
        cout<<cellCenterCalcSun->GetOutput()->GetPoint(i)[0]<<","
            <<cellCenterCalcSun->GetOutput()->GetPoint(i)[1]<<","
            <<cellCenterCalcSun->GetOutput()->GetPoint(i)[2]<<endl;
        */
        vtkNew<vtkPoints> points;
        points->InsertNextPoint(cellCenterCalcSun->GetOutput()->GetPoint(i)[0],
                                cellCenterCalcSun->GetOutput()->GetPoint(i)[1],
                                cellCenterCalcSun->GetOutput()->GetPoint(i)[2]);
        vtkSmartPointer<vtkActor> actor=point2Actor(points);
        actor->GetProperty()->SetColor(ColorSunPoints);
        actor->GetProperty()->SetPointSize(5);
        ren->AddActor(actor);
    }


    vtkNew<vtkPolyDataNormals> normalsCalcSun;
    normalsCalcSun->SetInputConnection(sun->GetOutputPort());
    // Disable normal calculation at cell vertices
    normalsCalcSun->ComputePointNormalsOff();
    // Enable normal calculation at cell centers
    normalsCalcSun->ComputeCellNormalsOn();
    // Disable splitting of sharp edges
    normalsCalcSun->SplittingOff();
    // Disable global flipping of normal orientation
    normalsCalcSun->FlipNormalsOff();
    // Enable automatic determination of correct normal orientation
    normalsCalcSun->AutoOrientNormalsOn();
    normalsCalcSun->Update();
    // Create a 'dummy' vtkCellCenters to force the glyphs to the cell-centers
    vtkNew<vtkCellCenters> dummy_cellCenterCalcSun;
    dummy_cellCenterCalcSun->VertexCellsOn();
    dummy_cellCenterCalcSun->SetInputConnection(normalsCalcSun->GetOutputPort());

    // Create a new 'default' arrow to use as a glyph
    vtkNew<vtkArrowSource> arrow;
    vtkNew<vtkGlyph3D> glyphSun;
    glyphSun->SetInputConnection(dummy_cellCenterCalcSun->GetOutputPort());
    glyphSun->SetSourceConnection(arrow->GetOutputPort());
    glyphSun->SetVectorModeToUseNormal();
    glyphSun->SetScaleFactor(5);
    vtkNew<vtkPolyDataMapper> glyphMapperSun;
    glyphMapperSun->SetInputConnection(glyphSun->GetOutputPort());
    vtkNew<vtkActor> glyphActorSun;
    glyphActorSun->SetMapper(glyphMapperSun);
    glyphActorSun->GetProperty()->SetColor(ColorSunGlyphs);
    ren->AddActor(glyphActorSun);

    // Prepare for ray-tracing
    vtkNew<vtkOBBTree> obbEarth;
    obbEarth->SetDataSet(earth->GetOutput());
    obbEarth->BuildLocator();
    double tol=1.e-8;
    obbEarth->SetTolerance(tol);

    vtkNew<vtkPolyDataNormals> normalsCalcEarth;
    normalsCalcEarth->SetInputConnection(earth->GetOutputPort());
    normalsCalcEarth->ComputePointNormalsOff();
    normalsCalcEarth->ComputeCellNormalsOn();
    normalsCalcEarth->SplittingOff();
    normalsCalcEarth->FlipNormalsOff();
    normalsCalcEarth->AutoOrientNormalsOn();
    normalsCalcEarth->Update();


    //cout<<"Prepare the ray using point and normal"<<endl;
    // Extract the normal-vector data at the sun's cells
    vtkDataArray* normalsSun=normalsCalcSun->GetOutput()->GetCellData()->GetNormals();
    // Extract the normal-vector data at the earth's cells
    vtkDataArray* normalsEarth=normalsCalcEarth->GetOutput()->GetCellData()->GetNormals();

    // Create a dummy 'vtkPoints' to act as a container for the point coordinates where intersections are found
    vtkNew<vtkPoints> intersectPoints;
    vtkNew<vtkIdList> intersectCells;
    // Create a dummy 'vtkList' to act as a container for the normal vectors where intersections are found.
    vtkNew<vtkDoubleArray> normalsVector;
    normalsVector->SetNumberOfComponents(3);
    // Create a dummy 'vtkPolyData' to store points and normals
    vtkNew<vtkPoints> dummy_points;
    vtkNew<vtkPolyData> dummy_polydata;
    for(vtkIdType i=0;i<pointsInCellCenterCalcSun->GetNumberOfPoints();++i){
        // Get the coordinates of sun's cell center
        double pointSun[3];
        cellCenterCalcSun->GetOutput()->GetPoint(i,pointSun);
        // Get normal vector at that cell
        double* normals=normalsSun->GetTuple(i);
        //cout<<normals[0]<<","<<normals[1]<<","<<normals[2]<<endl;
        // Calculate the 'target' of the ray based on 'RayCastLength'
        double pointEarth[3];
        pointEarth[0]=pointSun[0]+normals[0]*RayCastLength;
        pointEarth[1]=pointSun[1]+normals[1]*RayCastLength;
        pointEarth[2]=pointSun[2]+normals[2]*RayCastLength;

        int code=obbEarth->IntersectWithLine(pointSun,pointEarth,intersectPoints,intersectCells);
        if(code<0){
            continue;
        }
        double intersection[3];
        vtkIdType cellId;
        double normalIntersect[3];
        vtkNew<vtkLineSource> line;
        vtkNew<vtkLineSource> lineRay;
        for(int i=0;i<intersectPoints->GetNumberOfPoints();++i){
            if(i==1)
                continue;
            intersectPoints->GetPoint(i,intersection);
            //cout<<"Intersection "<<i<<" : "<<intersection[0]<<","<<intersection[1]<<","<<intersection[2]<<endl;
            //
            cellId=intersectCells->GetId(i);
            //cout<<"\tCellId "<<i<<" : "<<cellId<<endl;
            normalIntersect[0]=normalsEarth->GetTuple(cellId)[0];
            normalIntersect[1]=normalsEarth->GetTuple(cellId)[1];
            normalIntersect[2]=normalsEarth->GetTuple(cellId)[2];
            normalsVector->InsertNextTuple3(normalIntersect[0],normalIntersect[1],normalIntersect[2]);
            dummy_points->InsertNextPoint(intersection[0],intersection[1],intersection[2]);
            // line
            line->SetPoint1(pointSun);
            line->SetPoint2(intersection);

            // Calculate the incident ray vector
            double vecInc[3];
            vecInc[0]=intersection[0]-pointSun[0];
            vecInc[1]=intersection[1]-pointSun[1];
            vecInc[2]=intersection[2]-pointSun[2];
            // Calculate reflected ray vector
            double vecRef[3];
            double dot=vecInc[0]*normalIntersect[0]+vecInc[1]*normalIntersect[1]+vecInc[2]*normalIntersect[2];
            vecRef[0]=vecInc[0]-2.0*dot*normalIntersect[0];
            vecRef[1]=vecInc[1]-2.0*dot*normalIntersect[1];
            vecRef[2]=vecInc[2]-2.0*dot*normalIntersect[2];

            // Calculate the target of reflected ray
            double pointRayReflectedTarget[3];

            pointRayReflectedTarget[0]=intersection[0]+vecRef[0]*RayCastLength;
            pointRayReflectedTarget[1]=intersection[1]+vecRef[1]*RayCastLength;
            pointRayReflectedTarget[2]=intersection[2]+vecRef[2]*RayCastLength;
            lineRay->SetPoint1(intersection);
            lineRay->SetPoint2(pointRayReflectedTarget);
        }
        vtkNew<vtkPolyDataMapper> lineMapper;
        vtkNew<vtkPolyDataMapper> lineRayMapper;
        lineMapper->SetInputConnection(line->GetOutputPort());
        lineRayMapper->SetInputConnection(lineRay->GetOutputPort());
        vtkNew<vtkActor> lineActor;
        vtkNew<vtkActor> lineRayActor;
        lineActor->SetMapper(lineMapper);
        lineActor->GetProperty()->SetColor(ColorRayHit);
        lineRayActor->SetMapper(lineRayMapper);
        lineRayActor->GetProperty()->SetColor(ColorRayReflected);
        ren->AddActor(lineActor);
        ren->AddActor(lineRayActor);
    }
    dummy_polydata->SetPoints(dummy_points);
    dummy_polydata->GetPointData()->SetNormals(normalsVector);
    vtkNew<vtkGlyph3D> glyphEarth;
    glyphEarth->SetInputData(dummy_polydata);
    glyphEarth->SetSourceConnection(arrow->GetOutputPort());
    glyphEarth->SetVectorModeToUseNormal();
    glyphEarth->SetScaleFactor(5);

    vtkNew<vtkPolyDataMapper> glyphMapperEarth;
    glyphMapperEarth->SetInputConnection(glyphEarth->GetOutputPort());

    vtkNew<vtkActor> glyphActorEarth;
    glyphActorEarth->SetMapper(glyphMapperEarth);
    glyphActorEarth->GetProperty()->SetColor(ColorEarthGlyphs);
    ren->AddActor(glyphActorEarth);


    vtkNew<vtkCamera> camera;
    camera->SetPosition(RadiusEarth,DistanceSun,RadiusEarth);
    camera->SetFocalPoint(0.0,0.0,0.0);
    camera->SetViewAngle(30.0);
    ren->SetActiveCamera(camera);



    //
    vtkNew<vtkRenderWindow> renWin;
    renWin->SetSize(1024,1024);
    renWin->AddRenderer(ren);
    vtkNew<vtkRenderWindowInteractor> iren;
    iren->SetRenderWindow(renWin);
    vtkNew<vtkInteractorStyleTrackballCamera> style;
    iren->SetInteractorStyle(style);
    iren->Initialize();
    iren->Start();


    return 0;
}

在代码中有详细的说明,等有空我会讲解一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2182924.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VBA数据库解决方案第十五讲:Recordset集合中单个数据的精确处理

《VBA数据库解决方案》教程&#xff08;版权10090845&#xff09;是我推出的第二套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;是学完字典后的另一个专题讲解。数据库是数据处理的利器&#xff0c;教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法…

windows下安装nginx和基本配置

1. 下载 Nginx 从 Nginx 官方网站下载 Windows 版本的 Nginx。访问 Nginx 官网 并选择适合 Windows 的版本。通常应选择稳定版&#xff08;Stable version&#xff09; 2. 安装 Nginx 安装 Nginx 实际上是解压下载的文件。可以选择一个适合的位置来存放 Nginx 的文件夹 例如…

【数据结构初阶】排序算法(下)冒泡排序与归并排序

文章目录 4. 交换排序4. 1 冒泡排序 5. 归并排序6. 非比较排序6. 1 计数排序 5. 排序性能分析6. 排序算法复杂度及稳定度分析 4. 交换排序 交换排序基本思想: 所谓交换**&#xff0c;就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置**。 交换排序的特点是…

下一代性能怪兽RTX 5090最新规格更新与Blackwell架构解析

据悉&#xff0c;目前各家AIC厂商已经陆续收到NVIDIA的相关资料&#xff0c;RTX 5090、RTX 5080已经正式进入开案阶段&#xff0c;也就是厂商们开始设计各自的产品方案了。不出意外&#xff0c;年初的CES 2025上会看到RTX 5090/5080的发布。 作为NVIDIA的新一代GPU&#xff0c…

2024年健康经济与大数据研讨会(HEBD 2024)2024 Seminar on Health Economics and Big Data

在线投稿&#xff1a;学术会议-学术交流征稿-学术会议在线-艾思科蓝 2024年经济决策与人工智能国际学术会议 &#xff08;EDAI 2024&#xff09;将在2024年11月08-10日在广东省广州市隆重举行。大会邀请来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者、工程师…

理解互联网链路:从本地ISP到Tier 1 ISP运营商

1. 互联网服务提供商&#xff08;ISP&#xff09; 互联网服务提供商&#xff08;ISP&#xff09;是指提供互联网接入服务的公司或组织。它们负责将用户连接到互联网&#xff0c;并提供相关的服务&#xff0c;如电子邮件、网站托管和其他在线服务。ISP可以分为不同的层级&#…

告别转换顾虑,来试试这四款pdf转换器~

各位小伙伴们&#xff0c;大家好&#xff01;今天我来给大家分享几款超级好用的PDF转换工具&#xff0c;无论是工作还是学习&#xff0c;相信这些工具都会给你带来极大的便利&#xff1b;别看PDF文件看似难搞&#xff0c;其实有了这些神器&#xff0c;一切都变得轻松又愉快&…

在线css像素Px到百分比(%)换算器

具体请前往&#xff1a;在线Px转百分比(%)工具--将绝对像素(px)长度单位转换为相对父级元素内尺寸的相对长度单位百分比(%)

PCL GridMinimum获取栅格最低点

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 GridMinimum 栅格最低点提取 2.1.2 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长…

新农人的求索:既要种菜,也要种钱

澎湃新闻记者 何惠子 灯下立着一个玻璃瓶&#xff0c;内里空无一物&#xff0c;清晰透亮。 一只手握住瓶身。“就像这个瓶子。前途一片光明&#xff0c;但其实都在瓶子里。” 解晓巍说的是音乐——他曾梦想以此维生。事实上&#xff0c;这也适合描述农业。 在没有任何收入的202…

计算机网络:计算机网络概述 —— 初识计算机网络

文章目录 计算机网络组成部分网络架构协议与标准网络设备网络类型作用实际应用案例 计算机网络 计算机网络是指将多台计算机通过通信设备和通信链路连接起来&#xff0c;以实现数据和信息的交换和共享的技术和系统。它是现代信息社会的基础设施之一&#xff0c;也是互联网的基…

工业现场干扰问题及处理方法

目前&#xff0c;各种干扰在各类工业现场中均存在&#xff0c;所以仪表及控制系统的可靠性直接影响到现代化工业生产装置安全、稳定运行&#xff0c;系统的抗干扰能力是关系到整个系统可靠运行的关键。随着DCS、现场总线技术的应用&#xff0c;被控对象和被测信号往往分布在各个…

Ubuntu启动后第一次需要很久才能启动GTK应用问题

Ubuntu启动后第一次需要很久才能启动GTK应用问题 自从升级了 Ubuntu 之后&#xff0c;设备重启&#xff0c;发现打开 Terminal 、Nautilus 以及其他的GTK 应用都很慢&#xff0c;需要至少一分钟的时间启动。 刚开始也是拿着 journalctl 的异常日志去寻找答案&#xff0c;但是没…

cheese安卓版纯本地离线文字识别插件

目的 cheese自动化平台是一款可以模拟鼠标和键盘操作的自动化工具。它可以帮助用户自动完成一些重复的、繁琐的任务&#xff0c;节省大量人工操作的时间。可以采用Vscode、IDEA编写&#xff0c;支持Java、Python、nodejs、GO、Rust、Lua。cheese也包含图色功能&#xff0c;识别…

山东大学操作系统学习笔记:第3.1讲程序的结构-简单的程序

第3.1讲&#xff1a;程序的结构-简单的程序 可执行文件 & 程序的装入 .rwdata(读写数据段): 存放程序中的含初值常量。这些常量在程序运行可以修改。 零初始化数据段&#xff08;.zidata/.bss - Block Started by Symbol&#xff09;&#xff1a;存放程序中的不含初值&am…

《自控原理》最小相位系统

在复平面右半平面既没有零点&#xff0c;也没有极点的系统&#xff0c;称为最小相位系统&#xff0c;其余均为非最小相位系统。 从知乎看了一篇答案&#xff1a; https://www.zhihu.com/question/24163919 证明过程大概率比较难&#xff0c;我翻了两本自控的教材&#xff0c;…

【中间件】fastDFS的相关知识

一、分布式文件系统 1.1 传统的文件系统 我们在Linux中学习的文件系统就是传统的文件系统&#xff1a; 传统的文件系统格式&#xff1a; ntfs/fat32/ext3/ext4 可以被挂载和卸载&#xff0c;就是一般一个盘可以分成多个盘&#xff0c;每一盘都可以挂载到不同的目录路径中。…

实时语音交互,打造更加智能便捷的应用

随着人工智能和自然语言处理技术的进步&#xff0c;用户对智能化和便捷化应用的需求不断增加。语音交互技术以其直观的语音指令&#xff0c;革新了传统的手动输入方式&#xff0c;简化了用户操作&#xff0c;让应用变得更加易用和高效。 通过语音交互&#xff0c;用户可以在不…

考研笔记之操作系统(三)- 存储管理

操作系统&#xff08;三&#xff09;- 存储管理 1. 内存的基础知识1.1 存储单元与内存地址1.2 按字节编址和按字编址1.3 指令1.4 物理地址和逻辑地址1.5 从写程序到程序运行1.6 链接1.6.1 静态链接1.6.2 装入时动态链接1.6.3 运行时动态链接 1.7 装入1.7.1 概念1.7.2 绝对装入1…

算法-汉诺塔问题(Hanoi tower)

介绍 汉诺塔是源于印度的一个古老传说的小游戏&#xff0c;简单来说就是有三根柱子&#xff0c;开始的时候&#xff0c;第一根柱子上圆盘由大到小&#xff0c;自下往上排列。这个小游戏要实现的目的呢&#xff0c;就是要把第一根柱子上的圆盘移到第三根的柱子上去&#xff1b;…