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一下…...

redis6.0之后的多线程版本的问题
一、redis早期版本和新版本的讨论 这个问题其实有些废话,哪个版本肯定都有不同啊。其实这里主要是提到的网上的大家对Redis6.0中的多线程版本的不同即以前宣传的Redis是单线程程版的,之后变成了多线程版本的。网上对这个讨论非常激烈,反正各…...

python的 pandas.Dataframe 和 pandas.Series基础内容
目录 0 有一个比较麻烦琐碎的地方 1 python pandas.Dataframe 2 pd.concat() 可以合并 pd.Dataframe 2.1 pd.concat() 合并规则 3 pd.Dataframe.drop() 删除行列的操作 4 pd.Dataframe 列操作 5 pd.Dataframe 行操作 5.1 sample_dataframe2.head(n2) 取前面的n行&…...

golang学习5
为结构体添加方法 异常处理过程...

【C语言】11月第二次测试 ing
文章目录 1.输入n名同学的成绩和学号,对成绩排序,输出对应学号 要求重复的学号重新输入 计算n名同学的平均值,对小于60分的同学删除分数 大于60分的同学输出:优秀:几人,良好:几人,中…...

行列式的理解与计算:线性代数中的核心概念
开发领域:前端开发 | AI 应用 | Web3D | 元宇宙 技术栈:JavaScript、React、ThreeJs、WebGL、Go 经验经验:6 年 前端开发经验,专注于图形渲染和 AI 技术 开源项目:github 简智未来、数字孪生引擎、前端面试题 大家好&a…...

按出生日期排序(结构体专题)
题目描述 送人玫瑰手有余香,小明希望自己能带给他人快乐,于是小明在每个好友生日的时候发去一份生日祝福。小明希望将自己的通讯录按好友的生日排序排序,这样就查看起来方便多了,也避免错过好友的生日。为了小明的美好愿望&#x…...

【C++】拆分详解 - 多态
文章目录 一、概念二、定义和实现1. 多态的构成条件2. 虚函数2.1 虚函数的重写/覆盖2.2 虚函数重写的两个例外 3. override 和 final关键字4. 重载/重写/隐藏的对比5. 例题 三、纯虚函数和抽象类四、多态的原理1. 虚函数表2. 实现原理3. 动态绑定和静态绑定 总结 一、概念 多态…...

Python世界:力扣题解875,珂珂爱吃香蕉,中等
Python世界:力扣题解875,珂珂爱吃香蕉,中等 任务背景思路分析代码实现坑点排查测试套件本文小结 任务背景 问题来自力扣题目875 Koko Eating Bananas,大意如下: Koko loves to eat bananas. There are n piles of bana…...

Java设计模式 —— Java七大设计原则详解
文章目录 前言一、单一职责原则1、概述2、案例演示 二、接口隔离原则1、概述2、案例演示 三、依赖倒转原则1、概述2、案例演示 四、里氏替换原则1、概述2、案例演示 五、开闭原则1、概述2、案例演示 六、迪米特法则1、概述2、案例演示 七、合成/聚合复用原则1、概述2、组合3、聚…...

SpringBoot学习记录(六)配置文件参数化
SpringBoot学习记录(六)配置文件参数化 一、参数提取到配置文件中二、yml配置文件三、ConfigurationProperties注解实现批量属性注入 一、参数提取到配置文件中 定义在代码中的参数的值分散在各个不同的文件中,不便于后期维护管理࿰…...