qt+opengl 三维物体加入摄像机
1 在前几期的文章中,我们已经实现了三维正方体的显示了,那我们来实现让物体的由远及近,和由近及远。这里我们需要了解一个概念摄像机。
1.1 摄像机定义:在世界空间中位置、观察方向、指向右侧向量、指向上方的向量。如下图所示:

1.2 实现一个摄像机
首先定义一个摄像机位置,然后获取一个摄影机指向原点的向量,并且获取指向摄像机的单位向量(只关心摄像机的方向,不关心其长度).代码如下所示:
-
QVector3D cameraPos(0, 0, 3)
-
QVector3D cameraTarget(0, 0, 0);
-
QVector3D cameraDirection( (cameraTarget- cameraPos).normalized() )
1.3 摄像机位置
摄像机位置是在世界空间中一个指向摄像机位置的向量。右手坐标系:大拇指指向正x轴方向,食指指向正y轴方向,中指指向正z轴方向,z正轴从屏幕指向自己。

通过改变摄像机的位置就可以实现物体的远近效果。
在qt opengl 函数里面我们有函数实现了
void QMatrix4x4::lookAt(const QVector3D &eye, const QVector3D ¢er, const QVector3D &up)
//获取lookAt矩阵.
//eye: 设置摄像机(眼睛)位置,比如QVector3D(0,0,3)
//center:表示摄像机(眼睛)正在看的视图的中心,比如原点QVector3D(0,0,0)
//up:眼睛的上向量,一般为QVector3D(0,1,0),通过该向量就能获取到眼睛的右轴和上轴
这里我们只需要设置相应的参数就可以了
eye : 就是我们眼睛的位置,这里我们设置Z轴正方向 QVector3D(0, 0, 3);
center : 就是我们以什么地方为中心点观察物体,如QVector3D(0, 0, 0);原点。
up:眼睛的上向量,一般为QVector3D(0,1,0),通过该向量就能获取到眼睛的右轴和上轴
好了,那么我们现在来修改glsl语句和代码实现。
#include "glwidget.h"
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QMouseEvent>
#include <QDateTime>
#include <QtMath>static const char *vertexShaderSource ="#version 330\n""layout (location = 0) in vec4 vertex;\n""layout (location = 1) in vec4 texCoord;\n""out vec4 texc;\n""uniform mat4 matrix;\n""uniform mat4 model;\n""uniform mat4 view;\n""uniform mat4 projection;\n""void main(void)\n""{\n"" gl_Position = projection*view* matrix * vertex;\n"" texc = texCoord;\n""}\n";static const char *fragmentShaderSource ="#version 330\n""uniform sampler2D texture;\n""in vec4 texc;\n""void main(void)\n""{\n"" gl_FragColor = texture2D(texture, texc.st);\n""}\n";GLWidget::GLWidget():QOpenGLWidget(),m_xRos(0),m_yRos(0)
{cam = QVector3D(m_xRos, m_yRos, m_zRos);cameraPos = QVector3D(0, 0, 3); 近---远// cameraPos = QVector3D(0, 0, 30);远---近timer = new QTimer;timer->setInterval(20);connect(timer,&QTimer::timeout,this,[=]{qDebug()<<"timeout"<<nCount<<m_xRos;rotateBy(2 * 16, +2 * 16, -1 * 16);});}
GLWidget::~GLWidget()
{makeCurrent();vbo.destroy();for (int i = 0; i < 6; ++i)delete textures[i];delete program;doneCurrent();
}QSize GLWidget::minimumSizeHint() const
{return QSize(400, 400);
}QSize GLWidget::sizeHint() const
{return QSize(400, 400);
}void GLWidget::rotateBy(int xAngle, int yAngle, int zAngle)
{float cameraSpeed = 0.2;cameraPos += cameraSpeed * QVector3D(0, 0, 1);//由远到近//cameraPos -= cameraSpeed * QVector3D(0, 0, 1);//由近到远xRot += xAngle;yRot += yAngle;zRot += zAngle;update();
}void GLWidget::setClearColor(const QColor &color)
{clearColor = color;update();
}void GLWidget::initializeGL()
{vertices = {// ---- 位置---- - 纹理坐标 - ---- 颜色 ----0.5f, -0.5f, -0.5f, 1.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f,//10.5f, 0.5f, -0.5f, 1.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,//20.5f, -0.5f, 0.5f, 1.0f, 1.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,//3-0.5f, -0.5f, -0.5f, 1.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 1.0f, 0.0f,//40.5f, -0.5f, 0.5f, 1.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f,//5-0.5f, -0.5f, 0.5f, 1.0f, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,};initializeOpenGLFunctions();// makeObject();glEnable(GL_DEPTH_TEST);glEnable(GL_CULL_FACE);//#define PROGRAM_VERTEX_ATTRIBUTE 0
//#define PROGRAM_TEXCOORD_ATTRIBUTE 1program = new QOpenGLShaderProgram;program->addShaderFromSourceCode(QOpenGLShader::Vertex,vertexShaderSource);program->addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShaderSource);program->link();program->bind();//激活Program对象vbo.create();vbo.bind(); //绑定到当前的OpenGL上下文,vbo.allocate(vertices.constData(), vertices.count() * sizeof(GLfloat));//初始化VAO,设置顶点数据状态(顶点,法线,纹理坐标等)vao.create();vao.bind();for (int j = 0; j < 6; ++j){textures[j] = new QOpenGLTexture(QImage(QString(":/cube%1.png").arg(j + 1)).mirrored());textures[j]->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,QOpenGLTexture::Linear);textures[j]->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToEdge);textures[j]->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToEdge);}program->setAttributeBuffer(0, GL_FLOAT, 0, 3, 5 * sizeof(float)); //设置aPos顶点属性program->setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(float), 2, 5 * sizeof(float)); //设置aColor顶点颜色program->enableAttributeArray(0); //使能aPos顶点属性program->enableAttributeArray(1); //使能aColor顶点颜色program->setUniformValue("texture", 0);QMatrix4x4 projection;projection.perspective(60,(float)width()/height(),0.1,100);//构建透视矩阵,这个可以是固定写法program->setUniformValue("projection", projection);// vao.release();
// vbo.release();
}void GLWidget::paintGL()
{//glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF());glEnable(GL_DEPTH_TEST);glClearColor(0.1f,0.5f,0.7f,1.0f); //设置清屏颜色glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);QMatrix4x4 m;//m.ortho(-0.5f, +0.5f, +0.5f, -0.5f, 4.0f, 15.0f);m.translate(0.0f, 0.0f, 0.0f);m.rotate(xRot / 16.0f, 1.0f, 0.0f, 0.0f);m.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f);m.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f);m.scale(0.5);program->setUniformValue("matrix", m);// QMatrix4x4 view;
// view.translate(0.0f,0.0f,-3.0f);
// program->setUniformValue("view", view);QMatrix4x4 view;view.lookAt(cameraPos, QVector3D(0, 0, 0), QVector3D(0, 1, 0));//view.lookAt(cameraPos, cameraPos+QVector3D(0,0,-1), QVector3D(0,1,0));program->setUniformValue("view", view);for (int i = 0; i < 6; ++i) {textures[i]->bind();glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);}
}
void GLWidget::resizeGL(int width, int height)
{this->glViewport(0,0,width,height); //定义视口区域
}void GLWidget::mousePressEvent(QMouseEvent *event)
{lastPos = event->pos();timer->start();
}void GLWidget::mouseMoveEvent(QMouseEvent *event)
{int dx = event->x() - lastPos.x();int dy = event->y() - lastPos.y();if (event->buttons() & Qt::LeftButton) {rotateBy(8 * dy, 8 * dx, 0);} else if (event->buttons() & Qt::RightButton) {rotateBy(8 * dy, 0, 8 * dx);}lastPos = event->pos();
}void GLWidget::mouseReleaseEvent(QMouseEvent * /* event */)
{emit clicked();
}
#ifndef GLWIDGET_H
#define GLWIDGET_H#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QTimer>
#include <QOpenGLTexture>
#include <QOpenGLShaderProgram>QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram);
QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{Q_OBJECTpublic://using QOpenGLWidget::QOpenGLWidget;GLWidget();~GLWidget();QSize minimumSizeHint() const override;QSize sizeHint() const override;void rotateBy(int xAngle, int yAngle, int zAngle);void setClearColor(const QColor &color);signals:void clicked();protected:void initializeGL() override;void paintGL() override;void resizeGL(int width, int height) override;void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;private:QColor clearColor = Qt::black;QPoint lastPos;int xRot = 0;int yRot = 0;int zRot = 0;QOpenGLTexture *textures[6] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};QOpenGLShaderProgram *program = nullptr;QOpenGLBuffer vbo;QVector<float> vertices;QOpenGLVertexArrayObject vao;QTimer* timer;float m_xRos = 0.0f;float m_yRos = 0.0f;float m_zRos = 3.0f;QVector3D cam;int nCount=0;QVector3D cameraPos;QVector3D cameraTarget;QVector3D cameraDirection;
};#endif
运行下代码是不是就是可以由远到近和由近到远了呢.
我们初始化
cameraPos = QVector3D(0, 0, 3); cameraPos += cameraSpeed * QVector3D(0, 0, 1);//由近到远
这样写就是近--远了呢
cameraPos = QVector3D(0, 0, 30); cameraPos -= cameraSpeed * QVector3D(0, 0, 1);//由远到近了呢
我们这样写是固定了摄像机观察的点是QVector3D(0, 0, 0),可是有个问题是不是当我们设置eye为
cameraPos = QVector3D(0, 0, 30);的时候,运行出来显示出来的效果是由远到近,然后又近到远了呢?为什么?因为
cameraPos -= cameraSpeed * QVector3D(0, 0, 1);这个值减少到负方向了?
所以我们修改下程序,修改center(摄像机观察的点)让观察点随着摄像机变化,是不是就没有由远到近 ,然后又由近到远呢?上代码
#include "glwidget.h"
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QMouseEvent>
#include <QDateTime>
#include <QtMath>static const char *vertexShaderSource ="#version 330\n""layout (location = 0) in vec4 vertex;\n""layout (location = 1) in vec4 texCoord;\n""out vec4 texc;\n""uniform mat4 matrix;\n""uniform mat4 model;\n""uniform mat4 view;\n""uniform mat4 projection;\n""void main(void)\n""{\n"" gl_Position = projection*view* matrix * vertex;\n"" texc = texCoord;\n""}\n";static const char *fragmentShaderSource ="#version 330\n""uniform sampler2D texture;\n""in vec4 texc;\n""void main(void)\n""{\n"" gl_FragColor = texture2D(texture, texc.st);\n""}\n";GLWidget::GLWidget():QOpenGLWidget(),m_xRos(0),m_yRos(0)
{cam = QVector3D(m_xRos, m_yRos, m_zRos);cameraPos = QVector3D(0, 0, 3);timer = new QTimer;timer->setInterval(20);connect(timer,&QTimer::timeout,this,[=]{qDebug()<<"timeout"<<nCount<<m_xRos;rotateBy(2 * 16, +2 * 16, -1 * 16);});}
GLWidget::~GLWidget()
{makeCurrent();vbo.destroy();for (int i = 0; i < 6; ++i)delete textures[i];delete program;doneCurrent();
}QSize GLWidget::minimumSizeHint() const
{return QSize(400, 400);
}QSize GLWidget::sizeHint() const
{return QSize(400, 400);
}void GLWidget::rotateBy(int xAngle, int yAngle, int zAngle)
{float cameraSpeed = 0.2;cameraPos -= cameraSpeed * QVector3D(0, 0, -1);//由远到近//cameraPos += cameraSpeed * QVector3D(0, 0, -1);//由近到远xRot += xAngle;yRot += yAngle;zRot += zAngle;update();
}void GLWidget::setClearColor(const QColor &color)
{clearColor = color;update();
}void GLWidget::initializeGL()
{vertices = {// ---- 位置---- - 纹理坐标 - ---- 颜色 ----0.5f, -0.5f, -0.5f, 1.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f,//10.5f, 0.5f, -0.5f, 1.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,//20.5f, -0.5f, 0.5f, 1.0f, 1.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,//3-0.5f, -0.5f, -0.5f, 1.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 1.0f, 0.0f,//40.5f, -0.5f, 0.5f, 1.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f,//5-0.5f, -0.5f, 0.5f, 1.0f, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,};initializeOpenGLFunctions();// makeObject();glEnable(GL_DEPTH_TEST);glEnable(GL_CULL_FACE);//#define PROGRAM_VERTEX_ATTRIBUTE 0
//#define PROGRAM_TEXCOORD_ATTRIBUTE 1program = new QOpenGLShaderProgram;program->addShaderFromSourceCode(QOpenGLShader::Vertex,vertexShaderSource);program->addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShaderSource);program->link();program->bind();//激活Program对象vbo.create();vbo.bind(); //绑定到当前的OpenGL上下文,vbo.allocate(vertices.constData(), vertices.count() * sizeof(GLfloat));//初始化VAO,设置顶点数据状态(顶点,法线,纹理坐标等)vao.create();vao.bind();for (int j = 0; j < 6; ++j){textures[j] = new QOpenGLTexture(QImage(QString(":/cube%1.png").arg(j + 1)).mirrored());textures[j]->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,QOpenGLTexture::Linear);textures[j]->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToEdge);textures[j]->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToEdge);}program->setAttributeBuffer(0, GL_FLOAT, 0, 3, 5 * sizeof(float)); //设置aPos顶点属性program->setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(float), 2, 5 * sizeof(float)); //设置aColor顶点颜色program->enableAttributeArray(0); //使能aPos顶点属性program->enableAttributeArray(1); //使能aColor顶点颜色program->setUniformValue("texture", 0);QMatrix4x4 projection;projection.perspective(60,(float)width()/height(),0.1,100);//构建透视矩阵,这个可以是固定写法program->setUniformValue("projection", projection);// vao.release();
// vbo.release();
}void GLWidget::paintGL()
{//glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF());glEnable(GL_DEPTH_TEST);glClearColor(0.1f,0.5f,0.7f,1.0f); //设置清屏颜色glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);QMatrix4x4 m;//m.ortho(-0.5f, +0.5f, +0.5f, -0.5f, 4.0f, 15.0f);m.translate(0.0f, 0.0f, 0.0f);m.rotate(xRot / 16.0f, 1.0f, 0.0f, 0.0f);m.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f);m.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f);m.scale(0.5);program->setUniformValue("matrix", m);// QMatrix4x4 view;
// view.translate(0.0f,0.0f,-3.0f);
// program->setUniformValue("view", view);QMatrix4x4 view;view.lookAt(cameraPos, cameraPos+QVector3D(0,0,-1), QVector3D(0,1,0));program->setUniformValue("view", view);for (int i = 0; i < 6; ++i) {textures[i]->bind();glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);}
}
void GLWidget::resizeGL(int width, int height)
{this->glViewport(0,0,width,height); //定义视口区域
}void GLWidget::mousePressEvent(QMouseEvent *event)
{lastPos = event->pos();timer->start();
}void GLWidget::mouseMoveEvent(QMouseEvent *event)
{int dx = event->x() - lastPos.x();int dy = event->y() - lastPos.y();if (event->buttons() & Qt::LeftButton) {rotateBy(8 * dy, 8 * dx, 0);} else if (event->buttons() & Qt::RightButton) {rotateBy(8 * dy, 0, 8 * dx);}lastPos = event->pos();
}void GLWidget::mouseReleaseEvent(QMouseEvent * /* event */)
{emit clicked();
}
我们运行程序,最后点击下屏幕,是不是实现了呢?
相关文章:
qt+opengl 三维物体加入摄像机
1 在前几期的文章中,我们已经实现了三维正方体的显示了,那我们来实现让物体的由远及近,和由近及远。这里我们需要了解一个概念摄像机。 1.1 摄像机定义:在世界空间中位置、观察方向、指向右侧向量、指向上方的向量。如下图所示: …...
day05(单片机高级)PCB基础
目录 PCB基础 什么是PCB?PCB的作用? PCB的制作过程 PCB板的层数 PCB设计软件 安装立创EDA PCB基础 什么是PCB?PCB的作用? PCB(Printed Circuit Board),中文名称为印制电路板,又称印刷…...
全球天气预报5天-经纬度版免费API接口教程
接口简介: 获取全球任意地区未来5天天气预报,必须传经纬度参数。可先调用【位置坐标】分类下相关接口获取地区经纬度坐标。 请求地址: https://cn.apihz.cn/api/tianqi/tqybjw5.php 请求方式: POST或GET。 请求参数:…...
Shell编程8
声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…...
python语言基础-5 进阶语法-5.5 上下文管理协议(with语句)
声明:本内容非盈利性质,也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站,会尽量附上原文链接,并鼓励大家看原文。侵删。 5.5 上下文管理协议(with语句)(参考链接࿱…...
自动驾驶3D目标检测综述(三)
前两篇综述阅读理解放在这啦,有需要自行前往观看: 第一篇:自动驾驶3D目标检测综述(一)_3d 目标检测-CSDN博客 第二篇:自动驾驶3D目标检测综述(二)_子流行稀疏卷积 gpu实现-CSDN博客…...
【GESP】C++三级练习 luogu-B3661, [语言月赛202209] 排排
三级知识点一维数组练习,除了应用了数组以外,其余逻辑比较简单,适合初学者。 题目题解详见:https://www.coderli.com/gesp-3-luogu-b3661/ 【GESP】C三级练习 luogu-B3661, [语言月赛202209] 排排队 | OneCoder三级知识点一维数…...
【PPTist】添加PPT模版
前言:这篇文章来探索一下如何应用其他的PPT模版,给一个下拉菜单,列出几个项目中内置的模版 PPT模版数据 (一)增加菜单项 首先在下面这个菜单中增加一个“切换模版”的菜单项,点击之后在弹出框中显示所有的…...
大疆上云api开发
目前很多公司希望使用上云api开发自己的无人机平台,但是官网资料不是特别全,下面浅谈一下本人开发过程中遇到的一系列问题。 本人使用机场为大疆机场2,飞机为M3TD,纯内网使用 部署 链接: 上云api代码. 首先从github上面拉去代码 上云api代码github. 后…...
IDEA2023 SpringBoot整合MyBatis(三)
一、数据库表 CREATE TABLE students (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,age INT,gender ENUM(Male, Female, Other),email VARCHAR(100) UNIQUE,phone_number VARCHAR(20),address VARCHAR(255),date_of_birth DATE,enrollment_date DATE,cours…...
【Apache Paimon】-- 6 -- 清理过期数据
目录 1、简要介绍 2、操作方式和步骤 2.1、调整快照文件过期时间 2.2、设置分区过期时间 2.2.1、举例1 2.2.2、举例2 2.3、清理废弃文件 3、参考 1、简要介绍 清理 paimon (表)过期数据可以释放存储空间,优化资源利用并提升系统运行效率等。本文将介绍如何清理 Paim…...
C语言数据结构——详细讲解 双链表
从单链表到双链表:数据结构的演进与优化 前言一、单链表回顾二、单链表的局限性三、什么是双链表四、双链表的优势1.双向遍历2.不带头双链表的用途3.带头双链表的用途 五、双链表的操作双链表的插入操作(一)双链表的尾插操作(二&a…...
Shell脚本基础(4):条件判断
内容预览 ≧∀≦ゞ Shell脚本基础(4):条件判断声明导语基本的if语句结构数值比较运算符文件测试运算符扩展:使用elif和else使用&&和||结合条件判断小结 Shell脚本基础(4):条件判断 声明…...
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
文章目录 前言摘要描述题解答案题解代码题解代码分析示例测试及结果时间复杂度空间复杂度总结 前言 本题由于没有合适答案为以往遗留问题,最近有时间将以往遗留问题一一完善。 LeetCode - #140 单词拆分 II 不积跬步,无以至千里;不积小流&…...
win10中使用ffmpeg和MediaMTX 推流rtsp视频
在win10上测试下ffmpeg推流rtsp视频,需要同时用到流媒体服务器MediaMTX 。ffmpeg推流到流媒体服务器MediaMTX ,其他客户端从流媒体服务器拉流。 步骤如下: 1 下载MediaMTX github: Release v1.9.3 bluenviron/mediamtx GitHub…...
16. 【.NET 8 实战--孢子记账--从单体到微服务】--汇率获取定时器
这篇文章我们将一起编写这个系列专栏中第一个和外部系统交互的功能:获取每日汇率。下面我们一起来编写代码吧。 一、需求 根据文章标题可知,在这片文章中我们只进行汇率的获取和写入数据库。 编号需求说明1获取每日汇率1. 从第三方汇率API中获取汇率信…...
C#元组详解:创建、访问与解构
在C#中,元组(Tuple)是一种数据结构,用于将多个元素组合成一个单一的对象。元组可以包含不同类型的元素,并且每个元素都有一个指定的位置(索引)。元组在需要临时组合多个值而不想创建自定义类时非…...
wsl2安装
Windows Subsystem for Linux 2 (WSL2) 是 Windows 10 和 Windows 11 中用于运行 Linux 二进制可执行文件的兼容层。WSL2 是 WSL 的最新版本,提供了更快的文件系统性能和完整的系统调用兼容性。本教程将指导你如何在 Windows 系统上安装 WSL2。 前提条件 操作系统要…...
android studio无法下载,Could not GET xxx, Received status code 400
-- 1. 使用下面的地址代替 原地址: distributionUrlhttps\://services.gradle.org/distributions/gradle-6.5-all.zip 镜像地址: distributionUrlhttps\://downloads.gradle-dn.com/distributions/gradle-6.5-all.zips 上面的已经不好用了 https\://mirrors.cloud.tencent.c…...
RUST学习教程-安装教程
文章目录 参考文档安装教程更新卸载 参考文档 https://course.rs/first-try/installation.html 安装教程 Linux或者mac安装教程 curl --proto https --tlsv1.2 https://sh.rustup.rs -sSf | sh安装完成,当出现command not found的时候,需要source一下…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
