当前位置: 首页 > news >正文

小型网站设计及建设论文文献/个人自己免费建网站

小型网站设计及建设论文文献,个人自己免费建网站,重庆人才网,分类网站营销伴随资源 目录 一、说明二、 PyQt4三、PyOpenGL四、OpenGL 管线五、Python集成开发环境5.1 Emacs配置5.2 pycharm环境 六、你好,OpenGL!七、QGL控件八、平截头体.svg九、定义几何9.1 立即模式与保留模式9.2 使用 VBO 定义 Cube 十、渲染立方体十一、渲…

伴随资源

目录

  • 一、说明
  • 二、 PyQt4
  • 三、PyOpenGL
  • 四、OpenGL 管线
  • 五、Python集成开发环境
    • 5.1 Emacs配置
    • 5.2 pycharm环境
  • 六、你好,OpenGL!
  • 七、QGL控件
  • 八、平截头体.svg
  • 九、定义几何
    • 9.1 立即模式与保留模式
    • 9.2 使用 VBO 定义 Cube
  • 十、渲染立方体
  • 十一、渲染循环
  • 十二、添加旋转滑块

一、说明

在本教程中,我们将编写一个小型 Python 脚本,该脚本在 GUI 中呈现一个立方体,并使用滑块来控制其旋转。这将基于其他教程,即本教程,但会更详细地解释该过程和一般 OpenGL 概念。您可以在此处下载完整的脚本。

二、 PyQt4

有许多不同的框架用于在 python 中创建 GUI - 内置选项是TkInter,它提供了跨平台Tk GUI 工具包的包装器,该工具包具有简单的学习曲线并且适用于小型应用程序,但是流行的现代跨平台-平台解决方案是Qt。

Qt 的 python 端口称为 PyQt,有两个最新版本 - PyQt4 和 PyQt5 - 可以安装在 python 2 或 3 中。由于已经存在许多使用 PyQt4 的教程,而且核心库似乎很多版本之间相同,我们将使用 PyQt4。

这个包可以安装在linux上

apt-get install python-qt4
如果您使用的是 Windows,则与许多其他 python 包一样,您可以使用从Unofficial Windows Binaries for Python Extension Packages pagepip install下载的 python 轮来安装 PyQt4 。如果您更喜欢从源代码构建,请参阅本指南。

三、PyOpenGL

还有许多不同的库可用于在 python 中创建 3D 图形,但最常见的跨平台解决方案是 OpenGL - 特别是使用PyOpenGL包装器。您应该能够pip install pyopengl在 Linux 上轻松安装它,或者再次使用此处pip install下载的轮子进行安装。在 Ubuntu 16.04 上,我发现我必须使用而不是 ‘’‘pip’‘’

apt-get install python-qt4-gl
PyQt 在其QtOpenGL模块中使用与 PyOpenGL 相同的系统安装,以提供特殊的 OpenGL QWidget,从而可以轻松进行交互。下面详细介绍这一点。

四、OpenGL 管线

请注意,我们将在此处使用的 OpenGL 功能主要是固定功能管道的一部分,实际上在 OpenGL 3.0 之后已弃用,转而使用可编程(基于着色器)管道,该管道利用现代 GPU 并行性来高效渲染。不幸的是,网络上的大多数教程都使用已弃用的管道,而且它也恰好是我使用旧模拟器所习惯的管道。稍后我可能会尝试将所有内容切换到所谓的现代 OpenGL,但现在这里有一篇很好的读物,它用简单的术语解释了这些差异。

五、Python集成开发环境

在我们深入研究使用 Qt + OpenGL 创建简单应用程序的示例之前,您可能想知道使用哪些工具在 Python 中进行开发。有很多、很多、很多文章专门讨论这一点,其细节比我所能提供的要详细得多,但我想说的是,通过一些工作,好的 ol’ Emacs 可以变成一个很棒的轻量级 IDE(因为所有涉及 Emacs 的东西都需要),好处是,如果您已经使用 Emacs 处理其他事情,它可以很好地集成到您的工作流程中。下面我将详细介绍我的 Emacs 设置。

如果您要从 Matlab 过渡到 Python 并寻找类似的工具,Spyder是一个不错的选择,并且与一些 Python 发行版中的其他工具配合使用。在使用 JetBrains 的 CLion 进行 C/C++ 开发后,我很想尝试PyCharm,我听说过它很棒(不过,除非您是学生,否则它不是免费的)。

5.1 Emacs配置

Emacs 生态系统中有很多用于 Python 开发的优秀软件包,但我最近对​​Elpy很感兴趣;您可以在这里了解更多信息。要让 Elpy 使用 python3 而不是 python2,请查看此线程以获取说明。

Elpy 内置了一些很棒的功能,例如自动完成,但您可能希望使用其他一些软件包来扩展它。要查看当前集成的内容,请打开 Emacs 并运行M-x elpy-config,这将为您提供一个小界面来检查已安装的内容。如果您想进一步进行设置,您可以按照这个很棒的指南来启用 Flyspell 以获得更好的语法检查等。

非常重要的是,Elpy 使用Flake8进行语法检查,并且可以配置为编辑文件~/.flake8(可能尚不存在,如果不存在则创建它)。例如,Flake8 突出显示了许多令人烦恼的小语法错误,因此您可以添加到此配置文件中:

[flake8]
max-line-length = 99
max-doc-length = 79
ignore = E2,E302,E41,E303

我们还将行长度设置为 99,文档字符串长度设置为 79,正如python.org 所建议的那样,尽管标准 python 库使用更严格的长度。

最后,作为旁注,如果您的 Emacs 设置中的任何内容要求您在“临时”缓冲区中计算 lisp 表达式,请不要惊慌 - 请查看此页面以获取有关如何执行此操作的帮助。可以在 Emacs 中CTRL-X LEFTARROW从主缓冲区轻松访问“临时”缓冲区。

5.2 pycharm环境

如果您在windows下采用pycharm开发环境,一切变得异常简单,无需什么特殊配置,只要安装好QT、OpenGL就一切就绪。

六、你好,OpenGL!

现在我们已经接触了 IDE 的设置和选择,让我们开始导入必要的模块并了解它们各自提供的内容。

from PyQt4 import QtCore      # core Qt functionality
from PyQt4 import QtGui       # extends QtCore with GUI functionality
from PyQt4 import QtOpenGL    # provides QGLWidget, a special OpenGL QWidgetimport OpenGL.GL as gl        # python wrapping of OpenGL
from OpenGL import GLU        # OpenGL Utility Library, extends OpenGL functionalityimport sys                    # we'll need this later to run our Qt application

无需将其转变为 Qt 教程的介绍(因为我们现在确实想专注于 OpenGL 集成),任何应用程序的主窗口都是由派生自QtGui.QMainWindow.让我们创建主窗口类,然后给它一个名称并在初始化程序中调整它的大小:

class MainWindow(QtGui.QMainWindow):def __init__(self):QtGui.QMainWindow.__init__(self)    # call the init for the parent classself.resize(300, 300)self.setWindowTitle('Hello OpenGL App')if __name__ == '__main__':app = QtGui.QApplication(sys.argv)win = MainWindow()win.show()sys.exit(app.exec_())

如果您运行到目前为止的所有内容,则应该打开一个指定大小、名称为“Hello OpenGL App”的 Qt 窗口并且可以退出。多么激动人心!但是我们如何使用 OpenGL 在该窗口中渲染某些内容呢?这就是QGLWidget进来的地方。

QGL控件
定义几何
立即模式与保留模式
使用 VBO 定义 Cube
渲染立方体
渲染循环
添加旋转滑块
设置

七、QGL控件

QGLWidget是一个 Qt 小部件,旨在使用 OpenGL 轻松渲染图形。我们通过子类化 QGLWidget 并实现三个提供的虚拟函数来实现这一点,这些函数在必要时由 Qt 自动调用:

initializeGL:在调用调整大小或绘制之前调用一次以设置 OpenGL 渲染上下文
resizeGL:在创建窗口以及调整窗口大小以设置 OpenGL 视口和投影时调用一次
paintGL:在更新小部件以渲染场景时调用
让我们继承 QGLWidget 并开始填充这些函数。

class GLWidget(QtOpenGL.QGLWidget):def __init__(self, parent=None):self.parent = parentQtOpenGL.QGLWidget.__init__(self, parent)

在派生类的初始化程序中,我们调用父GLWidget类的初始化程序。

def initializeGL(self):self.qglClearColor(QtGui.QColor(0, 0, 255))    # initialize the screen to bluegl.glEnable(gl.GL_DEPTH_TEST)                  # enable depth testing

在初始化函数中启用深度测试,使 OpenGL 自动确保“片段”根据其在深度缓冲区中的值正确渲染。

def resizeGL(self, width, height):gl.glViewport(0, 0, width, height)gl.glMatrixMode(gl.GL_PROJECTION)gl.glLoadIdentity()aspect = width / float(height)GLU.gluPerspective(45.0, aspect, 1.0, 100.0)gl.glMatrixMode(gl.GL_MODELVIEW)

该resizeGL函数有更多的设置发生。首先,glViewport(x,y,width,height)指定窗口的哪一部分用于绘图,通常设置为使用窗口的完整宽度和高度(传递给resizeGL)。

接下来,glMatrixMode(mode)将活动矩阵堆栈设置为投影堆栈,其中包含用于定义查看体积的投影变换。为了定义这个变换,我们首先使用 加载单位矩阵到投影堆栈glLoadIdentity(),然后使用 定义视锥体gluPerspective(field_of_view, aspect_ratio, z_near, z_far):
在这里插入图片描述

八、平截头体.svg

透视投影创建的观察体积称为截锥体,如上所示;垂直视场 (FOV) 直接在第一个参数中指定,而水平视场则根据垂直视场和纵横比定义,近端和远端剪裁平面也是输入。

有一个更通用的函数glFrustum可用于创建离轴透视投影(实际上,在幕后gluPerspective调用)。我们也可以使用正交投影来glFrustrum定义观看体积。glOrtho这会创建一个矩形棱柱的观看体积,并且不切实际地导致位于不同深度(z 值)的相同高度的对象被绘制为相同的尺寸。我们将在这里坚持使用透视投影。
在这里插入图片描述

正交.svg

最后,我们将矩阵模式设置回GL_MODELVIEW用于所有后续相机和模型转换的矩阵模式。一般来说,我们不应该使用GL_PROJECTIONexcept 来定义观看量。

def paintGL(self):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)# Add rendering code here!

最后GLWidget要实现的虚拟函数是paintGL,我们将在其中进行所有渲染。目前,我们所做的只是使用glClear(bitmask)掩码的按位或来进行一些预渲染内务处理,告诉 OpenGL 要清除哪些缓冲区。我们清除颜色和深度缓冲区,以便每次都从干净的状态开始渲染步骤。

让我们GLWidget通过创建一个对象并将其设置为我们的中心小部件来使用我们新完成的类,MainWindow如下所示。

class MainWindow(QtGui.QMainWindow):def __init__(self):QtGui.QMainWindow.__init__(self)    # call the init for the parent classself.resize(300, 300)self.setWindowTitle('Hello OpenGL App')glWidget = GLWidget(self)self.setCentralWidget(glWidget)

所有QMainWindow对象都必须有一个中央小部件,其他小部件可以停靠在该中央小部件上。运行我们到目前为止编写的所有内容,您应该看到一个空白的蓝色窗口,而不是一个空白的黑色窗口,因为我们使用 OpenGL 在initializeGL.
在这里插入图片描述

hello_opengl_blue.svg

万岁!现在我们已经完成了GLWidget设置,让我们做一些更有趣的事情。

九、定义几何

9.1 立即模式与保留模式

就渲染简单几何体而言,有两种模式。立即模式包括将绘图命令夹在glBegin和glEnd命令之间,导致性能较差,因为 GPU 必须等待glEnd然后立即渲染。保留模式是现代方法;几何体不是在每个周期立即调用渲染,而是使用所谓的顶点缓冲区对象 (VBO)定义,这些对象被发送到并存储在 GPU 上进行渲染。除非需要更新VBO,否则后续渲染不需要CPU和GPU之间的通信,因为VBO数据存储在图形硬件上。

9.2 使用 VBO 定义 Cube

首先,我们将导入 python OpenGL 包提供的 VBO 类以及numpy通用数组:

from OpenGL.arrays import vbo
import numpy as np

现在我们准备定义我们正在绘制的立方体的几何形状。让我们向我们的GLWidget类添加一个新函数initGeometry,我们将在该类中定义立方体。

def initGeometry(self):self.cubeVtxArray = np.array([[0.0, 0.0, 0.0],[1.0, 0.0, 0.0],[1.0, 1.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0],[1.0, 0.0, 1.0],[1.0, 1.0, 1.0],[0.0, 1.0, 1.0]])self.vertVBO = vbo.VBO(np.reshape(self.cubeVtxArray,(1, -1)).astype(np.float32))self.vertVBO.bind()

首先,将以原点为中心的立方体顶点位置定义为 2D numpy 数组。然后,创建顶点位置 VBO vertVBO,注意将numpy 数组重塑为 1D 并将数组元素转换为,np.float32因为 OpenGL 需要浮点数(不是双精度数,这是 python 的默认值)。最后,绑定VBO以供GPU使用。

self.cubeClrArray = np.array([[0.0, 0.0, 0.0],[1.0, 0.0, 0.0],[1.0, 1.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0],[1.0, 0.0, 1.0],[1.0, 1.0, 1.0],[0.0, 1.0, 1.0 ]])
self.colorVBO = vbo.VBO(np.reshape(self.cubeClrArray,(1, -1)).astype(np.float32))
self.colorVBO.bind()

我们创建第二个 VBO 来存储每个顶点的颜色,该颜色被任意设置为与顶点位置相同。 OpenGL 将使用这些顶点颜色为立方体面着色,并具有良好的渐变效果。请注意,我们实际上并不需要一个全新的 VBO 来处理颜色;而是需要一个新的 VBO。相反,我们可以通过在渲染时交错行并指定步长(连续顶点或颜色数据值之间的字节数)来将顶点位置和颜色数据存储在同一个 VBO 中。

self.cubeIdxArray = np.array([0, 1, 2, 3,3, 2, 6, 7,1, 0, 4, 5,2, 1, 5, 6,0, 3, 7, 4,7, 6, 5, 4 ])

最后,我们指定组成一维数组中六个立方体面中每一个的顶点。所有这些几何设置都应该在 中调用initializeGL,我们将其修改为

def initializeGL(self):self.qglClearColor(QtGui.QColor(0, 0, 255))    # initialize the screen to bluegl.glEnable(gl.GL_DEPTH_TEST)                  # enable depth testingself.initGeometry()

十、渲染立方体

要渲染立方体,我们需要向paintGL函数添加代码。将其更新为以下内容:

def paintGL(self):gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)gl.glPushMatrix()    # push the current matrix to the current stackgl.glTranslate(0.0, 0.0, -50.0)    # third, translate cube to specified depthgl.glScale(20.0, 20.0, 20.0)       # second, scale cubegl.glTranslate(-0.5, -0.5, -0.5)   # first, translate cube center to origingl.glEnableClientState(gl.GL_VERTEX_ARRAY)gl.glEnableClientState(gl.GL_COLOR_ARRAY)gl.glVertexPointer(3, gl.GL_FLOAT, 0, self.vertVBO)gl.glColorPointer(3, gl.GL_FLOAT, 0, self.colorVBO)gl.glDrawElements(gl.GL_QUADS, len(self.cubeIdxArray), 			gl.GL_UNSIGNED_INT, self.cubeIdxArray)gl.glDisableClientState(gl.GL_VERTEX_ARRAY)gl.glDisableClientState(gl.GL_COLOR_ARRAY)gl.glPopMatrix()    # restore the previous modelview matrix

让我们逐步看一下新的调用:

gl.glPushMatrix()    # push the current matrix to the current stackgl.glTranslate(0.0, 0.0, -50.0)    # third, translate cube to specified depth
gl.glScale(20.0, 20.0, 20.0)       # second, scale cube
gl.glTranslate(-0.5, -0.5, -0.5)   # first, translate cube center to origin

首先,我们用来glPushMatrix()复制当前的变换矩阵(因为我们没有做任何其他事情,所以它是恒等式)并将其推送到当前的矩阵堆栈(回想一下,这是在GL_MODELVIEW我们设置场景投影之后设置的)。然后,我们应用一系列变换,以相反的顺序构建它们 - 因此我们将立方体中心平移到原点(这在缩放或旋转之前是必要的),然后缩放立方体,然后将其平移到较大的深度,以便我们实际上可以看到它。

但是等等……立方体在哪里渲染?好吧,我们实际上还没有渲染任何东西 - 我们只是设置将应用于立方体的转换,它是通过以下方式渲染的:

gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
gl.glEnableClientState(gl.GL_COLOR_ARRAY)gl.glVertexPointer(3, gl.GL_FLOAT, 0, self.vertVBO)
gl.glColorPointer(3, gl.GL_FLOAT, 0, self.colorVBO)gl.glDrawElements(gl.GL_QUADS,len(self.cubeIdxArray),gl.GL_UNSIGNED_INT,self.cubeIdxArray)gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
gl.glDisableClientState(gl.GL_COLOR_ARRAY)gl.glPopMatrix()    # restore the previous modelview matrix

为了渲染立方体,我们首先启用顶点和颜色数组,然后将指针设置为我们之前创建的顶点位置和颜色数组glVertexPointer(size, type, stride, pointer),glColorPointer(size, type, stride, pointer)以便 GPU 可以访问数据。

然后,我们调用使用 中指定的面索引glDrawElements(mode, count, type, indices)来渲染立方体面。或者,我们可以直接在顶点 VBO 中定义面并使用,但这需要将重复的顶点发送到 GPU。在这种情况下,使用索引列表会更有效。GL_QUADScubeIdxArrayglDrawArraysglDrawElements

最后,我们禁用启用的客户端状态(为了安全起见),然后从模型视图堆栈中弹出当前矩阵,将堆栈顶部重置为恒等变换。

十一、渲染循环

把它们放在一起会产生……什么也没有!我们已经准备好所有代码,但paintGL从未实际调用过。由我们决定渲染的时间/频率;最简单的方法是设置一个计时器作为updateGL回调(paintGL自动调用),以便定期进行渲染。更新MainWindow类如下:

class MainWindow(QtGui.QMainWindow):def __init__(self):QtGui.QMainWindow.__init__(self)self.resize(300, 300)self.setWindowTitle('Hello OpenGL App')glWidget = GLWidget(self)self.setCentralWidget(glWidget)timer = QtCore.QTimer(self)timer.setInterval(20)   # period, in millisecondstimer.timeout.connect(glWidget.updateGL)timer.start()

我们创建了一个QTimer对象,并将其设置为每 20 毫秒 (50 Hz) 发出一个信号,并将该信号连接到派生基类提供的槽(函数)。当我们开始添加滑块和其他 GUI 元素时,我们将更多地利用 Qt 的信号和插槽。updateGLGLWidget

十二、添加旋转滑块

在这里插入图片描述
hello_opengl_cube.svg

现在我们的应用程序中渲染了一个立方体!让我们添加一个滑块来更改其方向,以便我们实际上可以看到它是三维的。这涉及到修改 MainWindow类,我们在其中设置 GUI 结构。请注意,创建更复杂的 GUI 可能需要 QtCreator(用于 C++ 应用程序)等设计工具,但对于简单的 GUI,我们可以手动添加元素。

class MainWindow(QtGui.QMainWindow):

def __init__(self):QtGui.QMainWindow.__init__(self)    # call the init for the parent classself.resize(300, 300)self.setWindowTitle('Hello OpenGL App')self.glWidget = GLWidget(self)
self.initGUI()timer = QtCore.QTimer(self)timer.setInterval(20)   # period, in millisecondstimer.timeout.connect(self.glWidget.updateGL)timer.start()def initGUI(self):central_widget = QtGui.QWidget()gui_layout = QtGui.QVBoxLayout()central_widget.setLayout(gui_layout)self.setCentralWidget(central_widget)gui_layout.addWidget(self.glWidget)sliderX = QtGui.QSlider(QtCore.Qt.Horizontal)sliderX.valueChanged.connect(lambda val: self.glWidget.setRotX(val))sliderY = QtGui.QSlider(QtCore.Qt.Horizontal)sliderY.valueChanged.connect(lambda val: self.glWidget.setRotY(val))sliderZ = QtGui.QSlider(QtCore.Qt.Horizontal)sliderZ.valueChanged.connect(lambda val: self.glWidget.setRotZ(val))gui_layout.addWidget(sliderX)gui_layout.addWidget(sliderY)gui_layout.addWidget(sliderZ)

我们添加了一个新initGUI函数,该函数被调用来代替原始调用以设置glWidget为应用程序的中央小部件。该函数封装了所有GUI布局设置;让我们一步一步地看一下。

def initGUI(self):central_widget = QtGui.QWidget()gui_layout = QtGui.QVBoxLayout()central_widget.setLayout(gui_layout)self.setCentralWidget(central_widget)

我们可以通过以下方式构建 Qt GUI:首先定义一个新的中央小部件,为该小部件创建一个布局,该布局定义添加到其中的小部件将如何组织(垂直堆叠,因为我们使用QVBoxLayout),然后设置中央小部件的布局。最后,我们将新的小部件设置为该类的中心小部件MainWindow。

    gui_layout.addWidget(self.glWidget)sliderX = QtGui.QSlider(QtCore.Qt.Horizontal)sliderX.valueChanged.connect(lambda val: self.glWidget.setRotX(val))sliderY = QtGui.QSlider(QtCore.Qt.Horizontal)sliderY.valueChanged.connect(lambda val: self.glWidget.setRotY(val))sliderZ = QtGui.QSlider(QtCore.Qt.Horizontal)sliderZ.valueChanged.connect(lambda val: self.glWidget.setRotZ(val))gui_layout.addWidget(sliderX)gui_layout.addWidget(sliderY)gui_layout.addWidget(sliderZ)

接下来,我们将小部件添加到中央小部件的布局中,从glWidget顶部开始,然后QSlider在其下面添加三个小部件。我们将valueChanged每个滑块的信号连接到相应的槽函数,该函数捕获滑块值val并设置立方体绕轴的旋转。

我们将旋转角度作为glWidget属性添加到initializeGL函数中:

def initializeGL(self):self.qglClearColor(QtGui.QColor(0, 0, 255))    # initialize the screen to bluegl.glEnable(gl.GL_DEPTH_TEST)                  # enable depth testingself.initGeometry()self.rotX = 0.0self.rotY = 0.0self.rotZ = 0.0

使用上述设置器从滑块更新

def setRotX(self, val):self.rotX = valdef setRotY(self, val):self.rotY = valdef setRotZ(self, val):self.rotZ = val

然后更新paintGL渲染代码以使用这些角度来执行立方体围绕局部轴的连续旋转(我们将在以后的文章中详细介绍旋转,但格式是轴角度):

    gl.glTranslate(0.0, 0.0, -50.0)    # third, translate cube to specified depthgl.glScale(20.0, 20.0, 20.0)       # second, scale cubegl.glRotate(self.rotX, 1.0, 0.0, 0.0)gl.glRotate(self.rotY, 0.0, 1.0, 0.0)gl.glRotate(self.rotZ, 0.0, 0.0, 1.0)gl.glTranslate(-0.5, -0.5, -0.5)   # first, translate cube center to origin

结果是相同的渲染立方体,但其下方有三个滑块,允许我们旋转它。您应该看到一些与下面的立方体几乎但不完全不同的东西。

在这里插入图片描述

立方体.gif

想知道为什么我的立方体看起来这么糟糕?我使用这个漂亮的工具将屏幕直接录制为 GIF,而 GIF 格式的调色板极其有限(8 位,即 256 种颜色),这在尝试显示具有一堆颜色渐变的立方体时非常明显。我保证你的会看起来更好!
在这里插入图片描述

hello_opengl_cube_rotated.svg

您可以在此处下载完整的脚本。

相关文章:

【OpenGL】使用 python + Qt + OpenGL 的现代渲染

伴随资源 目录 一、说明二、 PyQt4三、PyOpenGL四、OpenGL 管线五、Python集成开发环境5.1 Emacs配置5.2 pycharm环境 六、你好,OpenGL!七、QGL控件八、平截头体.svg九、定义几何9.1 立即模式与保留模式9.2 使用 VBO 定义 Cube 十、渲染立方体十一、渲…...

vlan、三层交换机、网关、DNS、子网掩码、MAC地址详解

vlan、三层交换机、网关、DNS、子网掩码、MAC地址详解 一、 什么是VLAN? VLAN中文是“虚拟局域网”。 ​ LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成的企业网络。 ​ VLAN所指的LAN特指使用路由器分割的网络——也就是广…...

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记11:数字电位器MCP4017

系列文章目录 嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记01:赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记02:开发环境安装 嵌入式|蓝桥杯STM32G431(…...

CTF题型 nodejs(1) 命令执行绕过典型例题

CTF题型 nodejs(1) 命令执行绕过 文章目录 CTF题型 nodejs(1) 命令执行绕过一.nodejs中的命令执行二.nodejs中的命令绕过1.编码绕过2.拼接绕过3.模板字符串4.Obejct.keys5.反射6.过滤中括号的情况典型例题1.[GFCTF 2021]ez_calc2.[西湖论剑 2022]Node Magical Login 一.nodejs中…...

Mybatis在SpringBoot中是如何被加载执行

首先依赖于springboot的自动装配EnableAutoConfiguration注解,这个注解最终帮助我们读取mybatis-spring-boot-autoconfigure-x.x.x.jar中的META-INF\spring.factories配置类: org.springframework.boot.autoconfigure.EnableAutoConfiguration\ org.myb…...

数据采集用,集成了主流工业通讯协议

IoTClient 是一个物联网设备通讯协议实现客户端,集成了主流工业通讯协议,包括主流PLC通信读取、ModBus协议、Bacnet协议等。该组件基于.NET Standard 2.0,适用于.NET的跨平台开发,可在Windows、Linux等系统上运行,甚至…...

Django(三)-搭建第一个应用(2)

一、编写更多视图 问题详情页——展示某个投票的问题和不带结果的选项列表。问题结果页——展示某个投票的结果。投票处理器——用于响应用户为某个问题的特定选项投票的操作。 # 1.问题详情页:展示某个投票的问题和不带结果的选项列表 def detail(request,questi…...

求助:配置脚手架代理,跨域问题proxyTable配置无效,访问后显示404?

已经在这里卡了一天了。找了很多解决办法,比如重启,修改proxytable等等,但是每次但是404,求助各位大佬,怎么解决? 1、代码 (1)config的index.js (2) App.v…...

【4月】组队打卡《山有木Python特征工程极简入门》

活动名称 CDA Club 第2期《山有木兮Python数据分析极简入门》组队打卡 活动介绍 本次打卡活动由CDA俱乐部旗下学术部主办。目的是通过数据分析科普内容,为数据分析爱好者提供学习和交流的机会。方便大家利用碎片化时间在线学习,以组队打卡的形式提升学…...

Wireshark 抓包

启动时选择一个有信号的网卡双击打开,或者在 捕获选择里打开选择网卡。 然后输出下面的规则就可以抓到报文了。 最上面的三条是建立连接时的三次握手, 下面是发送数据hello 对应两条数据 最下面的4条是断时的4次挥手...

c语言运算符优先级

1、运算符介绍 在C语言中,运算符优先级是指在表达式中执行运算的先后顺序。按照C语言的标准规范,不同的运算符被赋予了不同的优先级等级,优先级高的运算符会先进行运算。如果同一优先级的运算符出现在同一个表达式中,则按照从左到…...

纳斯达克大屏媒体尺寸与投放费用:一次投放需要多少钱?

纳斯达克大屏媒体尺寸与投放费用:一次投放需要多少钱? 1. 纳斯达克图片要求 1.1 像素要求 高度:2336 像素宽度:1832 像素 1.2 分辨率要求 像素比率:1.0 px 72 dpi 1.3 文件格式要求 静态图片格式:.…...

将word转为PDF的几种简单方式

第一种:使用spire.doc.jar包,用时7秒左右。 引入spire.doc-11.1.1.jar包,该包带水印,建议使用免费版的spire.doc.free-5.2.0.jar,免费版只能转三页。 package web.tools.excel; import com.spire.doc.*; public cl…...

大型集团公司企业文化知识竞活动赛策划方案

一场高端企业文化知识竞赛活动完整策划书,按诗词大会舞美标准进行设计,竞赛规则新颖,值得收藏。 天纵高端知识竞赛服务商,20多年现场经验和软硬件开发。 专业承办全国高端知识竞赛活动。线上线下各类竞赛活动均可执行,…...

Spring Boot设置io临时目录

在部署springboot项目,使用MultipartFile上传文件会出现以下异常 Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.3016596448718765136.18001/work/Tomcat/localhost/xx] is …...

Polar 2024春季个人挑战赛 Jay17 WP

Polar 2024春季个人挑战赛 Rank&#xff1a;7 【WEB】机器人 开题 起手敏感文件robots.txt 【WEB】PHP反序列化初试 最简单的php反序列化 POC&#xff1a; <?php class Easy{public $name;public function __wakeup(){echo $this->name;} } class Evil{public $evi…...

10 mybatis 日志

文章目录 product.sqlpom.xmllogback.xmlmybatis-config.xmlProductsMapper.xmlProductsProductsMapper.java product.sql create table products (product_id int auto_increment comment 产品IDprimary key,product_name varchar(100) null comment 产品名称,bra…...

AJAX介绍使用案例

文章目录 一、AJAX概念二、AJAX快速入门1、编写AjaxServlet&#xff0c;并使用response输出字符&#xff08;后台代码&#xff09;2、创建XMLHttpRequest对象&#xff1a;用于和服务器交换数据 & 3、向服务器发送请求 & 4、获取服务器响应数据 三、案例-验证用户是否存…...

【echart】数据可视化

什么是数据可视化&#xff1f; 数据可视化主要目的:借助于图形化手段&#xff0c;清晰有效地传达与沟通信息。 数据可视化可以把数据从冰冷的数字转换成图形&#xff0c;揭示蕴含在数据中的规律和道理。 如何绘制&#xff1f; echarts 图表的绘制&#xff0c;大体分为三步:…...

排序(冒泡/快速/归并)

冒泡排序 时间复杂度为 O(n^2) 原理 比较相邻的元素. 如果第一个比第二个大,就交换他们两个.依次比较每一对相邻的元素—>结果 : 最后的元素是这组数中最大的重复上述步骤 , 除了最后一个[]因为最后一个已经是排好序的了(这组数中最大的那个)]持续对越来越少的元素进行如上…...

jq中的跨域

跨域 1.从一个地址到另外一个第一请求资源或者数据时&#xff0c;就有可能发生跨域 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>跨域</title><script src"jquery/jquery-1.11.3.j…...

CUDA学习笔记08: 原子规约/向量求和

参考资料 CUDA编程模型系列一(核心函数)_哔哩哔哩_bilibili 代码 #include <iostream> #include <cuda_runtime.h> #include <device_launch_parameters.h> #include <stdio.h> #include <math.h>#define N 10000000 #define BLOCK 256 #def…...

PointNet++论文复现(一)【PontNet网络模型代码详解 - 分类部分】

PontNet网络模型代码详解 - 分类部分 专栏持续更新中!关注博主查看后续部分! 分类模型的训练: ## e.g., pointnet2_ssg without normal features python train_classification.py --model pointnet2_cls_ssg --log_dir pointnet2_cls_ssg python test_classification.py…...

AI渣土车监测报警摄像机

随着城市建设的不断发展和交通运输的快速增长&#xff0c;渣土车作为建筑行业中不可或缺的运输工具&#xff0c;承担着大量的渣土运输任务。然而&#xff0c;由于渣土车在运输过程中存在超速、违规变道、碾压行人等交通安全问题&#xff0c;给道路交通和行人安全带来了严重的隐…...

Spring框架介绍及详细使用

前言 本篇文章将会对spring框架做出一个比较详细的讲解&#xff0c;并且每个知识点基本都会有例子演示&#xff0c;详细记录下了我在学习Spring时所了解到全部知识点。 在了解是什么spring之前&#xff0c;我们要先知道spring框架在开发时&#xff0c;服务器端采用三层架构的方…...

【论文速读】| 对大语言模型解决攻击性安全挑战的实证评估

本次分享论文为&#xff1a;An Empirical Evaluation of LLMs for Solving Offensive Security Challenges 基本信息 原文作者&#xff1a;Minghao Shao, Boyuan Chen, Sofija Jancheska, Brendan Dolan-Gavitt, Siddharth Garg, Ramesh Karri, Muhammad Shafique 作者单位&a…...

小迪安全48WEB 攻防-通用漏洞Py 反序列化链构造自动审计 bandit魔术方法

#知识点&#xff1a; 1、Python-反序列化函数使用 2、Python-反序列化魔术方法 3、Python-反序列化 POP 链构造&#xff08;payload构造&#xff09; 4、Python-自动化审计 bandit 使用 #前置知识&#xff1a; 函数使用&#xff1a; pickle.dump(obj, file) : 将对…...

微服务:解放软件开发的神器,引领企业级应用的未来(二)

本系列文章简介&#xff1a; 本系列文章将深入剖析微服务架构的原理、设计和实践&#xff0c;向大家介绍微服务的核心概念和关键技术&#xff0c;以及在实际项目中的应用和实践经验。我们将通过具体的案例和实例&#xff0c;帮助大家理解微服务架构的优势和挑战&#xff0c;掌握…...

easyexcel与vue配合下载excel

后端 设置响应 // 设置响应头 response.setContentType("application/octet-stream;charsetUTF-8"); String returnName null; try {returnName URLEncoder.encode(fileName, "UTF-8"); } catch (UnsupportedEncodingException e) {throw new RuntimeExc…...

Vue.js 模板语法

Vue.js 使用了基于 HTML 的模板语法&#xff0c;允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。 Vue.js 的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统。 结合响应系统&#xff0c;在应用状态改变时&#xff0c; Vue 能够智能地计算出重新…...