我们已经描述了一个广泛的可视化技术工具包的设计和实现。在本章中,我们将研究几个案例研究,以展示如何使用这些工具来深入了解重要的应用领域。这些领域包括医学成像、金融可视化、建模、计算流体动力学、有限元分析和算法可视化。对于每一种情况,我们简要描述了问题域,以及我们期望通过可视化获得哪些信息。然后我们设计一种方法来显示结果。很多时候,我们会使用特定于应用程序的工具来扩展可视化工具包的功能。最后,我们给出了一个示例程序并显示了生成的图像。

我们所经历的可视化设计过程在每种情况下都是相似的。首先,我们读取或生成特定于应用程序的数据,并将其转换为Visualization Toolkit中的一种数据表示类型。通常这第一步是最困难的一步,因为我们必须编写自定义的计算机代码,并决定使用哪种形式的可视化数据。在下一步中,我们为应用程序中的相关数据选择可视化。有时这意味着选择或创建与物理结构相对应的模型。例如用于原子的球体、用于模拟物理对象的多边形表面或用于模拟流动边界的计算表面。其他时候,我们生成更抽象的模型,如等值面或字形,对应于重要的应用程序数据。在最后一步中,我们将物理组件与抽象组件结合起来,以创建一个可视化,以帮助用户理解数据。

12.1三维医学成像

放射学是一门处理人体解剖图像的医学学科。这些图像来自各种医学成像设备,包括x射线、x射线计算机断层扫描(CT)、

磁共振成像(MRI)和超声波。每种成像技术,称为一次成像

图12-1人脑CT切片。

情态,有特殊的诊断优势。方式的选择是放射科医生和转诊医生的工作。在大多数情况下,放射科医生处理二维图像,但在某些情况下,三维模型可以帮助放射科医生进行诊断。放射科医生接受过特殊的训练来解释二维图像,并理解这些二维图像中复杂的解剖关系。然而,在与转诊医生和外科医生打交道时,放射科医生有时难以沟通这些关系。毕竟,外科医生在计划和执行手术时是三维的;此外,他们更容易观察和使用三维模型。

本案例研究涉及CT数据。计算机断层扫描测量x射线穿过人体时的衰减。CT图像由灰色级别组成,从黑色(空气)到灰色(软组织),再到白色(骨骼)。图12 - 1为头部CT横切面。这个切片是垂直于脊柱的,大约穿过耳朵的中部。头部周围的灰色边界清楚地显示出耳朵和鼻梁。切片内部的深色区域是鼻道和耳道。亮的部分是骨头。这项研究包含93个这样的切片,间隔1.5 mm。每个切片有2562像素,间隔0.8毫米,12位灰度。

我们面临的挑战是将这些灰色数据(超过12兆字节)转换为有助于外科医生的信息。幸运的是,我们的可视化工具包有合适的技术。我们将使用等轮廓技术来提取皮肤和骨骼表面,并显示正交横截面,以将等值面放在上下文中。根据经验,我们知道密度值500将定义空气/皮肤边界,值1150将定义软组织/骨骼边界。

在VTK术语中,医学成像切片数据是图像数据。回顾第5章,对于图像数据,数据的拓扑和几何结构是隐式已知的,只需要维度、原点和数据间距。

我们在这个案例研究中所遵循的步骤在许多三维医学研究中是常见的。

1. 读取输入。

2. 对于每个感兴趣的解剖特征,创建一个等值面。

3.将模型从病人空间转换到世界空间。

4. 渲染模型。

本案例详细描述了如何使用等轮廓法读取输入数据并提取解剖特征。正交平面将显示使用基于纹理的技术。在此过程中,我们还将向您展示如何呈现数据。最后简要讨论一下医疗数据转换。本节所示示例的完整源代码可从Medical1获得。cxx,医疗2。cxx和Medical3。cxx。

阅读输入

医学图像有多种文件格式。该研究存储为没有头信息的平面文件。每个16位像素以小端字节顺序存储。而且,通常情况下,每个片存储在单独的文件中,文件后缀是表单前缀的片号。1、前缀。2,依此类推。医学成像文件通常在图像数据开始之前有一个一定大小的头文件。头的大小因文件格式的不同而不同。最后,另一个复杂的问题是,有时每个16位像素中的一个或多个比特用于标记体素之间的连通性。重要的是能够在读取时屏蔽掉比特。

VTK提供了几种图像读取器,包括一个可以读取上述类型的原始格式的vtkVolume16Reader。为了读取这些数据,我们实例化类并设置适当的实例变量,如下所示。

FilePrefix和FilePattern实例变量一起工作,生成一系列片中的文件名。fileppattern—默认为%s。%d -通过对FilePrefix执行c语言sprintf()生成要读取的文件名,并将当前文件号写入FilePattern格式说明符。

创建等值面

我们可以从三种等值面可视化技术中选择:体绘制、移动立方体和分割立方体。我们假设希望以尽可能快的速度与数据交互,因此不使用体积渲染。如果我们有可用的多边形渲染硬件,或者如果我们需要靠近或在提取的表面内部移动,我们更喜欢移动立方体。即使使用硬件辅助渲染,我们也可能不得不减少多边形数量以获得合理的渲染速度。划分多维数据集适用于软件渲染。对于这个应用程序,我们将使用移动多维数据集。

对于医疗卷,移动的立方体会生成大量三角形。为了实际起见,我们将使用降低分辨率的数据集进行这个案例研究。我们取原始的2562数据,通过在切片平面上对相邻像素平均两次,将其减少到642片。我们称结果数据集为quarter,因为它的分辨率是原始数据的1/4。我们将分辨率降低的数据集的数据步调调整为每像素3.2 mm。我们的第一个程序将生成皮肤的等值面。

程序中的流程类似于大多数VTK应用程序。

1. 生成一些数据。

2. 用过滤器处理它。

3.创建一个映射器来生成呈现原语。

4. 为所有映射器创建角色。

5. 渲染结果。

我们选择使用的过滤器是vtkMarchingCubes。我们还可以使用vtkContourFilter,因为它将自动创建一个vtkMarchingCubes实例,因为它将委托给特定数据集类型的最快的子类。类vtkPolyDataNormals用于为数据生成漂亮的表面法线。vtkMarchingCubes也可以生成法线,但有时法线直接来自曲面(vtkpolydatanorals)而不是来自数据(vtkMarchingCubes)会获得更好的结果。为了完成这个示例,我们从等值面生成器vtkMarchingCubes获取输出,并通过vtkPolyDataMapper和vtkActor将其连接到映射器和actor。下面是c++代码。

为了提供等值面的上下文,在数据周围创建一个轮廓。初始视图设置在像素大小的窗口中。由于移动相机命令移动到数据,剪辑平面重置,以确保等值面是完全可见的。图12 - 2显示了患者的皮肤图像。

我们可以通过多种方式改进这种可视化。首先,我们可以为皮肤选择更合适的颜色(和其他表面属性)。我们使用vtkProperty方法SetDiffuseColor()将皮肤颜色设置为肉色。我们还在皮肤表面添加了一个镜面组件。接下来,我们可以添加与各种解剖特征相对应的额外等值面。这里我们选择通过添加额外的管道段来提取骨表面。它由筛选器vtkMarchingCubes、vtkPolyDataMapper和vtkActor组成,就像我们对皮肤所做的一样。最后,为了提高系统的渲染性能,我们从输出中创建三角形条

轮廓的过程。这需要添加vtkStripper。图12 - 3显示了生成的图像,下面是该管道的c++代码。

除了等高线外,可视化工具包还提供了用于探索体数据的其他有用技术。医学成像中使用的一种流行技术是通过数据查看正交切片或平面。由于计算机图形硬件支持纹理映射,使用纹理映射的方法在术语或交互性能方面提供了最佳结果。

我们将提取三个正交平面,对应于放射科医生熟悉的轴向、矢状和冠状截面。轴向面垂直于患者颈部,矢状面从左到右,冠状面从前到后。为了便于说明,我们使用不同颜色的查找表来呈现每个平面。对于矢状面,我们使用灰度。冠状面和轴向面分别改变饱和度和色相表。我们将其与皮肤的半透明渲染相结合(我们使用c++语句bone- >VisibilityOff()关闭骨骼)。下面的VTK代码创建了纹理映射过程中使用的三个查找表。

使用筛选器vtkImageMapToColors结合上面创建的查找表将图像数据映射到颜色。切片的实际显示是使用vtkImageActor执行的(有关更多信息,请参阅第74页的“程序集和其他类型的vtkProp”)。这个类方便地将一个四边形、多边形平面与纹理映射结合在一起。vtkImageActor需要unsigned char类型的图像数据,类vtkImageMapToColors方便地提供了这种数据。为了避免复制数据并指定要使用的2D纹理,需要适当地设置每个vtkImageActor的DisplayExtent。c++代码如下:

合成图像如图12 - 4所示。在本例中,名为skin的参与者最后呈现,因为我们使用的是半透明表面。回想一下第213页的“透明度和Alpha值”,我们必须对多边形进行排序,图12-4三个平面和半透明皮肤的合成图像(Medical3。cxx)。12.2从分段的卷数据445中创建模型,组合透明表面以获得正确的结果。我们最后渲染皮肤,将其添加到aRenderer的演员列表中。

关于处理医学影像数据,我们还需要说明最后一点。医学图像可以以各种顺序获得,这些顺序是指连续切片与患者的关系。放射科医生看图像时就好像在看病人的脚一样。这意味着在显示器上,病人的左边显示在右边。CT有两种标准顺序:从上到下或从下到上。在从上到下的采集中,i片比i - 1片离患者脚更远。我们为什么要担心这个订单?在医学应用中,我们必须保持左右关系。忽略片获取顺序可能导致左右翻转。为了纠正这一点,我们需要转换原始数据集或我们已经提取的几何图形。(详见第481页的“练习”。)另外,您可能希望检查类vtkVolume16Reader和vtkVolumeReader (vtkVolume16Reader的超类)的实现。这些类具有处理图像数据转换的特殊方法。

12.2根据分段卷数据创建模型

前面的示例描述了如何从灰度医学成像数据创建模型。与生成其他软组织模型的任务相比,提取骨骼和皮肤模型的技术是简单的。原因是磁共振,在某种程度上,计算机断层扫描,对不同类型的组织产生相似的灰度值。例如,医学计算机断层扫描体积中的肝脏和肾脏通常有重叠的强度。同样,当用磁共振成像观察时,大脑中许多不同的组织都有重叠的强度。为了解决这些问题,研究人员采用了一种被称为分割的方法来识别不同的组织。这些过程在复杂程度上各不相同,从几乎完全自动的方法到人工跟踪图像。分割仍然是一个热门的研究领域。虽然分割过程本身超出了本文的范围,但在这个案例研究中,我们将展示如何处理分割的医疗数据。

出于我们的目的,我们假设有人(或许多研究生)用组织标识符费力地标记了数据卷的每个切片中的每个像素。这个标识符是一个整数,描述每个像素属于哪个组织类。例如,我们可能会得到一系列膝盖的MRI切片,上面有定义半月板、股骨、肌肉等的组织编号。图12 - 5显示了从患者膝盖获得的体积切片的两种表示形式。左边的图像是原始的MRI切片;右边的图像包含了一些重要器官的组织标签。下面的图片是这两张图片的合成。

请注意每种表示所呈现的信息的差异。原始切片显示器官边界逐渐变化,而分割切片显示器官边界突变。在前面的CT实例中,我们处理的图像使用了行进立方体等轮廓算法和强度阈值提取等值面。我们目前的分段研究有整数标签,有一个有点任意的数值。我们在这个例子中的目标是以某种方式获取组织标签并创建灰度切片,我们可以使用之前使用的相同技术进行处理。另一个目标是展示图像处理和可视化如何在应用程序中协同工作。

图12-5磁性

膝盖的共振图像

(左);分段组织

(右);复合(底部)。(数据和分割由布莱根妇女医院提供

手术计划实验室)

为了演示分段数据的处理,我们将使用来自青蛙的数据集。这些数据是在劳伦斯伯克利国家实验室准备的,并在他们的允许下包含在本书附带的CD-ROM上。数据是通过对青蛙进行物理切片并对切片进行拍照来获得的。原始分段数据采用组织掩码的形式,每个组织有一个文件。每个组织有136片,15个不同的组织。每个切片是470乘500像素。(为了适应我们在VTK中拥有的卷阅读器,我们处理了掩码文件,并将它们合并到每个片的一个文件中。)我们用整数1-15来表示这15个组织。图12 - 6显示了原始切片、标记切片和两种表示的组合。

图12-6青蛙摄影切片(左上),分割青蛙(右上),照片和分割的合成(下)。紫色代表胃,黄色代表肾脏

(frogSlice。tcl)。

在我们描述从二进制标记的组织到适合于等值面提取的灰度数据的过程之前,比较图12 - 7所示的两张青蛙大脑图像。左边是用大脑的二进制标记提取的表面。正确的图像是使用我们将在本例中开发的可视化管道创建的。

  • 组合策略

在上一个例子中,我们使用c++创建了一个程序来提取两个表面:一个是皮肤,一个是骨头。所有用于表面提取的参数都在源代码中进行了硬编码。因为我们的青蛙有15种不同的组织;我们寻求对这个问题更普遍的解决办法。我们可能不得不为一些可视化和成像滤波器试验一些不同的参数。我们的目标是开发一个通用的管道,不仅适用于我们的15种组织,还适用于其他医疗数据集。我们将把程序设计成使用一组用户指定的参数来控制管道的元素。一个合理的描述可能是这样的:

SLICE_ORDER hfsi

ROWS 470

COLUMNS 500

STUDY

..间距1.5加上可能更多的参数来控制抽取,平滑,等等。在c++中,我们必须设计文件的格式,并编写代码来解释语句。在这里,我们使用Tcl解释器来简化工作。另一个决定是将建模与渲染分离。我们的脚本将以“批处理”模式生成模型。我们将为每个组织运行一个VTK Tcl脚本。该脚本将创建一个.vtk输出文件,其中包含每个组织的多边形表示。稍后,我们可以使用单独的脚本渲染模型。

管路概述管路设计

如图12 - 8所示。多年来,我们实验室和布里格姆妇女医院手术计划实验室一直在开发这种通用管道。我们发现它能从分段数据集中产生合理的模型。不要被过滤器的数量吓倒(总共12个)。在开发VTK之前,我们用一堆用不同接口编写的程序做了类似的处理。我们使用中间文件将数据从一个过滤器传递到下一个过滤器。在VTK中实现的新管道在时间和计算资源上更加高效。

我们首先开发Tcl脚本来处理卷数据。在这些脚本中,我们使用用户指定的变量用大写字母表示的约定。首先,我们展示了管道的元素,随后展示了样本文件,提取青蛙组织的3D模型。

图12-7青蛙的大脑。左为未平滑提取的模型,右为平滑提取的模型。

读取分段卷数据

我们在这里假设所有要处理的数据都是通过一个恒定的中心地标获得的。在VTK中,数据的原点应用于图像卷的左下角。在这个管道中,我们计算的原点是体积的x,y中心为(0,0)。dataspace描述了每个像素的大小和片之间的距离。DataVOI选择感兴趣的卷(VOI)。VOI可以让我们选择感兴趣的区域,有时可以消除无关的结构,如CT台床。对于青蛙,我们编写了一个小的C程序来读取组织标签文件,并为每个组织找到感兴趣的体积。

SetTransform()方法定义了如何在内存中排列数据。医学图像可以以不同的顺序获得。例如,在CT中,数据可以从上到下(上级到下级)收集,也可以从下到上(下级到上级)收集。此外,MRI数据可以从左到右、从右到左、从前到后(前到后)或从后到前获取。这个过滤器转换三角形顶点,这样得到的模型都将“面向”观看者,视角向上(0,-1,0),向下看正z轴。同时,保持适当的左右对应关系。这意味着病人的左侧将始终留在生成的模型上。查看SliceOrder。TCL来查看每个顺序的排列和旋转。

所有其他参数都是不言自明的,除了最后一个。在这个脚本中,我们知道管道将只执行一次。为了节省内存,我们调用ReleaseDataFlagOn()方法。这允许VTK管道在过滤器处理完数据后释放数据。对于大型医疗数据集,这可能意味着是否能够处理数据集之间的差异。

图12-8分段卷转三角管路在等值面提取(frogSegmentation)之前,体积通过图像管道。tcl)。

删除群岛

一些分割技术,特别是那些自动分割技术,可能会产生错误分类的体素岛。这个过滤器寻找带有ISLAND_REPLACE标签的连接像素,如果连接像素的数量小于ISLAND_AREA,它将它们替换为标签

组织。注意,这个过滤器只在ISLAND_REPLACE为正数时执行。

选择纸巾

管道的其余部分需要灰度数据。为了将现在包含整数组织标签的体积转换为只包含一个组织的灰度体积,我们使用阈值过滤器将所有值tissue(该管道选择的组织)的像素设置为255,所有其他像素设置为0。

选择255有点随意。

重新采样卷

分辨率越低,产生的多边形就越少。在实验中,我们经常用这个滤波器降低数据的分辨率。然而,在这个过程中,细节可能会丢失。平均通过平均相邻像素在重新采样的体积中创建新的像素。如果平均值被关闭,每个SAMPLE_RATE像素将被传递到输出。

平滑体积数据

到目前为止,除非我们重新采样了数据,否则所选组织的体积被标记为255像素,其他地方为0。如果我们不模糊它,这个“二进制”体积就会产生台阶状的表面。在这个过滤器中指定的高斯核完成了我们提取表面所需的平滑。平滑量由12.2从分段卷数据创建模型451 GAUSSIAN_STANDARD_DEVIATION控制,可以为卷数据的每个轴独立指定。我们只在需要平滑时运行这个过滤器,

生成的三角形

现在我们可以用移动的立方体来处理体积,就像我们从扫描仪中获得灰度数据一样。我们在管道中添加了一些附加功能。如果我们关闭梯度和普通计算,过滤器运行得更快。移动立方体通常根据体积数据的梯度计算顶点法线。在我们的管道中,我们已经调制了一个灰度表示,随后将抽取三角形网格并平滑产生的顶点。此处理使通过移动立方体计算的法线失效。

减少三角形的数量

等值面算法生成的三角形通常比我们渲染所需的要多。在这里,我们通过消除位于用户指定距离内的三角形顶点来减少三角形计数,这些三角形顶点是由相邻顶点构成的平面。我们保留三角形的任何边,这些边被认为是“特征”。

平滑三角形顶点

该过滤器使用在第350页的“网格平滑”中描述的拉普拉斯平滑来调整三角形顶点作为相邻顶点的“平均值”。通常,移动将小于一个体素。

452应用程序

当然,我们已经用高斯核平滑了图像数据,所以这一步可能不会有太大的改进;然而,严重抽取的模型有时可以通过额外的多边形平滑来改进。

生成法线

为了在渲染过程中生成平滑的阴影模型,我们需要每个顶点的法线。在抽取中,可以通过设置特征角来保留锐利的边缘。

生成三角形条

三角形条是大量三角形的紧凑表示。这个过滤器在我们将独立三角形写入文件之前处理它们。

将三角形写入文件

最后,管道的最后一个组件将三角形条写入文件。

执行管道

如果您已经读到这里,您就知道可视化工具包使用了需求驱动的管道体系结构,到目前为止我们还没有要求任何东西。我们刚刚为每个管道元素指定了管道拓扑结构和参数。

writer Update

使管道执行。实际上,我们所做的不仅仅是更新管道的最后一个元素。我们显式地更新每个元素,以便对各个步骤计时。脚本frogSegmentation。TCL包含更复杂的方法。

为管道指定参数

以上提到的所有变量都必须为要处理的每个组织定义。这些参数大致分为两类。有些是特定于特定研究的,而有些是特定于每个组织的。对于青蛙,我们收集了档案蛙的特定研究参数。TCL,包含:

每种组织类型都有一个特定的文件。这个特定于组织的文件读取特定于青蛙的参数,设置特定于组织的参数,然后读取管道脚本(我们称之为frogSegmentation)。tcl)。例如,肝脏。tcl包含:

frog中的参数。TCL也可以被覆盖。例如,骷髅。tcl覆盖高斯滤波器的标准偏差。

请注意,这两个示例都指定了感兴趣的量。这通过消除空白空间提高了成像和可视化算法的性能。

另一个脚本,marchingFrog。TCL使用类似的参数,但处理原始的灰度卷,而不是分割的卷。此脚本用于皮肤。TCL提取皮肤。文件前进青蛙。TCL没有移除岛或阈值管道元素,因为数据已经具有灰度信息。

一旦模型按照上述流程生成,就可以使用下面的名为ViewFrog的tcl脚本进行渲染。tcl。首先,我们创建一个Tcl过程来自动从模型文件中创建角色。所有管道元素的命名都与部件的名称后面跟着管道元素的名称一致。这使得用户很容易在更复杂的用户界面中识别每个对象。

在创建所需渲染对象的常规代码之后,为每个部分创建一个可以添加到渲染器的actor:

脚本的其余部分定义了一个标准视图。

图12 - 9显示了用ViewFrog生成的青蛙的四个视图。tcl。这个冗长的示例展示了像VTK这样的综合可视化系统的强大功能。

•我们混合了图像处理和计算机图形算法来处理由外部分割过程创建的数据。

•我们开发了一种通用的方法,允许用户使用熟悉的脚本语言tcl控制管道的元素。

•我们将任务分为“批处理”部分和“交互”部分。

其他青蛙相关信息劳伦斯伯克利国家实验室的人有一个令人印象深刻的网站,介绍了这个例子中使用的青蛙。该网站描述了如何获得青蛙数据,还允许用户创建青蛙的mpeg电影。还有其他可用的数据集。关于“整个青蛙项目”的更多细节可以在http://www-itg.lbl.gov/Frog上找到。还有斯坦福大学

图12-9使用ViewFrog.tcl生成的各种青蛙图像

大学医疗媒体和信息技术(SUMMIT)小组正在使用伯克利蛙进行研究。他们是VTK的早期用户。享受他们的虚拟生物项目:http://summit.stanford.edu/creatures。

12.3财务可视化

三维可视化技术在金融数据中的应用是一个相对较新的领域。历史上,财务数据一直使用二维绘图技术来表示,如直线、散点图、柱状图和饼图。这些技术特别适合于显示股票、债券和共同基金的价格和数量信息。由于近年来信息量的增加,三维技术正变得越来越重要,三维图形和可视化技术正变得交互式。交互率意味着可视化可以应用于数据的日常处理。我们相信,这将有助于对当今复杂的金融数据和其他更及时的决策有更深入的理解。

在这个例子中,我们经历了获取数据的过程,将其转换为我们可以使用的形式,然后使用可视化技术来查看它。一些外部软件工具使用所有青蛙的部分和半透明的皮肤。没有皮肤的完整青蛙。没有皮肤和骨骼。从高处俯瞰。你的生理机能有多好?图12-9使用ViewFrog生成的各种青蛙图像。tcl。12.3财务可视化457在本例中您可能不熟悉。这不应该是一个大问题。我们只是选择了我们所熟悉的工具。在我们使用Awk脚本的地方,您可以选择编写一个小的C程序来完成同样的事情。这个例子的价值在于说明了解决可视化问题的高级过程。

第一步是获取数据。我们从万维网(WWW)上的一个公开网站获得数据,该网站记录了许多公开交易股票的股价和成交量。(本网站自第一版出版以来已关闭。本例的数据可以在CD-ROM上找到。)

一旦我们获得了数据,我们将其转换为可以读入VTK的格式。虽然VTK可以读取各种数据格式,但您的数据通常不是其中一种格式。我们获取的数据文件的存储格式如下:

每一行存储一天交易的数据。第一个数字是日期,存储为年份的最后两位数字,然后是两个数字的月份,最后是月份的日期。接下来的三个值代表当天股票的最高价、最低价和收盘价。下一个值是数千股的交易量。最终的价值是以百万美元为单位的交易量。

我们使用Awk脚本将原始数据格式转换为VTK数据文件。(有关VTK文件格式的资料,请参阅VTK用户指南;或参阅网页http:// www.vtk.org/VTK/pdf/file-formats.pdf。)这种转换可以使用许多其他方法来完成,例如编写C程序或Tcl脚本。

上面的Awk脚本执行转换。它的第一行输出所需的头信息,指示该文件是包含多边形数据的VTK数据文件。它还包括一个注释,表明数据代表股票价值。我们可以选择几种不同的VTK数据格式。由您决定哪种格式最适合您要可视化的数据。我们认为多边形格式(vtkPolyData)最适合这个特定的股票可视化。

Awk脚本的下一行创建了一个名为count的变量,用于跟踪文件中有多少天的信息。这相当于原始数据文件中的行数。

接下来的14行代码将六位数的日期转换为更有用的格式,因为原始格式存在许多问题。如果我们盲目地使用原始格式,以日期为自变量绘制数据,那么我们的图中就会出现很大的缺口。例如,931231是1993年的最后一天,940101是1994年的第一天。从时间上看,这两个日期是连续的,但从数学上看,它们之间有(940101-931231 =)8870个值。一个简单的解决方法是使用行号作为自变量。只要我们知道每个交易日都记录在数据文件中,这就可以工作。它不能正确处理市场开放,但由于某种原因没有记录数据的情况。更好的解决方案是将日期转换为按数字顺序排列的日期。前面的Awk脚本将1993年1月1日设置为第一天,然后从那里开始编号接下来的所有日子。在这14行的末尾,变量d将包含结果值。

Awk脚本中的下一行将转换后的日期、收盘价和美元交易量存储到数组中,数组的索引是存储在变量count中的行号。一旦读取所有行并将其存储到数组中,我们将写出VTK数据文件的其余部分。我们选择日期作为自变量和x坐标。我们将收盘价存储为y坐标,将z坐标设为0。在指示要存储的点的数量和类型之后,Awk脚本循环遍历所有点,并将它们写入VTK数据文件。然后它写出线路连接列表。在这种情况下,我们只是将一个点连接到下一个点,以形成每个股票的折线。最后,我们将体积信息写成与点相关的标量数据。生成的VTK数据文件的部分如下所示。

现在我们已经生成了VTK数据文件,我们可以开始为库存数据创建可视化的过程。为此,我们编写了一个与基于Tcl的VTK可执行文件一起使用的Tcl脚本。

在较高的级别上,脚本读取股票数据,将其通过管道过滤器发送,为其创建一个标签,然后在结果数据集周围创建一个轮廓。理想情况下,我们希望在同一个窗口中显示多个股票。为了便于实现这一点,我们设计了Tcl脚本,使其使用一个过程来对每个库存执行操作。生成的脚本如下所示。

该脚本的第一部分包含渲染器和交互器创建的标准过程,几乎所有的VTK Tcl脚本中都有。下一节将创建围绕所有股票数据绘制轮廓所需的对象。vtkAppendPolyData过滤器用于将所有库存数据附加在一起。然后通过vtkOutlineFilter发送,在数据周围创建一个边界框。创建一个映射器和参与者来显示结果。

在该脚本的下一部分中,我们将定义向该可视化中添加股票数据的过程。这个过程有五个参数:股票的名称,我们想要显示的标签,以及定义标签位置的x, y, z坐标。该过程的第一行表示变量ren1应该对该过程可见。默认情况下,过程只能访问自己的局部变量。接下来,我们使用vtkTextSource、vtkPolyDataMapper和vtkFollower创建标签。这些对象的名称都以变量“$prefix”作为前缀。这样实例名将是唯一的。使用了vtkFollower的一个实例,而不是通常的vtkActor,因为我们总是希望文本朝上并面向摄像机。vtkFollower类提供了此功能。其余的行适当地定位和缩放标签。我们将标签的原点设置为其数据的中心。这确保从动件将围绕其中心点旋转。

下一组行创建所需的对象,以读入数据,通过管过滤器和转换过滤器传递数据,最后显示结果。管道过滤器使用标量数据(本例中的库存体积)来确定管道的半径。绘图器还使用标量数据来确定管的颜色。转换过滤器使用转换对象根据变量zpos的值设置股票的位置。对于每个库存,我们将zpos增加10,有效地将下一个库存从当前库存转移10个单位。这可以防止股票被堆叠在彼此的顶部。我们还使用变换来压缩x轴,以使数据更容易查看。接下来,我们将这个股票作为输入添加到附加过滤器,并将参与者和追随者添加到呈现器。该过程的最后一行将追随者的相机设置为渲染器的活动相机。

回到Tcl脚本的主体,我们用四种不同的股票四次调用AddStock过程。最后,我们添加outline actor并自定义渲染器和相机

图12-10库存可视化脚本的两个视图。顶部显示了收盘价随时间的变化;底部显示了交易量随时间的变化(股票。tcl)。

生成一个漂亮的初始视图。图12 - 10显示两种不同的结果视图。上面的图片显示了我们四支股票的收盘价历史。这些线条的颜色和宽度与当天股票的成交量相对应。从上面的数据来看,下图更清楚地说明了存量的变化。

对于图12 - 10,一个合理的抱怨是,管子宽度的变化使得很难看到价格与时间曲线的真实形状。我们可以通过使用带式过滤器和线性挤压过滤器来解决这个问题,而不是使用管式过滤器。色带过滤器将创建一个色带,其宽度将与数据的标量值成比例变化。然后,我们使用线性挤压过滤器沿y轴挤压这条带,使其具有恒定的厚度。如图12 - 11所示。

图12-11案例分析的另外两个视图。在这里,管式过滤器已被带式过滤器和线性挤压过滤器所取代。

12.4隐式建模

可视化工具包有一些有用的几何建模功能。最强大的功能之一是隐式建模。在本例中,我们将展示如何使用对象的多边形描述,并使用VTK中的隐式建模对象创建对象的“blobby”模型。下面的示例从字母v、t和k的多边形表示中为可视化工具包生成一个徽标。

图12-12 VTK blobby logo可视化流程图

我们创建了三个独立的可视化管道,每个字母一个。可视化流程如图12 - 12所示。正如在VTK应用程序中常见的那样,我们设计了一个管道,并在呈现之前填充实例变量的细节。我们通过vtkTransformPolyDataFilter传递字母,以使它们彼此相对地定位。然后我们使用vtkAppendPolyData过滤器将转换后的字母中的所有多边形组合成一个多边形数据集。vtkimplicitmodeleller创建了一个维度为64 3的卷数据集,其中每个体素包含一个标量值,该标量值是到最近多边形的距离。回想一下第189页的“隐式建模”,隐式建模算法让我们指定每个多边形的影响区域。这里我们使用vtkimplicitmodeler的SetMaximumDistance()方法来指定。通过限制影响区域,可以显著提高隐式建模算法的性能。然后我们使用vtkContourFilter提取一个与每个多边形距离为1.0的等值面。我们创建了两个actor:一个用于斑点标志,另一个用于原始多边形字母。注意,两个参与者共享由vtkAppendPolyData创建的多边形数据。由于VTK可视化管道的性质(请参阅第91页的“隐式执行”),追加的数据将只由管道的第一部分创建一次。最后,我们将多边形logo移动到blobby logo的前面。现在我们将详细介绍这个示例。

首先,我们读取包含logo中每个字母的多边形模型的几何文件。数据是VTK多边形格式,因此我们使用vtkPolyDataReader。

我们希望将每个字母转换为徽标中的适当位置和方向。我们在这里创建了转换过滤器,但是将指定位置和方向推迟到程序的后面部分。

我们使用类vtkAppendPolyData的实例将所有转换后的字母收集到一组多边形中。

由于每个字母的几何图形都没有表面法线,我们将它们添加到这里。我们使用vtkPolyDataNormals。然后我们通过创建映射器和参与者来完成管道的这一部分。

我们用隐式建模器创建斑点状的logo,然后用vtkContourFilter提取logo。管道通过创建映射器和参与者来完成。

为了改善结果可视化的外观,我们定义了两个有机颜色。柔和的颜色在某些电子媒体(如VHS录像带)上表现得更好,也更赏心悦目。

然后将这些颜色分配给适当的参与者。

最后,我们在logo中定位字母,并通过修改actor的位置将多边形logo移到blobby logo的前面。

用本节描述的技术制作的图像如图12 - 13所示。请注意,左边的图像已经使用纹理贴图进行了增强。

12.5计算流体力学

创建一个可以在计算机上求解的大方程组。网格在i-j-k空间中拓扑均匀,但对应的物理坐标不需要均匀分布。这就是我们在VTK中所说的结构化网格数据集。

当我们第一次看到由CFD应用程序呈现的复杂数据时,我们可以使用许多技术。因为我们需要对数据应用几个算法,而且这些算法会有很多参数变化,所以我们建议使用Tcl解释器而不是c++代码。我们将CFD数据可视化的策略包括:

1.显示计算网格。分析人员仔细构造了有限差分网格,以便在流量变量发生快速变化的区域具有更高的密度。我们将在线框中显示网格,以便我们可以看到计算单元格。

2. 在计算网格上显示标量字段。这将使我们了解标量数据在哪里发生了变化。我们将对网格提取的范围进行实验,以专注于感兴趣的区域。

3.探索矢量场播种流线与球形云的点。移动球体通过速度快速变化的区域。

4. 尝试使用计算网格本身作为流线的种子。当然,我们将不得不限制您为此目的使用的网格的范围。使用网格,我们将能够在分析师预期更多行动的地区投放更多种子。

在这个案例研究中,我们使用了来自NASA的一个名为LOx Post的数据集。它模拟液氧在平板上的流动,带有垂直于流动的圆柱柱柱[Rogers86]。该分析模拟了火箭发动机中的气流。柱子促进液氧的混合。

我们从研究数据中的标量和向量场开始。通过计算速度矢量的大小,我们得到了一个标量场。这项研究在柱子周围有一个特别有趣的向量场。我们用多个起始点(使用沿曲线排列的点,称为耙)来播种场,并对流线的参数进行实验。流多边形在这里特别合适,它可以很好地显示帖子下游的流。我们通过移动播种线或在柱子后面来回耙来使流线创建动画。按照我们自己的建议,我们首先显示计算网格。下面的Tcl代码生成了图12 - 14的正确图像。

为了使用颜色映射显示标量字段,我们必须将参与者的表示从线框改为表面,为每个vtkPolyDataMapper打开标量可见性,设置每个映射器的标量范围,并再次呈现,生成如图12 - 14所示的正确图像。

现在,我们使用vtkPointSource来研究向量场。回想一下,这个对象围绕一个球形中心点生成了一个随机的点云。我们将使用这个点云来生成流线。我们把云的中心放在柱子附近,因为这是速度变化最快的地方。在这个探索过程中,出于效率考虑,我们使用流线而不是流管。Tcl代码如下所示。

图12-16使用柱子前面的计算网格创建的Streamtubes作为种子的来源

(液态氧。tcl)。

图12 - 15显示了沿着柱子从四个位置播种的流线。注意当流线的起始位置在柱子前面上下移动时,流的结构是如何开始出现的。如果我们以互动的方式进行,这一点尤其正确;大脑将流线的行为组装成对流场的整体理解。

最后一个例子,我们使用计算网格来播种流线,然后生成流管,如图12 - 16所示。这种方法的一个很好的特点是,我们在分析人员构建更密集网格的区域生成更多流线。我们唯一需要做的改变是用网格几何的一部分替换球体源的耙子。

我们还可以使用许多其他方法来可视化这些数据。像vtkLineWidget这样的3D小部件可以交互式地为流线播种(参见第252页的“3D小部件和用户交互”)。正如我们在312页的“点探测”中看到的,探测数据的数值是一种有价值的技术。特别是,如果探针是一条线,我们可以将它与vtkXYPlotActor结合使用,以绘制数据值沿这条线的变化。另一个有用的可视化方法是识别涡度区域。我们可以将公式9-12与等值线算法(例如,vtkContourFilter)结合使用,以创建大螺旋密度的等值面。

12.6有限元分析

有限元分析是求解偏微分方程的一种广泛应用的数值方法。有限元分析的应用包括线性和非线性结构,热,动力,电磁和流动分析。在这个应用程序中,我们将可视化吹塑过程的结果。

在挤压吹塑工艺中,将材料通过环形模具挤压成空心圆柱体。这个圆柱体叫做圆柱。然后在坯坯上闭合两个模半,同时坯坯充气。一些混合料留在模具内,而另一些则成为废料。这种材料通常是一种加热软化的聚合物塑料,但吹塑已被用于形成金属零件。塑料瓶通常采用吹塑工艺制造。

模具设计是一件不容易的事情。设计不当导致壁厚变化较大。在某些情况下,零件可能在薄壁区域失效。因此,基于有限元技术的分析工具已经开发出来,以协助模具的设计。

其中一个分析结果如图12 - 17所示。聚合物是用等温,非线性弹性,不可压缩(橡胶类)材料成型的。采用三角膜有限元对模型进行建模,采用三角和四边形组合有限元对模具进行建模。假设模具表面是刚性的,并且假设模坯在接触时附着在模具上。因此,坯坯的变薄是由坯坯在膨胀过程中的拉伸和坯坯接触模具的顺序所控制的。

图12 - 17展示了一次分析的10个步骤。坯坯的颜色表明它的厚度。用彩虹刻度法,红色区域最薄,蓝色区域最厚。我们的可视化清楚地显示了我们所使用的分析技术的一个问题。注意,虽然有限元网格的节点(即点)被阻止通过模具,但三角形元素的内部却不是。这是很明显的遮挡模子线框由配对网格。

为了生成这些图像,我们使用了如图12 - 18和图12 - 19所示的Tcl脚本。输入数据为VTK格式,因此使用vtkUnstructuredGridReader作为源对象。网格位移是使用vtkWarpVector实例完成的。在这一点上,管道分裂。我们希望以不同的方式对待模具和混合料(不同的属性,如线框和表面),但模具和混合料的数据是结合在一起的。幸运的是,我们可以使用类vtkConnectivityFilter的两个实例轻松地分离数据。一个过滤器提取焦坯,而另一个提取模具的两个部分。最后,为了在parison上实现平滑的表面外观,我们使用了vtkPolyDataNormals过滤器。为了使用这个过滤器,我们必须将数据类型从vtkUnstructuredGrid (vtkConnectivityFilter的输出)转换为类型vtkPolyData。过滤器vtkGeometryFilter很好地做到了这一点。

12.7算法可视化

可视化可用于显示算法和数据结构。表示这些信息通常需要应用程序程序员进行创造性的工作。例如,罗伯逊等

图12-17吹塑成型十帧有限元分析。模半(显示在线框中)是封闭在一个坯坯周围,因为坯坯是膨胀的。颜色表示厚度-红色区域比蓝色区域薄(吹。tcl)

图12-18使用Tcl脚本生成吹塑图像。显示了网络拓扑结构和脚本的初始部分(两部分中的第一部分)。

[Robertson91]展示了可视化目录结构和在其中导航的3D技术。他们的方法包括构建三维模型(所谓的“圆锥树”)来表示文件、目录以及文件和目录之间的关联。类似的方法可用于可视化堆栈、队列、链表、树和其他数据结构。在这个例子中,我们将可视化递归的Towers of Hanoi谜题的操作。

在这个拼图中有三个钉子(图12 - 20)。在初始位置上有一个或多个不同直径的圆盘(或冰球)。磁盘根据磁盘直径进行排序,最大的磁盘在底部,其次是第二大磁盘,依此类推。这个谜题的目标是

图12-20河内的塔楼。(a)初始配置。(b)中间结构。

(c)最后配置(河内。cxx)。

将磁盘从一个挂钩移动到另一个挂钩,每次移动一个磁盘,不要将较大的磁盘放在较小的磁盘上面。

这个谜题的经典解决方案是基于分治方法[AhoHopUll83]。将n个磁盘从最初的固定桩移动到第二个固定桩的问题可以看作是解决两个大小为n - 1的子问题。首先将n-1个磁盘从最初的钉到第三个钉。然后将第n个磁盘移动到第二个钉子上。最后,将第三个钉子上的n-1个磁盘移回第二个钉子。

这个问题的解决方案可以使用递归优雅地实现。我们已经在图12 - 21和图12 - 22中展示了部分c++代码。在解决方案的第一部分(图12 - 21中没有显示)中,桌面、连接和磁盘是使用两个类vtkPlaneSource和vtkCylinderSource创建的。然后调用函数Hanoi()开始递归。例程MovePuck()负责将磁盘从一个挂钩移动到另一个挂钩。它可以以用户指定的小增量移动磁盘,并在磁盘从一个固定位置移动到下一个固定位置时翻转磁盘。这提供了一个令人愉悦的视觉效果,并为可视化添加了有趣的元素。

由于算法和物理现实之间的明确关系,河内塔谜题相对容易可视化。可视化研究人员面临的一个主要挑战是可视化更抽象的信息,如互联网上的信息,文档的结构,或广告/娱乐在大细分市场中的有效性。这种类型的可视化,被称为信息可视化,很可能在未来成为一个重要的研究挑战。

12.8章节小结

用于介绍内科医生和外科医生。医疗数据集通常是图像数据卷或形成卷的二维图像分层堆栈。医学成像常用的可视化工具包括等值面、切面和体切片上的图像显示。

接下来,我们展示了一个将3D可视化技术应用于金融数据的例子。在这个案例研究中,我们首先展示了如何从外部源导入数据。我们对数据应用了管道过滤器,并改变管道的宽度来显示股票交易量。我们看到了// routineis责任感如何将磁盘从pegnext移动。所产生的运动是小的步骤与额外的磁盘翻转。应用程序可以使用不同的视图来显示不同的信息。在本例中,通过从前面查看可视化,我们看到了常规的价格显示。然后,通过从上面查看可视化图,我们看到了交易量。

在建模案例研究中,我们展示了如何使用多边形模型和VTK中的隐式建模工具来创建一个有风格的徽标。最后的模型通过在用户选择的偏移处提取等值面来创建。

计算流体动力学分析人员经常使用结构化网格数据。我们研究了探索标量场和向量场的一些策略。分析人员创建的计算网格作为分析数据的起点。我们展示了从有限差分网格、标量颜色映射、流线和流管中提取的几何图形来研究数据。

在有限元案例研究中,我们研究了在吹塑过程模拟中使用的非结构化网格。我们使用位移图来显示几何变形,并使用颜色映射来表示材料厚度。我们看到了如何通过生成一系列图像来创建简单的动画。

我们通过可视化的河内塔算法来总结案例研究。在这里,我们展示了如何将c++的过程功能与VTK中的可视化功能结合起来。我们看到可视化通常需要我们的创造性资源来将数据结构和信息转换为可视化形式。

12.9书目注释

本章中介绍的案例研究依赖于有趣的数据来可视化。有时练习可视化最难的部分是找到相关数据。对于这项任务,互联网是一个巨大的资源。Paul Gilster [Gilster94]写了一篇优秀的文章,介绍了许多在互联网上访问信息的工具。

在当地的书店里有很多关于这个主题的书。在库存案例研究中,我们使用了一个名为AWK的编程工具将数据转换为适合VTK的形式。更多关于AWK的信息可以在AWK编程语言[Aho88]中找到。另一种流行的文本处理语言是Perl [Perl95]。

如果你想了解更多关于信息可视化的知识,你可以从这里列出的参考文献开始[Becker95] [Ding90] [Eick93] [Feiner88] [Johnson91] [Robertson91]。这是一个相对较新的领域,但在不久的将来肯定会增长。

12.10参考资料

[Aho88]李国强,李国强。AWK编程语言。AddisonWesley, Reading, MA, 1988。

[刘志强,李志强,李志强,等。数据结构和算法。Addison-Wesley, Reading, MA, 1983。

[刘国强,李国强,李国强,等。“可视化网络数据。”IEEE可视化与图形汇刊。1(1): 16-28, 1995年。12.11练习481

[deLorenzi93] H. G. deLorenzi和C. A. Taylor。吹塑过程中工艺参数的作用及三维有限元分析与实验的相关性高分子材料学报。3(4):365-374,1993。

[Ding90]丁志刚。自动绘制数据结构图的框架IEEE软件工程汇刊。16(5): 543-557, 1990。

[Eick93]李志强。“用层次结构导航大型网络。”在《可视化学报》93年。第204-210页,IEEE计算机协会出版社,加州洛斯阿拉米托斯,1993年10月。

[Feiner88]李志刚。见树见林:超文本结构的分层显示在办公信息系统会议上。帕洛阿尔托,加州,1988年。

[刘文杰,李文杰,李文杰,等。在互联网上找到它:Archie, Veronica, Gopher, WAIS, WWW(包括马赛克)和其他搜索和浏览工具的基本指南。约翰·威利父子公司,1994年。

[Johnson91]李国强。树图:层次信息结构可视化的空间填充方法>,发表于《可视化学报》91年。第284-291页,IEEE计算机协会出版社,Los Alamitos, CA, 1991年10月。

[Perl95] D.直到。21天自学Perl。山姆出版社,印第安纳州印第安纳波利斯,1995年。

[杨晓明,李志刚,李志刚,等。圆锥树:分层信息的动画3D可视化。ACM CHI ' 91计算系统中的人为因素会议论文集。第189-194页,1991。[j]李志强,李志强,李志强,“三维不可压流场的数值模拟研究。美国航空航天科学会议论文集。卷。AIAA论文86-0353。1986年,内华达州里诺。

12.11运动

12.1医学示例没有将原始数据转换为标准坐标系。许多医疗系统使用RAS坐标。R代表右/左,A代表前/后,S代表上/下。这是病人坐标系。讨论并比较以下将卷数据转换为RAS坐标的替代方案。

a) vtkActor转换方法。

b) vtkTransformFilter。

c)读卡器转换。

12.2修改医疗应用(Medical3. properties)中最后一个示例。cxx)使用vtkImageDataGeometryFilter代替vtkImageActor。比较使用几何和使用纹理的性能。性能如何随着体积数据分辨率的变化而变化?482应用

12.3修改最后一个医疗实例(Medical3. properties)。cxx)使用v tkTexture和vtkPlaneSource代替vtkImageActor。

12.4将医学案例研究改为使用皮肤表面的分割立方体。

12.5结合两个脚本frogSegmentation。tcl和marchingFrog。TCL转换为一个脚本,该脚本将处理分段文件或灰度文件。对于这个应用程序,还有哪些参数和管道组件可能有用?

12.6创建你的首字母的多边形/线条描边模型,并建立自己的标志。尝试不同的转换。

12.7增强河内塔的可视化外观。

a)纹理映射磁盘、基面和挂钩。

b)创建有中心孔的磁盘。

12.8以吹塑为例作为以下内容的起点。

a)创建一个吹塑序列的动画。有可能在时间步长之间进行插值吗?你会怎么做呢?

b)使用对称创建parison的后半部分。你需要用什么变换矩阵?

12.9从本章给出的股票可视化示例开始。

a)修改示例代码,使用文本中描述的带状滤波器和线性挤压滤波器。注意生成的缎带的宽度。

b)你能想出一种方法来表示每天的高/低交易价值吗?

vtk教程第十二章 应用相关推荐

  1. 谭浩强c语言不讲位运算呢,谭浩强C语言教程第十二章-位运算.doc

    谭浩强C语言教程第十二章-位运算 12位运算1 12.1位运算符C语言提供了六种位运算符:1 12.1.1按位与运算1 12.1.2按位或运算2 12.1.3按位异或运算2 12.1.4求反运算3 1 ...

  2. C#图解教程 第十二章 数组

    数组 数组 定义 重要细节 数组的类型 数组是对象 一维数组和矩形数组 实例化一维数组或矩形数组 访问数组元素 初始化数组 显式初始化一维数组 显式初始化矩形数组 快捷语法 隐式类型数组 综合内容 交 ...

  3. 单片机c语言置位程序流程图,单片机c语言教程第十二章--C51开关分支语句

    学习了条件语句,用多个条件语句能实现多方向条件分支,但是能发现使用过多的 条件语句实现多方向分支会使条件语句嵌套过多,程序冗长,这样读起来也很不好读.这个时候 使用开关语句同样能达到处理多分支选择的目 ...

  4. [AJava]FusionCharts Free中文开发指南[使用文档教程]第十二章--FCF中的特殊字符

    在FCF里,如果要在图形里用到一些特殊的字符,你就要对它进行编码,否则就无法显示. 欧元符号在FCF里显示"€",你需要用"%80"来替换它.如下: <g ...

  5. 《Dreamweaver CS6 完全自学教程》笔记 第十二章:框架的应用

    文章目录 第十二章:框架的应用 12.1 创建框架或框架集 12.1.1 创建自定义框架 12.1.2 创建预定义框架 技术专题:框架的拆分与合并 12.1.3 创建嵌套框架 12.2 框架和框架集的 ...

  6. iPhone开发基础教程笔记(十二)--第十二章 使用Quartz和OpenGL绘图

    第十二章 使用Quartz和OpenGL绘图 有时应用程序需要能够自定义绘图.一个库是Quartz 2D,她是Core Graphics框架的一部分:另一个库是OpenGL ES,她是跨平台的图形库. ...

  7. 小菜鸡的html初步教程(第十二章 初步构建响应式网站)

    小菜鸡的第三篇博客  今天是3/19,天气不错,跑到自习室来更新博客. 本系列文章仅仅是对基础的HTML5以及CSS进行讲解,更加详细的内容均会附上链接,以便查阅和版权保护.  昨晚我思考了下,决定对 ...

  8. 第十二章_网络搭建及训练

    文章目录 第十二章 网络搭建及训练 CNN训练注意事项 第十二章 TensorFlow.pytorch和caffe介绍 12.1 TensorFlow 12.1.1 TensorFlow是什么? 12 ...

  9. python从入门到实践十二章

    python编程从入门到实践12章 今天看了星球里面一位学长的经历,感到很受鼓舞,他参加工作三年了,三月份到四月份自学完了三本书,感到和学长差距很大,我要努力去弥补! 决定首先开始三本书,廖雪峰的py ...

最新文章

  1. 每天学习java一小时_java再学感受 - 编程一小时的个人空间 - OSCHINA - 中文开源技术交流社区...
  2. java策略模式 if else_Java如何利用策略模式替代if/else语句
  3. 【翻译】How-To: Using the N* Stack, part 3
  4. Spring Data Solr教程:将自定义方法添加到单个存储库
  5. (转) Android平台上关于IM的实践总结
  6. 数据结构之插入排序:直接插入排序
  7. day5 字典 dict
  8. 智课雅思词汇---十九、前缀se是什么意思
  9. DOS入门教程。DOS的特点,DOS命令格式
  10. 家用电冰箱3C认证检测标准
  11. 怎么修改思迅软件的服务器地址,思迅的服务器地址如何更改
  12. kaptcha 验证码
  13. html5期末大作业课程设计仿苹果官网(源码+报告)
  14. 木兰词·拟古决绝词柬友
  15. 德国汉诺威地面材料展览会搭建就找上海宽创国际
  16. android app 头像上传原理
  17. 邮件服务器有故障 英文,ClamAV 故障
  18. Jenny DAO 运营月报|2021 年 12 月
  19. 个人博客(一)之表结构设计
  20. 适合上班族做的5个副业推荐?适合下班后做的副业推荐

热门文章

  1. AutoML全面解析@Qing
  2. jquery中的for循环与each循环
  3. C#网络编程服务器端程序实现源码浅析
  4. 天翼云十年一诺,以普惠算力拥抱万里山河
  5. 实训班学员求职与唐骏事件引发的思考
  6. 第一个Python小程序(Hello World!)
  7. 海洋工程水动力学整理
  8. 深度学习评价指标系列——CDF累积分布函数(分布函数)
  9. python配置多数据源
  10. (转)关于字符编码的八个点