LearnOpenGL-入门-8.坐标系统
本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正
我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject
LearnOpenGL中文官网:https://learnopengl-cn.github.io/
文章目录
- 坐标系统
- 概述
- 局部空间
- 世界空间
- 观察空间
- 裁剪空间
- 正交投影
- 透视投影
- 把他们组合到一起
- 进入3D
- 例子1
- 例子2:更加3D
- 例子3:箱子派对
坐标系统
-
标准化设备坐标介绍
-
每个顶点的x,y,z坐标都在**-1.0到1.0**之间
-
OpenGL希望在每次顶点着色器运行后,我们可见的所有顶点都为标准化设备坐标
-
我们通常会自己设定一个坐标的范围,之后再在顶点着色器中将这些坐标变换为标准化设备坐标
-
将标准化设备坐标传入光栅器(Rasterizer),将它们变换为屏幕上的二维坐标或像素。
-
-
多个坐标系统
-
为什么存在
将坐标变换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分步进行的,所以物体的顶点在最终转化为屏幕坐标之前还会被变换到多个坐标系统
-
多个坐标系统的优点优点
在这些特定的坐标系统中,一些操作或运算更加方便和容易
-
概述
- 局部坐标是对象相对于局部原点的坐标,也是物体起始的坐标
- 局部坐标通过Model矩阵变换为世界空间坐标,这些坐标相对于世界的全局原点,它们会和其它物体一起相对于世界的原点进行摆放。
- 观察空间坐标,通过view矩阵将世界空间转换到观察空间,使得每个坐标都是从摄像机或者说观察者的角度进行观察的。
- 裁剪坐标,通过投影矩阵从观察空间到裁剪空间,裁剪坐标会被处理(透视除法)至-1.0到1.0的范围内,并判断哪些顶点将会出现在屏幕上。
- 视口变换将-1.0到1.0范围的裁剪坐标(标准化设备坐标)变换到由glViewport函数所定义的坐标范围内。
局部空间
-
简介
局部空间是指物体所在的坐标空间
世界空间
-
简介
是指顶点相对于(游戏)世界的坐标
-
如何从局部到世界坐标
该变换是由模型矩阵(Model Matrix)实现的。
观察空间
-
简介
摄像机的视角所观察到的空间,是由观察矩阵(Model Matrix)从世界到观察坐标。
-
view(观察)矩阵
由一系列的位移和旋转的组合来完成,平移/旋转场景从而使得特定的对象被变换到摄像机的前方。
这些组合在一起的变换通常存储在一个观察矩阵(View Matrix)里
裁剪空间
-
简介
- OpenGL自动执行
- 范围内的保留,范围外的裁掉
- 当裁剪后剩下的可见的片段就是裁剪空间
-
如何进入裁剪空间
由投影矩阵将观察空间变换到裁剪空间
-
投影矩阵分为
- 正交投影
- 透视投影
-
透视除法
-
什么时候执行
一旦所有顶点被变换到裁剪空间,OpenGL自动会透视除法(在每一个顶点着色器运行的最后被自动执行)
-
它如何做
将位置向量的x,y,z分量分别除以向量的齐次w分量
-
结果
透视除法执行后才将裁剪坐标系变换到标准化设备坐标系
-
-
小结工作流程(自己捋的,很大概率有误)
设置-1000到1000范围,投影矩阵会将在这个范围内的坐标从观察空间变换到裁剪空间,然后OpenGL自动执行透视除法,转换为标准化设备坐标的范围(-1.0, 1.0)。
所有的坐标先转换为(-1, 1)之间,然后不在-1.0到1.0的范围,会被裁剪掉(OpenGL自动执行裁剪)。
-
在标准化设备坐标系之后
执行第一张图所说的视口变换:
最终的坐标(标准化设备坐标系)将会被映射到屏幕空间中(使用glViewport中的设定),并被变换成片段。
即:视口变换将标准化设备坐标系到屏幕坐标
正交投影
-
图示
-
glm创建
glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
-
前两个参数指定了平截头体的左右坐标
-
第三和第四参数指定了平截头体的底部和顶部
通过这四个参数我们定义了近平面和远平面的大小
-
第五和第六个参数则定义了近平面和远平面的距离
-
-
缺点
这个投影没有将透视(Perspective)考虑进去,所有的物体仿佛都保持原有大小。
因为这个投影不改变每个向量的w分量,都保持1,透视除法是用x,y,z除以w分量,w=1,自然不会变。
透视投影
-
图示
-
简介
近大远小
-
透视投影矩阵如何工作
-
这个投影矩阵将给定的平截头体范围映射到裁剪空间
-
除此之外还修改了每个顶点坐标的w值
-
从而使得离观察者越远的顶点坐标w分量越大。
-
透视除法所做
将位置向量的x,y,z分量分别除以向量的齐次w分量,因为远的顶点坐标w分量大,所以距离观察者越远顶点坐标就会越小
-
-
什么时候执行透视除法
- 上面有讲:由projection投影矩阵变换到裁剪空间后
- OpenGL要求所有可见的坐标都落在-1.0到1.0范围内,作为顶点着色器最后的输出。因此,一旦坐标在裁剪空间内之后,就会在裁剪空间坐标上执行透视除法,透视除法执行后便是标准化设备坐标(-1.0,1.0)范围。
-
-
glm创建
glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f);
-
第一个参数定义了fov的值,它表示的是视野
-
第二个参数设置了宽高比,由视口的宽除以高所得
-
第三和第四个参数设置了平截头体的近和远平面
-
说明第三个参数
当 near 值设置太大时(如10.0f),OpenGL会将靠近摄像机的坐标**(在0.0f和10.0f之间)**都裁剪掉
-
-
-
透视投影与正交投影对比
把他们组合到一起
-
注意顺序
-
写代码顺序
v = projection * view * model * local
-
读顺序
需从右往左阅读矩阵
-
-
再重复了一次裁剪空间这点的内容
OpenGL将会自动进行透视除法和裁剪操作
重要的顺序
- 顶点着色器的输出要求所有的顶点都在裁剪空间内,这正是我们刚才使用变换矩阵所做的。
- OpenGL然后对裁剪坐标自动执行透视除法从而将它们变换到标准化设备坐标
- 视口变换:OpenGL会使用glViewPort内部的参数来将标准化设备坐标映射到屏幕坐标
进入3D
- 观察矩阵
- 将摄像机向后移动,和将整个场景向前移动是一样的。
- 这正是观察矩阵所做的,我们以相反于摄像机移动的方向移动整个场景
- 因为我们想要往后移动,所以场景需要沿着z轴负方向平移来实现,它会给我们一种我们在往后移动的感觉。(opengl右手坐标系)
例子1
-
代码
glsl
顶点着色器
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTexCoord; out vec2 TexCoord; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() {// 注意乘法要从右向左读gl_Position = projection * view * model * vec4(aPos, 1.0);TexCoord = aTexCoord; }
-
在顶点着色器上进行坐标系转换,从局部空间到裁剪空间
-
代码顺序是
project*view*model*local
-
解读顺序是
相反的需从右往左读:将顶点local经过model矩阵到世界空间,再经过view矩阵到观察空间,再经过project到裁剪空间。
-
-
再次重复
到裁剪空间后,经过透视除法到标准化设备坐标系,再经过视口变换到屏幕坐标,这两个是opengl自动执行的
片段着色器
#version 330 core out vec4 FragColor; in vec2 TexCoord; uniform sampler2D texture1; uniform sampler2D texture2; void main() {FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); }
cpp
Shader ourShader("assest/shader/1入门/1.8.transform.vs", "assest/shader/1入门/1.8.transform.fs");// 顶点数据 float vertices[] = {// positions // texture coords0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left }; unsigned int indices[] = {0, 1, 3, // first triangle1, 2, 3 // second triangle }; // 顶点数组 unsigned int VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1);// 加载纹理 unsigned int texture1, texture2; // texture 1 glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis. unsigned char* data = stbi_load(FileSystem::getPath("assest/textures/container.jpg").c_str(), &width, &height, &nrChannels, 0); if (data) {glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D); } else {std::cout << "Failed to load texture" << std::endl; } stbi_image_free(data); // texture 2 和texture1一样 ....... // 告诉OpenGL两个采样器对应哪个纹理单元 ourShader.use(); ourShader.setInt("texture1", 0); ourShader.setInt("texture2", 1);// render loop while (!glfwWindowShouldClose(window)) {// inputprocessInput(window);// renderglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // also clear the depth buffer now!// bind textures on corresponding texture unitsglActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture1);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture2);// 此节重点在这///// 构造矩阵变换glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix firstglm::mat4 view = glm::mat4(1.0f);glm::mat4 projection = glm::mat4(1.0f);model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));// 注意,我们将矩阵向我们要进行移动场景的反方向移动。view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));// 透视投影矩阵projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);// 设置uniformourShader.use();unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model");unsigned int viewLoc = glGetUniformLocation(ourShader.ID, "view");// 3种不同的方式发送数据给ShaderglUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);ourShader.setMat4("projection", projection);// 渲染boxglBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
-
重点代码
// 将物体绕着x轴旋转-55.0度 model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f)); // 注意,我们将矩阵向我们要进行移动场景的反方向移动。 view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); // 透视投影矩阵 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
-
-
效果
- 经过model矩阵实现的旋转+透视投影可看到的效果
- 稍微向后倾斜至地板方向。
- 离我们有一些距离。
- 有透视效果(顶点越远,变得越小)。
- 经过model矩阵实现的旋转+透视投影可看到的效果
例子2:更加3D
-
代码改变
与上一个例子相比的改变
- 改变了顶点数据,顶点数据是一个箱子的36个顶点
- 去除了索引缓冲与索引绘制
- model矩阵不再是绕着x旋转-55度,而是绕着y轴旋转度数time(运行时间作为度数)
-
代码
float vertices[] = {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,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, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 1.0f,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,-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, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,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, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 1.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.0f, 1.0f, 0.0f));
-
效果
效果奇怪,奇怪的地方在于没有进行深度测试,导致后渲染的片段覆盖前渲染的片段,从而箱子的背面覆盖前面。
-
如何修复
-
由于OpenGL默认不进行深度测试,需要设置开启深度测试,开启后opengl自动完成
只需在渲染代码前中加一句
glEnable(GL_DEPTH_TEST);
-
深度测试工作原理
- OpenGL存储它的所有深度信息于一个Z缓冲,又称深度缓冲
- GLFW会自动为你生成这样一个缓冲(就像它也有一个颜色缓冲来存储输出图像的颜色)
- 深度值存储在每个片段里面(作为片段的z值),当片段想要输出它的颜色时,OpenGL会将它的深度值和z缓冲进行比较,如果当前的片段在其它片段之后,它将会被丢弃,否则将会覆盖
-
-
修复效果
例子3:箱子派对
-
实现思路
-
定义10个箱子的出生点
-
循环10次
每次model为单位矩阵,再将model矩阵进行平移到出生点,再可以加上旋转效果(代码顺序)
-
-
代码
float vertices[] = {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,...... }; // 出生点-初始位置 glm::vec3 cubePositions[] = {glm::vec3(0.0f, 0.0f, 0.0f),glm::vec3(2.0f, 5.0f, -15.0f),glm::vec3(-1.5f, -2.2f, -2.5f),glm::vec3(-3.8f, -2.0f, -12.3f),glm::vec3(2.4f, -0.4f, -3.5f),glm::vec3(-1.7f, 3.0f, -7.5f),glm::vec3(1.3f, -2.0f, -2.5f),glm::vec3(1.5f, 2.0f, -2.5f),glm::vec3(1.5f, 0.2f, -1.5f),glm::vec3(-1.3f, 1.0f, -1.5f) }; // render box glBindVertexArray(VAO); for (unsigned int i = 0; i < 10; i++) {glm::mat4 model = glm::mat4(1.0f);model = glm::translate(model, cubePositions[i]); // 先平移float angle = 20.0f * i * (float)glfwGetTime();model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));// 再旋转ourShader.setMat4("model", model);glDrawArrays(GL_TRIANGLES, 0, 36); }
注意model矩阵,写代码的顺序是先平移再旋转,但是解读的话是先旋转再平移(请看本专栏中变换-矩阵的组合)。
-
效果
相关文章:
LearnOpenGL-入门-8.坐标系统
本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject LearnOpenGL中文官网:https://learnopengl-cn.github.io/ 文章目录坐标系统概述局部空间世界空…...
windows10使用wsl2安装docker
配环境很麻烦,想利用docker的镜像环境跑一下代码整个安装过程的原理是:windows使用docker,必须先安装一个linux虚拟机,才可运行docker,而采用wsl2安装虚拟机是目前最好的方法第一步 windows安装wsl2控制面板->程序-…...
Javascript的API基本内容(六)
一、正则表达式 1.定义规则 const reg /表达式/ 其中/ /是正则表达式字面量正则表达式也是对象 2.使用正则 test()方法 用来查看正则表达式与指定的字符串是否匹配如果正则表达式与指定的字符串匹配 ,返回true,否则false 3.元字符 比如࿰…...
电压放大器和电流放大器的区别是什么意思
在日常电子实验测试中,很多电子工程师都会使用到电压放大器和电流放大器,但是很多新手工程师却无法区分两者的区别,下面就让安泰电子来为我们讲解电压放大器和电流放大器的区别是什么意思。 一、电压放大器介绍: 电压放大器是一种…...
cast提前!最简单有效的神经网络优化方法,没有之一!
做优化有时候真的很头疼,绞尽脑汁的想怎么做算法等价,怎么把神经网络各层指令流水起来,在确保整网精度的同时,又有高性能。 但有时做了半天,却发现流水根本就流不起来,总是莫名其妙地被卡住。 真的是一顿…...
LeetCode刷题——动态规划(C/C++)
文章目录[简单]买股票的最佳时机[简单]爬楼梯[中等]最长递增子序列[中等]最大连续子数组和[简单]买股票的最佳时机 原题链接 题解 min:今天之前买股的最低价 res:最大利润 每一天比较今天和往前的最低价差值能否比最大利润还大 class Solution { publ…...
车载智能终端TBOX
YD886 终端设备是基于GSM/WCDMA全网通讯方式的GPS定位移动终端,车载设备具有强大的车辆监控管理、CAN总线数据采集等功能,可以满足不同用户的需求,同时具备汽车行驶记录功能扩展应用。具体功能请以终端实际情况为准! 一、移动管家 车载智能终…...
技术分担产品之忧(上):挑选有业务专家潜力的人
你好,我是王植萌,去哪儿网的高级技术总监、TC主席。从2014年起,担任一个部门的技术负责人,有8年技术总监经验、5年TC主席的经验。这节课我会从去哪儿网产研融合的经验出发,和你聊一聊怎么让技术分担产品之忧。 技术分…...
UVa 12569 Planning mobile robot on Tree (EASY Version) 树上机器人规划(简单版) BFS 二进制
题目链接:Planning mobile robot on Tree (EASY Version) 题目描述: 给定一棵树,树上有一个位置存在一个机器人,其他mmm个位置存在石头,保证初始状态一个结点最多一个物体(一个石头或者一个机器人或者为空…...
intel的集成显卡(intel(r) uhd graphics) 配置stable diffusion
由于很多商务本没有独立显卡,只有Intel的集成显卡,在配置安装stable diffusion 时候需要特殊对待,参考不少帖子,各取部分现稍加整合。整体思路分两个部分:第一步是先配置环境,主要是安装Anaconda Pytorch&…...
【数据库的基础知识(2)】
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
Docker部署实战
文章目录Docker部署应用准备制作容器镜像启动容器上传镜像docker exec数据卷(Volume)声明原理实践Docker部署 应用准备 这一次,我们来用 Docker 部署一个用 Python 编写的 Web 应用。这个应用的代码部分(app.py)非常…...
RestTemplate 相关使用
RestTemplate介绍简单接口调用(getForObject)添加 Header 和 Cookie(exchange)介绍 在项目中,当我们需要远程调用一个 HTTP 接口时,我们经常会用到 RestTemplate 这个类。这个类是 Spring 框架提供的一个工…...
新手小白亚马逊注册最全教程在此
自从龙哥出了Walmart注册教程后,立刻看到私信有兄弟问这个亚马逊的注册。亚马逊是跨境电商的鼻祖,资源和流量是无容置疑的。作为一个重产品,轻店铺的平台,是比较看中客户体验的,要求卖家要有好的资源。而且亚马逊有强大…...
二分查找重复情况 找最左边或最右边的位置下标
目录二分找最左边二分找最右边综合应用(剑指offer)二分找最左边 核心思想: 先mid (lr)/2每次向左取整; 然后命中target的时候,右边界逼近到mid; 因为每次mid向左取整,mid命中target时l代替mid位置,则循环迭代最后会卡出重复数字最左侧的位置…...
智慧扫码点餐系统源码
智慧餐厅扫码点餐小程序系统源码 1. 开发语言:JAVA 2. 数据库:MySQL 3. 原生小程序 4. Saas 模式 5. 带调试部署视频 6、总后台管理端商家端门店端小程序用户端 智慧扫码点餐系统支持多店铺运营,单店铺运营以及连锁店铺运营。系统功能支…...
分布式环境并发场景下,如何操作抢红包(或者减少库存)
文章目录简介思考lua 对 redis 的原子操作其他解决方式一些问题简介 在分布式场景高并发环境中,无论是抢红包还是减库存,其实本质上都是如何处理高并发中共享资源的问题,保证高并发资源分配的安全性 相互学习,如有错误还请指正&…...
明星的孩子也在做的感统训练,真的有用吗?
林志颖曾经在社交网站晒过带他儿子“模拟过山车”的视频。孩子大脑前庭受到适当的刺激,可以有效地锻炼前庭平衡感。 除此之外,还能看见地上的感统教具:过河石、平衡桥,看来明星老爸在陪孩子做感统游戏的日常一点也不含糊。 其实在…...
守护进程与TCP通讯
目录 一.守护进程 1.1进程组与会画 1.2守护进程 二.创建守护进程 setsid函数: 三. TCP通讯流程 3.1三次握手: 3.2 数据传输的过程 3.3四次挥手 一.守护进程 1.1进程组与会画 进程组:进程组由一个进程或者多个进程组成,每…...
在线文本翻译能力新增14个直译模型,打造以中文为轴心语言的翻译系统
经济全球化的今天,人们在工作和生活中经常会与外语打交道。相较传播性较广的英语而言,其他语种的识别和阅读对大多数人来说是一件难事,此时就需要借助语言翻译软件来帮助理解。 华为 HMS Core 机器学习服务(ML Kit)翻…...
CVE-2022-42889 Apache Commons Text 漏洞
0x00 前言 所幸遇到,就简单看看,其中没有啥比较难的地方,仅做记录。10月13日的漏洞。 cve链接可以看下面这个: https://cve.mitre.org/cgi-bin/cvename.cgi?nameCVE-2022-42889 git地址: https://github.com/apache…...
20- widedeep及函数式构建模型 (TensorFlow系列) (深度学习)
知识要点 wide&deep: 模型构建中, 卷积后数据和原始数据结合进行输出.fetch_california_housing:加利福尼亚的房价数据,总计20640个样本,每个样本8个属性表示,以及房价作为target,所有属性值均为number࿰…...
大家一起做测试的,凭什么你现在拿20k,我却还只有10k?...
最近我发现一个神奇的事情,我一个97年的朋友居然已经当上了测试项目组长,据我所知他去年还是在深圳的一家创业公司做苦逼的测试狗,短短8个月,到底发生了什么? 于是我立刻私聊他八卦一番。 原来他所在的公司最近正在裁…...
>>数据管理:DAMA简介「考试和续期」
关于DAMA,这里就不再多做描述,可以参考以前写的一些简介或官方介绍。下面就考试再做一些详细介绍。 1 区别 CDGA:数据治理工程师(Certified Data Governance Associate),“DAMA中国”组织的数据治理方面的职业认证考试。 CDGP:数据治理专家(Certified Data Governa…...
React的生命周期详细讲解
什么是生命周期? 所谓的React生命周期,就是指组件从被创建出来,到被使用,最后被销毁的这么一个过程。而在这个过程中,React提供了我们会自动执行的不同的钩子函数,我们称之为生命周期函数。**组件的生命周期…...
蓝蓝算法二期工程day3,一万年太久,只争朝夕
思路: 最好想的是用hashmap,当然用c的话也可以用两个数组,一个数组用于存放字符串,自动对应ACSII码,一个将对应ACSII码的数字对应其下标,当然这也是用的映射的思想。 import java.util.*;public class Cac…...
程序代码的自动化生成方案设计
程序设计就能够适用这种代码自动化生成方法的前提是:PLC 程序代码具有高度重复性,执行的是相同数据处理或者逻辑判断,而相关变量组 是离 散 的,没 有规 律 可循 。以 I/O 变量和中间 变量的地 址 映 射 程序为例 ,程序代码为赋 值 语 句 ,高度重复;IO 变量和与 其 对应 的中间 …...
Go 稀疏数组学习与实现
仍然还是一个数组 基本介绍 一般就是指二维以上的数组 当一个数组中大部分元素是0 ,或者为同一个值的数组时,可以使用系数数组来保存该数组. 稀疏数组的处理方法: 记录数组一共有几行几列,有多少个不同的值把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程…...
MySQL 学习笔记(借鉴黑马程序员MySQL)
MySQL视频课链接 MySQL概述 数据库相关概念 数据库是存储数据的仓库,数据是有组织的进行存储(DataBase) 数据库管理系统是操纵和管理数据库的大型软件(DataBase Management System) SQL是操作关系型数据库的编程语…...
中级工程师职称申报到底需要参加答辩不?
获得中级工程师职称的方式有认定、评审、考试这几种形式。 甘建二老师先来简单说一下关于认定和考试这两种: 1.认定:中级职称认定一般是根据各地职称认定政策,如果你想走认定渠道,首先本人简历条件、业绩、奖项等非常优秀&#…...
工作室网站建设方案模板/网络推广是干什么的
author:skate time:2009-09-08 今天整体了解nagios的原理,画了几张图,方便以后查看 第二张 哪天把文本说明贴上来 -----须----...
网站优化有哪些/公司网站搭建
数据链路层(一)3.1 使用点对点信道的数据链路层3.1.1 数据链路层和帧数据发送模型数据链路层的信道类型数据链路层使用的信道主要有以下两种类型:点对点信道。这种信道使用一对一的点对点通信方式。广播信道。这种信道使用一对多的广播通信方式,因此过程…...
绵阳力嘉信息网站建设公司/如何在百度上发布自己的文章
引用:http://www.cnblogs.com/smallstone/archive/2010/04/29/1723838.html 1、进入mysql,创建一个新用户root,密码为root: 格式:grant 权限 on 数据库名.表名 to 用户登录主机 identified by "用户密码"; gr…...
徐州泰安抖音代运营/seo技术教程
说起来很搞笑,我在用 sublime 3 写排序算法的时候,准备用 nodejs 来运行,就用 sublime 3 提供的编译功能。但问题来了,我比较挫,写了个死循环,然后 sublime 3 也不给输出提示,我很疑惑的连续跑了…...
工作简历模板免费使用/佛山seo技术
这是一个系列,我们将其命名为android最佳实践,如果你还没有看之前的文章: Android最佳实践(一) android最佳实践(二) android最佳实践(三) android最佳实践(四…...
做网站一定要自己搭建服务器吗/域名服务器ip查询网站
caffe执行draw.py的错误汇总 发表于2017/5/11 17:18:43 89人阅读 caffe执行draw.py的错误汇总 安装完caffe后,使用caffe时,有时候需要调用draw.py来画整个神经网络拓扑图,不过github上最新版本运行draw.py会报错,具体如下 错误1&…...