slam学习笔记

2023-05-16

ubuntu20.04 使用vs code编写

现放cmake文件(记得链接库文件和配置C++版本)

cmake_minimum_required( VERSION 2.8 )

project(learingMatrix)

set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CXX_FLAGS "-std=c++17")

include_directories("/usr/include/eigen3")
add_executable(learningMatrix eigenMatrix.cpp)
add_executable(learnningGeometry useGeometry.cpp)
add_executable(coordinatetrans coordinateTransform.cpp)
add_executable(plot plotTrajectory.cpp)
add_executable(cube visualizeGeometry.cpp)

include_directories(${Pangolin_INCLUDE_DIRS})
find_package( Pangolin )

target_link_libraries(plot ${Pangolin_LIBRARIES})

target_link_libraries(cube ${Pangolin_LIBRARIES})

以下为eigen的简单运算部分

#include <iostream>
using namespace std;

#include <ctime>

#include <Eigen/Core>           //eigen 核心
#include <Eigen/Dense>          //稠密矩阵运算规则
using namespace Eigen;

#define MATRIX_SIZE 50

int main(int argc, char** argv)
{
    Matrix<float,2,3> matrix_23;   //Matrix模板类用三个参数生成一个矩阵 数据类型,行,列

    Vector3d v_3d;                 //Vector3d生成一个三维行向量,d是double的意思,本质上还是Matrix一个特殊形式 
    Matrix<double,3,1>  v1_3d;    //同一个意思

    Matrix3d matrix_33 = Matrix3d::Zero(); //Matrix3d生成一个3*3的方阵, Zero是0阵

    Matrix<double , Dynamic,Dynamic> matrix_dynamic; //定义动态矩阵,行和列随数据变化
    MatrixXd matrix_x;                               //同上

    // ------------------------------------------------------------------------------------

    matrix_23<<1,2,3,4,5,6;        //输入数据(运算符重载)

    cout<<"matrix 2*3 from 1 to 6 : "<<matrix_23<<endl; //输出(运算符重载)

    cout<<"print matrix 2*3: "<<endl;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<3;j++)
        {
            cout<<matrix_23(i,j)<<"\t";
        }
        cout<<endl;
    }

    //-----------------------------------------------------------------------------------------
    v_3d << 3,2,1;
    v1_3d <<4,5,6;

    //Matrix<double ,2,1> result_wrong_type =matrix_23*v1_3d;(不能混用不同数据类型的矩阵,eigen不会自动升级数据类型)
    Matrix<double , 2, 1> result = matrix_23.cast<double>()*v_3d;           //cast转换数据类型
    cout<<"[1,2,3;4,5,6]*[3,2,1]="<<result.transpose()<<endl;

    Matrix<double , 2,1> result2 = matrix_23.cast<double>()*v1_3d;
    cout<<"[1,2,3;4,5,6]*[4,5,6]="<<result2.transpose()<<endl;              //transpose转置
    //Eigen::Matrix<double , 2,3 > result_wrong_dimension = matrix_23.cast<double>()*v_3d; (不同维度的矩阵不能直接赋值,eigen不会自动填充空白)

    //----------------------------------------------------------------------------------------
    matrix_33 = Matrix3d::Random();                                         //随机填充数
    cout<<"random matrix:\n"<<matrix_33<<endl;
    cout<<"transpose :\n"<<matrix_33.transpose()<<endl;
    cout<<"sum: \n"<<matrix_33.sum()<<endl;
    cout<<"trace: \n"<<matrix_33.trace()<<endl;
    cout<<"10 times: \n"<<10*matrix_33<<endl;
    cout<<"inverse ; \n"<<matrix_33.inverse()<<endl;                        //不推荐直接求逆,维度一大起来,计算量太大
    cout<<"det: \n"<<matrix_33.determinant()<<endl;

    //----------------------------------------------------------------------------------------
    SelfAdjointEigenSolver<Matrix3d> eigen_solver(matrix_33.transpose()*matrix_33);  //矩阵对角化?
    cout<<"Eigen value =\n"<< eigen_solver.eigenvalues()<<endl;
    cout<<"Eigen vectors = \n"<<eigen_solver.eigenvectors()<<endl;   

    //----------------------------------------------------------------------------------------
    Matrix<double,MATRIX_SIZE,MATRIX_SIZE> matrix_NN
    = MatrixXd::Random(MATRIX_SIZE,MATRIX_SIZE);
    matrix_NN = matrix_NN * matrix_NN.transpose();
    Matrix<double,MATRIX_SIZE,1> v_Nd = MatrixXd::Random(MATRIX_SIZE,1);

    clock_t time_stt = clock();
    //----------------------------------------------------------------------------------------
    //直接求逆
    Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse() * v_Nd;
    cout<<"time of normal inverse is "
        <<1000*(clock()-time_stt)/(double) CLOCKS_PER_SEC<<"ms"<<endl;
    cout<<"x = "<<x.transpose()<<endl;
    //----------------------------------------------------------------------------------------
    //Qr分解
    time_stt = clock();
    x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
    cout<<"time of Qr decomposition is "
        <<1000*(clock()-time_stt)/(double) CLOCKS_PER_SEC<<"ms"<<endl;
    cout<<"x = "<<x.transpose()<<endl;
    //----------------------------------------------------------------------------------------
    //正定阵可以用cholesky分解
    time_stt = clock();
    x = matrix_NN.ldlt().solve(v_Nd);
    cout<<"time of ldlt decomposition is "
        <<1000*(clock()-time_stt)/(double) CLOCKS_PER_SEC<<"ms"<<endl;
    cout<<"x = "<<x.transpose()<<endl;

    return 0;
}

以下为eigen的几何运算部分

#include <iostream>
#include <cmath>
using namespace std;

#include <Eigen/Core>
#include <Eigen/Geometry>
using namespace Eigen;

int main(int argc,char** argv)
{
    Matrix3d rotation_matrix = Matrix3d::Identity();            //旋转矩阵
    AngleAxisd rotation_vector(M_PI/4,Vector3d(0,0,1));         //旋转向量      绕Z轴旋转45度
    cout.precision(3);
    cout<<"rotation matrix= \n"<<rotation_vector.matrix()<<endl;//用.matrix()把轴角式转换成矩阵输出

    rotation_matrix=rotation_vector.toRotationMatrix();         //toRotationmatrix可以直接转换成矩阵并赋值
//用轴角 旋转向量--------------------------------------------------------------------------------------------
    Vector3d v(1,0,0);
    Vector3d v_rotated = rotation_vector * v;
    cout<<"(1,0,0) after rotation (by angle axis) = "<<v_rotated.transpose()<<endl;
//用旋转矩阵 旋转向量----------------------------------------------------------------------------------------
    v_rotated = rotation_matrix * v;
    cout<<"(1,0,0) after rotation (by matrix) = "<<v_rotated.transpose()<<endl;
//欧拉角转换-----------------------------------------------------------------------------------------------
    Vector3d euler_angles = rotation_matrix.eulerAngles(2,1,0);
    cout<<"yaw pitch roll = "<<euler_angles.transpose()<<endl;
//欧式变换(长度、夹角、)
    Isometry3d T = Isometry3d::Identity();                 //4*4的矩阵!!!
    T.rotate(rotation_vector);                             //旋转 
    T.pretranslate(Vector3d(1,3,4));                       //平移
    cout<<"Transform matrix = \n"<<T.matrix()<<endl;
// 用变换矩阵变换
    Vector3d v_transformed = T*v;
    cout<<"v transformed = "<<v_transformed.transpose();

//四元数(四元数和轴角之间可以相互转换)
    Quaterniond q = Quaterniond(rotation_vector);
    cout<<"quaternion from rotation vector = "<<q.coeffs().transpose()<<endl;
    q = Quaterniond(rotation_matrix);
    cout<<"quaternion from rotation matrix = "<<q.coeffs().transpose()<<endl;
//用四元数旋转一个向量
    v_rotated = q * v;                                      
    cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;
//从数学表达式应该是下面的qvq^-1
    cout<<"should be equal to "<<(q*Quaterniond(0,1,0,0) * q.inverse()).coeffs().transpose()<<endl;
    
    return 0;
}

以下为两个小机器人的坐标变换问题

#include <iostream>
#include <vector>
#include <algorithm>
#include <Eigen/Core>
#include <Eigen/Geometry>
using namespace std;
using namespace Eigen;


int main(int argc,char** argv)
{
    Quaterniond q1(0.35,0.2,0.3,0.1),q2(-0.5,0.4,-0.1,0.2);       //一号位姿q1,t1,二号位姿q2,t2  四元数表示旋转,t为平移矩阵
    q1.normalize();                                               //归一化数据
    q2.normalize();
    Vector3d t1(0.3,0.1,0.1),t2(-0.1,0.5,0.3);
    Vector3d p1(0.5,0,0.2);                                       //目标在一号机器人坐标系下的坐标

    Isometry3d T1w(q1),T2w(q2);                                   //隐藏了一部旋转向量设定
    // T1w.rotate(q1);
    //T2w.rotate(q2);                                             //旋转向量设定

    T1w.pretranslate(t1);                                         //平移向量设定
    T2w.pretranslate(t2);

    Vector3d p2 =T2w * T1w.inverse()*p1;                          //目标由(一号转世界)(世界转二号)转换至二号机器人坐标系下,得到p2
    cout<<endl<<p2.transpose();
    return 0;
}

以下为pangolin路径绘制部分

#include <iostream>
#include <pangolin/pangolin.h>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <unistd.h>
using namespace std;
using namespace Eigen;

string trajectory_file = "/home/martin/桌面/code/eigen/trajectory.txt";
void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>>);       //先声明函数

int main(int argc,char** argv)
{
    vector<Isometry3d,Eigen::aligned_allocator<Isometry3d>> poses;                   //声明
    ifstream fin(trajectory_file);
    if(!fin)
    {
        cout<<"cannot find trajectory file at "<<trajectory_file<<endl;
        return 1;
    }

    while (!fin.eof())
    {
        double time ,tx, ty, tz, qx, qy, qz, qw;
        fin>>time>>tx>>ty>>tz>>qx>>qy>>qz>>qw;                                       //读取时间、平移、旋转
        Isometry3d Twr(Quaterniond(qw,qx,qy,qz));                                    //定义旋转向量
        Twr.pretranslate(Vector3d(tx,ty,tz));                                        //定义平移向量
        poses.push_back(Twr);
    }
    cout<<"real total "<<poses.size()<<" pose entries"<<endl;

    DrawTrajectory(poses);
    return 0;
}

void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses)        //实例化
{
    pangolin::CreateWindowAndBind("Trajectory Viewer", 1024,768 );                         //标题和窗口大小
    glEnable(GL_DEPTH_TEST);                                                               //这三句直接写 这句是启用深度检测,下一句是启用混合
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC0_ALPHA,GL_ONE_MINUS_SRC_ALPHA);                                     //表示颜色的混合方式

    pangolin::OpenGlRenderState s_cam(
        pangolin::ProjectionMatrix(1024,768,500,500,512,389,0.1,1000),                     //投影矩阵(前四个是尺寸,然后是near和far的边界值)
        pangolin::ModelViewLookAt(0,-0.1,-1.8,0,0,0,0.0,-1.0,0.0)                          //初始化视角(三个一组分别是观测方向、目标位置、观测位置)
    );
    pangolin::View &d_cam =pangolin::CreateDisplay()                                       //定义地图面板
    .SetBounds(0.0,1.0,0.0,1.0,-1024.0f/768.0f)                                            //末尾两个双精度数表示长宽比
    .SetHandler(new pangolin::Handler3D(s_cam));

    while (pangolin::ShouldQuit()==false)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);                                //清除画面
        d_cam.Activate(s_cam);                                                             //激活相机s
        glClearColor(1.0f,1.0f,1.0f,1.0f);                                                 //opencv类似设定颜色和线宽
        glLineWidth(2);
        for (size_t i = 0; i < poses.size(); i++)
        {
            Vector3d Ow = poses[i].translation();                                          //平移向量

            Vector3d Xw = poses[i]*(0.1*Vector3d(1,0,0));                                  //旋转向量
            Vector3d Yw = poses[i]*(0.1*Vector3d(0,1,0));
            Vector3d Zw = poses[i]*(0.1*Vector3d(0,0,1));

            glBegin(GL_LINES);                                                             //给各个轴分配不同的颜色
            glColor3f(1.0,0.0,0.0);
            glVertex3d(Ow[0],Ow[1],Ow[2]);
            glVertex3d(Xw[0],Xw[1],Xw[2]);
            glColor3f(0.0,1.0,0.0);
            glVertex3d(Ow[0],Ow[1],Ow[2]);
            glVertex3d(Yw[0],Yw[1],Yw[2]);
            glColor3f(0.0,0.0,1.0);
            glVertex3d(Ow[0],Ow[1],Ow[2]);
            glVertex3d(Zw[0],Zw[1],Zw[2]);
            glEnd();

        }
        
        for (size_t i = 0; i < poses.size(); i++)                                          //画线
        {
            glColor3f(0.0,0.0,0.0);
            glBegin(GL_LINES);
            auto p1 = poses[i],p2=poses[i+1];
            glVertex3d(p1.translation()[0],p1.translation()[1],p1.translation()[2]);
            glVertex3d(p2.translation()[0],p2.translation()[1],p2.translation()[2]);
            glEnd();
        }

        pangolin::FinishFrame();
        usleep(5000);
    }
}

以下为三维集合体可视化部分

#include <iostream>
#include <iomanip>

using namespace std;

#include <Eigen/Core>
#include <Eigen/Geometry>

using namespace Eigen;

#include <pangolin/pangolin.h>

struct RotationMatrix {
  Matrix3d matrix = Matrix3d::Identity();
};

ostream &operator<<(ostream &out, const RotationMatrix &r)                    //重载运算符
{
  out.setf(ios::fixed);
  Matrix3d matrix = r.matrix;
  out << '=';
  out << "[" << setprecision(2) << matrix(0, 0) << "," << matrix(0, 1) << "," << matrix(0, 2) << "],"
      << "[" << matrix(1, 0) << "," << matrix(1, 1) << "," << matrix(1, 2) << "],"
      << "[" << matrix(2, 0) << "," << matrix(2, 1) << "," << matrix(2, 2) << "]";
  return out;
}

istream &operator>>(istream &in, RotationMatrix &r)                           //重载运算符
{
  return in;
}

struct TranslationVector 
{
  Vector3d trans = Vector3d(0, 0, 0);
};

ostream &operator<<(ostream &out, const TranslationVector &t) 
{
  out << "=[" << t.trans(0) << ',' << t.trans(1) << ',' << t.trans(2) << "]";
  return out;
}

istream &operator>>(istream &in, TranslationVector &t) 
{
  return in;
}

struct QuaternionDraw {
  Quaterniond q;
};

ostream &operator<<(ostream &out, const QuaternionDraw quat) 
{
  auto c = quat.q.coeffs();
  out << "=[" << c[0] << "," << c[1] << "," << c[2] << "," << c[3] << "]";
  return out;
}

istream &operator>>(istream &in, const QuaternionDraw quat) 
{
  return in;
}

int main(int argc, char **argv) 
{
  pangolin::CreateWindowAndBind("visualize geometry", 1000, 600);
  glEnable(GL_DEPTH_TEST);
  pangolin::OpenGlRenderState s_cam(
    pangolin::ProjectionMatrix(1000, 600, 420, 420, 500, 300, 0.1, 1000),
    pangolin::ModelViewLookAt(3, 3, 3, 0, 0, 0, pangolin::AxisY)
  );

  const int UI_WIDTH = 500;

  pangolin::View &d_cam = pangolin::CreateDisplay().
    SetBounds(0.0, 1.0, pangolin::Attach::Pix(UI_WIDTH), 1.0, -1000.0f / 600.0f).
    SetHandler(new pangolin::Handler3D(s_cam));

                                    
  pangolin::Var<RotationMatrix> rotation_matrix("ui.R", RotationMatrix());                 //绘制左侧提示栏
  pangolin::Var<TranslationVector> translation_vector("ui.t", TranslationVector());
  pangolin::Var<TranslationVector> euler_angles("ui.rpy", TranslationVector());
  pangolin::Var<QuaternionDraw> quaternion("ui.q", QuaternionDraw());
  pangolin::CreatePanel("ui").SetBounds(0.0, 1.0, 0.0, pangolin::Attach::Pix(UI_WIDTH));

  while (!pangolin::ShouldQuit()) 
  {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    d_cam.Activate(s_cam);

    pangolin::OpenGlMatrix matrix = s_cam.GetModelViewMatrix();
    Matrix<double, 4, 4> m = matrix;

    RotationMatrix R;
    for (int i = 0; i < 3; i++)
      for (int j = 0; j < 3; j++)
        R.matrix(i, j) = m(j, i);
    rotation_matrix = R;

    TranslationVector t;
    t.trans = Vector3d(m(0, 3), m(1, 3), m(2, 3));
    t.trans = -R.matrix * t.trans;
    translation_vector = t;

    TranslationVector euler;
    euler.trans = R.matrix.eulerAngles(2, 1, 0);
    euler_angles = euler;

    QuaternionDraw quat;
    quat.q = Quaterniond(R.matrix);
    quaternion = quat;

    glColor3f(1.0, 1.0, 1.0);

    pangolin::glDrawColouredCube();                   //绘制直线
    // draw the original axis
    glLineWidth(3);
    glColor3f(0.8f, 0.f, 0.f);
    glBegin(GL_LINES);
    glVertex3f(0, 0, 0);
    glVertex3f(10, 0, 0);
    glColor3f(0.f, 0.8f, 0.f);
    glVertex3f(0, 0, 0);
    glVertex3f(0, 10, 0);
    glColor3f(0.2f, 0.2f, 1.f);
    glVertex3f(0, 0, 0);
    glVertex3f(0, 0, 10);
    glEnd();

    pangolin::FinishFrame();
  }
}

自学slam确实挺麻烦的,继续学。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

slam学习笔记 的相关文章

  • 链表的建立、赋值、输出、查找、增、删

    include lt stdio h gt include lt string h gt include lt math h gt include lt stdlib h gt typedef struct node 定义结构体 int n
  • 蓝桥杯-串口

    本文通过电脑串口发送文本模式和HEX模式进行介绍串口的简单使用 xff01 注意事项 xff1a 1 本节通过定时器2的串口1 进行串口控制 2 串口如果开启了 编程完成后自动打开串口会导致第一次发送无法看到 xff08 HEX模式 xff
  • GSV2008

    GSV2008 是HDMI2 0 四进二出矩阵 xff0c 自持HDCP2 2 xff0c 支持DOWN SCALER 四个HDMI输入 xff0c 2个HDMI输出 xff0c 自动EQ 应用 xff1a 1 xff0c 功放 ARC C
  • 漏洞挖掘-从任意文件读取漏洞到获取账户利用

    开篇 大家好 xff0c 我是承影战队的v1ct0ry xff0c 这次我为大家分享一次比较有趣的漏洞挖掘经历 这次挖掘过程是以灰盒挖掘为主要思想进行展开 xff0c 不熟悉的读者可以阅读上篇文章熟悉一下 一 任意文件读取 开局我们通过扫描
  • curl命令行工具

    转载 curl 命令行工具的使用及命令参数说明 curl的使用 1 1 URL访问 1 2 表单提交 1 3 其它HTTP请求方法 1 4 文件上传 1 5 HTTPS支持 1 6 添加请求头 1 7 Cookie支持curl语法及选项cu
  • Ubuntu20.4安装ROS系统教程(自用)

    1 Ubuntu各个版本系统对应的ROS版本 1 2Ubuntu16 04与ROS kinetic的安装 1 2 1Ubuntu16 04配置 1 2 2安装ROS kinetic版 1 3Ubuntu18 04和ROS melodic的安
  • UART 空闲中断+DMA接收流程

    在项目中利用UART空闲中断接收外部信号 xff0c 利用DMA接收 xff0c 实现外部到内存的传输 通过分析其它文章的代码 xff0c 大概如下 xff1a span class token comment 配置 DMA Stream
  • 5分钟带你从数据类型了解Java相比C/C++有什么优势

    数据类型是一门语言的血肉 xff0c 通过这5分钟的浏览 xff0c 只学过C C 43 43 的小伙伴会初步了解Java的一些特性 xff0c 学过一点Java的朋友在读完这篇文章后也一定会对Java的语法规范有更深刻的了解 Java数据
  • 备赛电赛学习硬件篇(一):电机部分

    目录 一 电机选型 二 电机的正反转 xff0c 刹车 一 电机选型 1 电机类型 无刷电机较贵 xff0c 但是静音且损耗小 xff0c 由于霍尔元件的特殊性 xff08 不带霍尔需要转速高的时候才可以利用反电动势准确确定转子的位置 xf
  • 【总线】一文看懂RS232和RS485通信总线

    目录 RS232概述 RS232特性 RS485 概述 RS485 特性 RS232 和 RS485 的区别 区别总结 RS232概述 RS 232接口符合电子工业联盟 xff08 EIA xff09 建立的串行数据通信接口标准 原始编号是
  • 【C++学习笔记】vector构造函数

    文章目录 1 vector构造函数说明 xff1a 2 实战 xff1a 2 1 vector构造函数代码示例2 2 输出 3 参考资料 1 vector构造函数说明 xff1a span class token keyword templ
  • 请求报文/相应报文

    一 请求报文分为4个部分 请求行 请求头 请求空行 请求体 1 1 请求行 主要是3个部分 GET 请求方式 1 2 请求地址 所带的参数 demo demo php userName 61 E6 9D 8E E5 9B 9B amp us
  • python+requests——高级用法——auth认证

  • C语言char指针的使用

    在c语言中 xff0c char指针不仅能指向char变量 xff0c 还能指向常量字符串 xff0c 同时也能指向一个char数组的 想要访问单个字符 xff0c 就要通过 来进行解引用 xff0c 若是要访问整个数组或字符串的话 xff
  • HTTP协议的请求格式解析

    HTTP协议是一个使用较多的应用层协议 xff0c 它是一个请求 响应式的一个协议 xff0c 就是我客户端给你发一个请求 xff0c 你客户端需要返回给我一样响应 首先我们来看一下HTTP协议的请求格式 HTTP请求格式 xff1a HT
  • 运行Gazebo+moveit+Rviz,报错,提示无控制器

    在rviz里规划成功后 xff0c 执行显示failed rviz里能规划 xff0c 但是Gazebo里动不了 moveit报错如下 xff1a WARN 1679466487 132361192 26 763000000 Waiting
  • 基于UDP协议搭建的简单客户端与服务器(UDP协议)

    UDP协议 UDP协议的介绍1 UDP的缺点 基于UDP实现的回显服务器基于UDP实现的客户端 UDP协议的介绍 UDP协议特点 xff1a 1 无连接 2 面向数据报 3 不可靠传输 4 全双工 16位源端口号 目的端口号 xff1a 表
  • C++之AStar寻路算法

    仅以记录 有一种算法 名为AStar 它的作用是求图中两点之间的最短路径 沉迷 该算法的我 自己编写了一个版本 注释虽少 但求传神 代码虽 恶心 但求理解 include lt iostream gt include lt vector g
  • 使用livox_viewer2对激光雷达livox_mid360进行调试

    准备 系统 windows10 硬件 xff1a livox mid360 软件 xff1a livox viewer2 测试 连接号激光雷达设备 xff0c 电脑ip相关设置和livox avia一样 livox系列激光雷达ip设置都是一
  • 听说你还不会制作“GIF动图”,手把手包教会,这不就来了吗

    近期 xff0c 看了好多写的博客 xff0c xff08 不管是前端HTML的还是后端Java的 xff0c 前端制作的3D部分的效果图需要展示动图 xff09 发现有点还存在想使用动图 xff0c 但是不会制作 xff0c 又或者是制作

随机推荐

  • HTML+js实现贪吃蛇小游戏(内含完整代码)

    案例分析 看图拆解游戏 首先我们根据图片上的内容把这个游戏拆解成几个部分去单独看 xff1a 最外面的大盒子包裹着内容加边框限制蛇的活动范围 xff0c 整个范围可以看成由许多小方格排列构成的 xff0c 例如这样子的 xff1a xff1
  • 【华为Hilink SDK Linux系统开发】第三章:华为hilink SDK Linux系统网关适配

    mark xff1a https blog csdn net qq 24550925 article details 107282773 关注嘉友创科技公众号 声明 xff1a 文章只做技术交流 xff0c 没有其他任何用途 xff0c 侵
  • 快速去除GIF动图的背景(让背景变透明),保姆级教程

    很多小伙伴在看到好看的动图效果时 xff0c 想用在自己的页面上 xff0c 可是常常会碰到一些动图背景颜色不符合自己的需求 xff0c 所以会产生修改动图背景的想法 xff0c 但是GIF动图终究是GIF动图 xff0c 不像静态图片那样
  • Vue在HTML中如何使用

    x1f440 Vue是什么 一套用于构建用户界面的渐进式JavaScript框架 构建用户界面 xff1a 数据变成界面渐进式 xff1a Vue可以自底向上逐层的应用 x1f440 Vue如何使用 一 引入vue js lt script
  • 简单记录一下怎么看package.json文件

    首先每个vue工程文件从仓库克隆代码下来的时候 xff0c 一般都会包含这个文件 xff0c 这个文件非常重要 xff0c package json包含了关于项目重要信息 xff0c 如下图所示 其中包含了name version desc
  • 项目中常用到的前端vue根据后端接口返回文件地址实现在线预览和下载功能

    简简单单的记录一下项目中做过的东西 项目中时常会有要求查看附件 xff0c 附件的下载的要求 xff0c 在这里简单记录一下前端vue根据后端接口返回文件地址实现在线预览和下载功能 x1f440 文件在线预览 目前我这里使用的是点击a链接跳
  • 记录面试问题

    以下问题不分先后 xff0c 按照印象深浅排序 xff0c 可能一次记录不完成 xff0c 后面想起来会及时补充 xff0c 如有不对 xff0c 恳请各位围观大佬多多指教 x1f64f 印象最深的是一道很简单很简单的题目 xff0c 我结
  • C++中“.“,“->“,“:“和“::“的区别

    在 C 43 43 中 xff0c 34 34 xff0c 34 gt 34 xff0c 34 34 和 34 34 都是运算符 xff0c 它们的作用是明显不同的 xff0c 但是初学者很容易被其迷惑 1 34 34 是成员访问运算符 x
  • ubuntu系统中忘记root密码的解决办法

    1 启动ubuntu按shift进入grub菜单 xff1b 2 选择recovery mode进入Recovery Menu界面 xff0c 选择root Drop to root shell prompt 3 修改root密码操作 xf
  • C++语言实现哈希表中的线性探测法和平方探测法

    哈希表 xff08 Hash表 xff09 xff0c 也称为散列表 xff0c 是一种数据结构 xff0c 通过使用哈希函数将键映射到数组的特定位置来实现高效的查找 插入和删除操作 哈希函数将键转换为一个整数 xff0c 这个整数对应数组
  • C++实现的二叉树前序遍历函数

    include lt iostream gt using namespace std struct TreeNode int val TreeNode left TreeNode right TreeNode int x val x lef
  • c语言和c++实现层序遍历

    层序遍历是一种二叉树的遍历方式 xff0c 也称为广度优先遍历 xff0c 它的遍历顺序是 xff1a 从上到下 xff0c 从左到右 xff0c 一层一层地遍历整棵树 在 C 语言中 xff0c 我们可以使用队列来实现层序遍历 具体实现步
  • C语言获取wifi状态

    mark https blog csdn net dongyoubin article details 122134198 int getWirelessStatus char ath char ssid char ipAddr
  • 最全Visual Studio版本号对应表VisualStudioVersion

    名字 版本号 简称 全称 msvc70 VC7 0 VS2002 Microsoft Visual Studio 2002 msvc71 VC7 1 VS2003 Microsoft Visual Studio 2003 msvc80 VC
  • 二叉树静态实现的示例代码

    使用指针对于初学者容易出现很多困惑 下面是一个完整的二叉树静态实现的示例代码 xff0c 包括初始化 插入节点 各种遍历方法以及一些辅助函数 include lt stdio h gt include lt stdlib h gt defi
  • 广度优先搜索(BFS)算法实现二叉树层序遍历的 C++ 代码

    include lt iostream gt 输入输出流 include lt vector gt 向量容器 include lt queue gt 队列容器 using namespace std 命名空间 定义二叉树节点结构体 stru
  • PAT 1005 Spell It Right

    Given a non negative integer N your task is to compute the sum of all the digits of N and output every digit of the sum
  • 在PC的Ubuntu虚拟机上完成一个TCP 服务器,在设备上实现一个TCP客户端

    要求 在虚拟机上实现一个服务器 xff0c 设备终端上实现一个客户端设备客户端每隔 1 秒 检测一次网卡eth2 1 xff08 WAN口网卡 xff09 的信息 xff08 使用popen调用ifconfig xff09 然后将RX和TX
  • TCP发送数据、接受数据及TCP通信程序练习

    目录 一 TCP发送数据 二 TCP接收数据 三 TCP通信程序练习 一 TCP发送数据 Java中的TCP通信 xff1a Java对于基于TCP协议的网络提供了良好的封装 xff0c 使用Socket对象来代表两端的通信端口 xff0c
  • slam学习笔记

    ubuntu20 04 使用vs code编写 现放cmake文件 xff08 记得链接库文件和配置C 43 43 版本 xff09 cmake minimum required VERSION 2 8 project learingMat