OSG编程指南<十一>:OSG几何体操作及三维地形创建

news2024/11/28 12:52:11

1、简化几何体

  在 OSG 中,场景都是由基本的绘图基元构成的,基本的绘图基元构成简单的几何体,简单的几何体构成复杂的几何体,复杂的几何体最终构造成复杂的场景。当多个几何体组合时,可能
存在多种降低场景渲染效率的原因。在很多 3D 引擎中,都提供了对场景的几何体进行修改的操作,以达到最优渲染效率。虽然最优渲染效率只是一个理想状态,但一定的几何体操作在相当程度上可以提高渲染效率。
  在 OSG 中,为了获得所需的性能和渲染的效率,osgUtil 库提供了一些通用的几何体运算,这些几何体运算主要包括 osgUtil::Simplifier(简化)、osgUtil::SmoothingVisitor(生成法线)、osgUtil::DelaunayTriangulator(生成 Delaunay 三角网工具)和 osgUtil::TriStripVisitor(条带化)等。
  下面就来介绍几种常用的几何体操作。

1.1 osgUtil::Simplifier类

  简化几何体(osgUtil::Simplifier)类继承自 osg::NodeVisitor 类,它采用访问器的方式遍历几何体并对其进行简化处理,在后面的章节将会详细说明访问器的工作机制。osgUtil::Simplifier 类对几何体的简化主要需要设置两个方面的参数,即当几何体样本比率小于 1时,设置点的误差限制;当几何体的样本比率大于 1 时,设置边的长度限制。通过对点的误差或者边的长度的限制简化不必要的点和边,然后通过平滑处理和条带化渲染几何体,进而达到提高渲染效率的目的,也可以用于自动生成低层次模型。一般来说,样本比率越大,简化越少;样本比率越小,简化越多。优化可以直接调用下面的函数:

virtual void apply(osg::Geode &geode) //应用于叶节点
void simplify(osg::Geometry &geometry)//简化几何体

这两个函数同样可用于 osg::Node 节点,不过,关联实例时需要使用 accept()方法。osgUtil::Simplifier 简化采用的是边塌陷算法。

1.2 实例

在这里插入图片描述

1.3 实例源码

// OSGExamples.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <windows.h>
#include <osgViewer/Viewer>

#include <osg/Node>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/Billboard>
#include <osg/Texture2D>
#include <osg/Image>
#include <osg/Vec3>
#include <osg/Vec2>
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>

#include <osgViewer/ViewerEventHandlers> //事件监听
#include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制
#include <osgUtil/Simplifier> //简化几何体

#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgUtild.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgTextd.lib")

//读取模型
osg::Node *readModel()
{
	osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
	return node.release();
}

//深拷贝并简化新模型
osg::Node *deepCopy(osg::Node *node)
{
	/*
	创建简化对象  simplifier(sampleRatio, maxError)
	参数:样本比率、点的误差或边的长度 样本比率<1 设置点的误差
	样本比率>1 设置边的长度限制   比率越大,简化越少  使用的是边塌陷算法
	*/
	float sampleRatio = 0.3f;
	float maxError = 4.0f;
	osgUtil::Simplifier simplifier(sampleRatio, maxError);

	//深拷贝
	osg::ref_ptr<osg::Node> deepnode = (osg::Node *)(node->clone(osg::CopyOp::DEEP_COPY_ALL));
	//创建一个位置变换节点,将之设置为新位置,将深拷贝的模型移到新位置
	osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();
	pat->setPosition(osg::Vec3(10.0f, 0.0f, 0.0f));
	pat->addChild(deepnode);

	pat->accept(simplifier);

	return pat.release();
}

int main()
{
	//创建一个叶节点对象并添加节点 
	osg::ref_ptr<osg::Group> root = new osg::Group();
	osg::ref_ptr<osg::Node> node1 = readModel();
	osg::ref_ptr<osg::Node> node2 = deepCopy(node1);
	root->addChild(node1);
	root->addChild(node2);

	//优化场景数据
	osgUtil::Optimizer optimizer;
	optimizer.optimize(root.get());

	//显示模型
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
	//切换网格模式,方便比较
	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
	viewer->addEventHandler(new osgViewer::StatsHandler());//实现状态信息统计
	viewer->addEventHandler(new osgViewer::WindowSizeHandler());
	viewer->setSceneData(root.get());
	viewer->realize();

	return viewer->run();
}

2、Delaunay 三角网绘制

  在数字地形建模中,不规则三角网(TIN)通过从不规则离散分布的数据点生成的连续三角面来逼近地形表面。就表达地形信息的角度而言,TIN 模型的优点是它能以不同层次的分辨率来描述地形表面。与格网数据模型相比,TIN 模型在某一特定分辨率下能用更少的空间和时间更精确地表示更加复杂的表面。特别是当地形包含有大量特征,如断裂线、构造线时,TIN 模型能更好地顾及这些特征,从而能更精确合理地表达地表形态。
对于 TIN 模型,其基本要求有以下 3 点:
(1)TIN 是唯一的。
(2)力求最佳三角形几何形状。
(3)保证最邻近的点构成三角形。

  在所有可能的三角网中,狄洛尼(Delaunay)三角网在地形拟合方面表现最为出色,常用于 TIN的生成。当不相交的断裂线等被作为预先定义的限制条件作用于 TIN 的生成当中时,就必须考虑带约束条件的狄洛尼三角网。
  目前,狄洛尼三角网生成的算法比较多,传统的算法主要包括两种,即 Lawson 算法以及Bowyer-Watson 算法。后来经过该传统算法改进的算法就多了,这里不专门对这些算法予以介绍,可参考相关论文。上面介绍了狄洛尼(Delaunay)三角网的特性、生成算法及应用,下面来看一下 OSG 中的狄洛尼三角网。

2.1 osgUtil::DelaunayTriangulator 类

  osgUtil::DelaunayTriangulator 类直接继承自 osg::Referenced 类,创建狄洛尼三角网有如下 3 个步骤:
(1)创建顶点数组
(2)创建一个 osgUtil::DelaunayTriangulator 对象,并初始化顶点数组,同时生成三角网,**程序代码如下:

bool triangulate()//开始生成三角网格

(3)创建一个几何体对象,把 osgUtil::DelaunayTriangulator 类对象生成的绘制图元加入到几何体中。在生成狄洛尼三角网时,还可以添加一些限制条件,限制条件可以是点、线或多边形,例如:

void addInputConstraint(DelaunayConstraint *dc)//添加限制条件

2.2 三角带绘制

  三角带绘制(osgUtil::TriStripVisitor)类继承自 osgUtil::BaseOptimizerVisitor 类,它采用访问器的机制遍历场景中的几何体,实现三角带绘制,以提高渲染效率。
  下面对 osgUtil::TriStripVisitor 的两个常用成员函数予以说明:

void stripify(osg::Geometry &drawable)//条带化几何体
virtual void apply(osg::Geode &geode)//应用于叶节点

从上面可以看出,它同样可应用于叶节点。值得注意的是,关联叶节点实例时需要调用 accept()
方法。
  大多数图形卡并不直接支持索引三角网。在渲染三角形时,一般是将 3 个顶点同时提交,这样,共享的顶点会多次提交,三角形用到一次就提交一次。因为内存和图形硬件间的数据传输是瓶颈,所以很多 API 和硬件支持特殊的三角网格式以减少传输量。基本思想是排序点和面,使显卡中已有的三角形不需要再次传输。
  这里,我们只讨论三角带,三角带是一个三角形列表,其中每个三角形都与前一个三角形共享一边。在一种最理想的状态下,三角带可以用 N+2 个顶点表示存储 N 个面。N 很大时,每个三角形平均发送一个顶点。在实践中,很多情况下,很多网格是一个三角带无法表达的,此时就需要多个三角带来联合绘制。因为我们希望最小化发往图形卡的顶点数,所以,三角带的数目应该尽可能得少,即三角带越长越好。从另一个方面来说,分别渲染两个长度为 N 的三角带所需要的时间比渲染一个长度为2N 的三角带要长,即使 2N 的三角带中三角形的个数多于两个分开的三角带中的三角形个数的和,因为建立各三角带需要额外的处理时间。

2.3 实例效果

在这里插入图片描述

2.4 源码

#include <windows.h>
#include <osgViewer/Viewer>

#include <osg/Node>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/Billboard>
#include <osg/Texture2D>
#include <osg/Image>
#include <osg/Vec3>
#include <osg/Vec2>
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>

#include <osgViewer/ViewerEventHandlers> //事件监听
#include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制
#include <osgUtil/Simplifier> //简化几何体
#include <osgUtil/DelaunayTriangulator> 

#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgUtild.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgTextd.lib")

//Delaunay三角形
/*
创建顶点数组并添加数据  设置其他相关属性(可选)  创建osgUtil::DelaunayTriangulator类对象并生成三角网  创建几何体对象,把三角网类对象生成的绘制图元添加到几何体中
按w键显示网格化模型,可以看出网格密度不同  由于光照条件默认开启,旋转模型可以看出不同部位亮度显示不同  按l键显示关闭光照,旋转模型,可以看出亮度不变
*/

int GetRandValue(int nMIN, int nMAX)
{
	int nMax = 1;
	nMax = RAND_MAX;//rand()函数随机数的最大值

	return (int)(rand() * (nMAX - nMIN) / nMax + nMIN);
}

osg::ref_ptr <osg::Geode> createTriangulate()
{
	//创建顶点数组
	osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array();
	//添加顶点数据
	int nMin = -50;
	int nMax = 100;
	for (int i = -3000; i < 3000; i += 100)
	{
		if (i < -1000)
		{
			nMin = -100;
			nMax = 100;
		}
		else if (i > -1000 && i < 0)
		{
			nMin = -60;
			nMax = 30;
		}
		else if (i > 0 && i < 500)
		{
			nMin = -15;
			nMax = 10;
		}
		else if (i > 500 && i < 1000)
		{
			nMin = -10;
			nMax = 10;
		}
		else if (i > 1000 && i < 1500)
		{
			nMin = -20;
			nMax = 10;
		}
		else if (i > 15000)
		{
			nMin = -80;
			nMax = 50;
		}

		for (int j = -3000; j < 3000; j += 100)
		{
			float nZ = (float)GetRandValue(nMin, nMax);
			osg::Vec3 vertex(i, j, nZ);
			coords->push_back(vertex);
		}
	}

	//创建颜色数组
	osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array();
	//添加颜色数据 
	for (unsigned int i = 0; i < 6000; i++)
	{
		int nR = rand() % 10 + 2;
		color->push_back(osg::Vec4(0.0f, (double)nR / 10.0, 0.0f, 0.5f));
	}

	//创建Delaunay三角网对象
	osg::ref_ptr<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator(coords.get());
	//生成三角网
	dt->triangulate();

	//创建几何体
	osg::ref_ptr<osg::Geometry> pGeometry = new osg::Geometry();

	//设置顶点数组
	pGeometry->setVertexArray(coords.get());

	//设置颜色数组
	pGeometry->setColorArray(color.get());

	//设置颜色的绑定方式为单个顶点
	pGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

	//添加到绘图基元
	pGeometry->addPrimitiveSet(dt->getTriangles());

	osg::ref_ptr <osg::Geode> pGNode = new osg::Geode;

	pGNode->addChild(pGeometry);

	return pGNode.release();
}

int main()
{
	//添加到根节点
	osg::ref_ptr<osg::Group> root = new osg::Group();
	root->addChild(createTriangulate());

	//优化场景数据
	osgUtil::Optimizer optimizer;
	optimizer.optimize(root.get());

	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
	//方便查看在多边形之间切换,以查看三角网
	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
	viewer->addEventHandler(new osgViewer::StatsHandler());
	viewer->addEventHandler(new osgViewer::WindowSizeHandler());
	viewer->setSceneData(root.get());
	viewer->setUpViewInWindow(600, 600, 1000, 800);
	return viewer->run();
}

3、自动生成顶点法向量

  生成顶点法向量(osgUtil::SmoothingVisitor)类继承自 osg::NodeVisitor 类,它采用访问器机制,遍历场景中的几何体,生成顶点法向量。
下面对 osgUtil::SmoothingVisitor 的一个常用成员函数予以说明:

static void smooth(osg::Geometry &geoset)

  该函数用于生成顶点法向量,调用时需要注意,这是一个静态函数。在很多应用程序中,网格上的各点都需要一个表面法向量,它的用处非常广泛,例如:
计算光照。
背面剔除。
模拟粒子系统在表面的“弹跳”效果。
通过只需要正面而加速碰撞检测。

  通常我们在绘制几何体时都会指定法线。当得到一个模型,它本身并没有法向量时,则有必要通过现有的数据生成。通常,表面法向量可能保存于三角形级或顶点级,其中的一个技巧就是平均相邻三角形的表面法向量,并将结果标准化。当然,这要求知道三角形的法向量。一般可以这样假设,三角形的顶点按逆时针排列,通过叉积就可以计算外表面的法向量。当然,在有些情况下,顶点的顺序是未知且比较混乱的,这样就比较麻烦了。这个笔者也没有仔细深入研究,推荐读者看一下《计算非固定结构序列的多边形的顶点法线》这篇论文。通过平均三角形法向量求得顶点法向量是一种经验性的方法,不具有通用性。虽然在很多情况下都可以正确地工作,但有些情况下还是无法正常使用的,在使用布告板时,一定要注意这点,这时生成顶点法线的方法就会失效。因为布告板由两个三角形背靠构造而成,它的两个法向量是相反的,其平均值为 0,所以不能初始化,这时只能采用别的方法来处理,如“双面”三角形等。

4、OSG生成三维高程地形

  结合以上知识我们可以加入纹理制作一个三维地形文件。

4.1 地形效果

在这里插入图片描述

4.2 源码

#include <windows.h>
#include <osgViewer/Viewer>

#include <osg/Node>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/Billboard>
#include <osg/Texture2D>
#include <osg/Image>
#include <osg/Vec3>
#include <osg/Vec2>
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>

#include <osgViewer/ViewerEventHandlers> //事件监听
#include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制
#include <osgUtil/Simplifier> //简化几何体
#include <osgUtil/DelaunayTriangulator> 
#include <osgUtil/TriStripVisitor>
#include <osgUtil/SmoothingVisitor>

#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgUtild.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgTextd.lib")

//Delaunay三角形
/*
创建顶点数组并添加数据  设置其他相关属性(可选)  创建osgUtil::DelaunayTriangulator类对象并生成三角网  创建几何体对象,把三角网类对象生成的绘制图元添加到几何体中
按w键显示网格化模型,可以看出网格密度不同  由于光照条件默认开启,旋转模型可以看出不同部位亮度显示不同  按l键显示关闭光照,旋转模型,可以看出亮度不变
*/

int GetRandValue(int nMIN, int nMAX)
{
	int nMax = 1;
	nMax = RAND_MAX;//rand()函数随机数的最大值

	return (int)(rand() * (nMAX - nMIN) / nMax + nMIN);
}

osg::ref_ptr <osg::Geometry> createTriangulate()
{
	//创建顶点数组
	osg::ref_ptr<osg::Vec3Array> verTexs = new osg::Vec3Array();
	//添加顶点数据
	int nMin = -50;
	int nMax = 100;
	for (int i = -3000; i < 3000; i += 100)
	{
		if (i < -1000)
		{
			nMin = -100;
			nMax = 100;
		}
		else if (i > -1000 && i < 0)
		{
			nMin = -60;
			nMax = 30;
		}
		else if (i > 0 && i < 500)
		{
			nMin = -15;
			nMax = 10;
		}
		else if (i > 500 && i < 1000)
		{
			nMin = -10;
			nMax = 10;
		}
		else if (i > 1000 && i < 1500)
		{
			nMin = -20;
			nMax = 10;
		}
		else if (i > 15000)
		{
			nMin = -80;
			nMax = 50;
		}

		for (int j = -3000; j < 3000; j += 100)
		{
			float nZ = (float)GetRandValue(nMin, nMax);
			osg::Vec3 vertex(i, j, nZ);
			verTexs->push_back(vertex);
		}
	}

	//创建颜色数组
	osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array();
	//添加颜色数据 
	for (unsigned int i = 0; i < 6000; i++)
	{
		int nR = rand() % 10 + 2;
		color->push_back(osg::Vec4(0.0f, (double)nR / 10.0, 0.0f, 0.5f));
	}

	//创建Delaunay三角网对象
	osg::ref_ptr<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator(verTexs.get());
	//生成三角网
	dt->triangulate();

	//创建几何体
	osg::ref_ptr<osg::Geometry> pGeometry = new osg::Geometry();

	//设置顶点数组
	pGeometry->setVertexArray(verTexs.get());

	osg::ref_ptr<osg::Image> sImagePath = osgDB::readImageFile("D:\\Terrain.png");
	if (sImagePath.get())
	{
		osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
		texture2D->setImage(sImagePath.get());

		//绑定纹理后,释放内部的ref_ptr<Image>,删除image图像
		texture2D->setUnRefImageDataAfterApply(true);

		//建立纹理顶点
		osg::ref_ptr<osg::Vec2Array> pVec2Array = new osg::Vec2Array;
		for (int i = -3000; i < 3000; i += 100)
		{
			for (int j = -3000; j < 3000; j += 100)
			{
				osg::Vec2 textCoord(0.0, 0.0);
				textCoord.x() = (double)(j + 3000.0) / 6000.0;
				textCoord.y() = (double)(i + 3000.0) / 6000.0;
				pVec2Array->push_back(textCoord);
			}
		}

		//Texture类关联到渲染状态StateSet
		osg::ref_ptr<osg::StateSet> pStateSet = pGeometry->getOrCreateStateSet();

		//将纹理关联给StateSet纹理单元0、osg::StateAttribute::OFF关闭纹理
		pStateSet->setTextureAttributeAndModes(0, texture2D.get(), osg::StateAttribute::ON);

		pGeometry->setTexCoordArray(0, pVec2Array.get());

		//建立法线数组normal,垂直于Z轴负方向
		//osg::ref_ptr<osg::Vec3Array> pVec3ArrayNormal = new osg::Vec3Array;
		//pGeometry->setNormalArray(pVec3ArrayNormal.get());
		//pGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
		//pVec3ArrayNormal->push_back(osg::Vec3(0.0, 0.0, 1.0));

		pGeometry->setStateSet(pStateSet);
	}
	else
	{
		//设置颜色数组
		pGeometry->setColorArray(color.get());

		//设置颜色的绑定方式为单个顶点
		pGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
	}

	//添加到绘图基元
	pGeometry->addPrimitiveSet(dt->getTriangles());

	return pGeometry.release();
}

int main()
{
	//添加到根节点
	osg::ref_ptr<osg::Group> root = new osg::Group();
	osg::ref_ptr <osg::Geode> pGNode = new osg::Geode;

	//创建一个几何体对象
	osg::ref_ptr<osg::Geometry> geometry = createTriangulate();

	//自动生成顶点法线
	osgUtil::SmoothingVisitor::smooth(*(geometry.get()));

	//对几何体进行条带化
	osgUtil::TriStripVisitor stripper;
	stripper.stripify(*(geometry.get()));

	pGNode->addChild(geometry.get());

	root->addChild(pGNode);

	//优化场景数据
	osgUtil::Optimizer optimizer;
	optimizer.optimize(root.get());

	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
	//方便查看在多边形之间切换,以查看三角网
	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
	viewer->addEventHandler(new osgViewer::StatsHandler());
	viewer->addEventHandler(new osgViewer::WindowSizeHandler());
	viewer->setSceneData(root.get());
	viewer->setUpViewInWindow(600, 600, 1000, 800);
	return viewer->run();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1256833.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【双指针】三数之和

三数之和 在做这道题之前&#xff0c;建议建议先将两数之和做完再做&#xff0c;提升更大~ 文章目录 三数之和题目描述算法原理解法一解法二思路如下&#xff1a;处理细节问题&#xff1a; 代码编写Java代码编写C代码编写 15. 三数之和 - 力扣&#xff08;LeetCode&#xff0…

62 权限提升-烂土豆dll劫持引号路径服务权限

目录 演示案例:Win2012-烂士豆配合令牌窃取提权-Web权限Win2012-DLL劫持提权应用配合MSF-Web权限Win2012-不安全的服务权限配合MSF-本地权限Win2012-不带引号服务路径配合MSF-Web&#xff0c;本地权限补充说明: dll劫持提权及AlwaysInstallElevated等说明关于Windows相关知识点…

Redis未授权访问-CNVD-2019-21763复现

Redis未授权访问-CNVD-2019-21763复现 利用项目&#xff1a; https://github.com/vulhub/redis-rogue-getshell 解压后先进入到 RedisModulesSDK目录里面的exp目录下&#xff0c;make编译一下才会产生exp.so文件&#xff0c;后面再利用这个exp.so文件进行远程代码执行 需要p…

微机原理_5

一、单项选择题(本大题共15小题,每小题3分,共45分。在每小题给出的四个备选项中,选出一个正确的答案,请将选定的答案填涂在答题纸的相应位置上。) 8086微处理器CLK引脚输入时钟信号是由(提供。 A. 8284 B. 8288 C.8287 D. 8289 2.下面4个寄存器中,不能作为间接寻址的寄存器是(…

hivesql 将json格式字符串转为数组

hivesql 将json格式字符串转为数组 完整过程SQL在文末 json 格式字符串 本案例 json 字符串参考格式&#xff0c;请勿使用本数据 {"data": [{"province": 11,"id_card": "110182198903224674","name": "闾丘饱乾"…

【开源】基于JAVA的高校学院网站

项目编号&#xff1a; S 020 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S020&#xff0c;文末获取源码。} 项目编号&#xff1a;S020&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学院院系模块2.2 竞赛报名模块2.3 教…

人工智能_机器学习051_支持向量机SVM概念介绍_理解support vector machine---人工智能工作笔记0091

在出现深度学习,神经网络算法之前,支持向量机已经可以解决很多问题了,我们自然界中的问题,无非就是可以转换为回归问题和分类问题. 然后从现在开始我们来看支持向量机,首先看一下这几个字 support 是支持 vector是向量的意思,然后 machine指的是机器 那么我们之前用到的模型…

85基于Matlab的交通设施识别

基于Matlab的交通设施识别。 GUI设计图像处理, 基于数字图像处理&#xff0c;设计实现一个自然场景下公路交通限速标志分割和识别的程序。要求系统具有界面&#xff0c;并实现以下功能&#xff1a; 1&#xff09;读入自然场景下包含交通标志的图像&#xff1b; 2&#xff09;对…

Qt TCP网络上位机的设计(通过网络编程与下位机结合)

目录 TCP 协议基础 QTcpServer 和 QAbstractSocket 主要接口函数 TCP 应用程序 1.服务端 2.客户端 上位机通过网络编程与下位机实现通信 TCP 协议基础 传输控制协议&#xff08;TCP&#xff0c;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的、基于…

蓝桥杯-动态规划-子数组问题

目录 一、乘积最大数组 二、乘积为正数的最长子数组长度 三、等差数列划分 四、最长湍流子数组 心得&#xff1a; 最重要的还是状态表示&#xff0c;我们需要根据题的意思&#xff0c;来分析出不同的题&#xff0c;不同的情况&#xff0c;来分析需要多少个状态 一、乘积最…

Node.js与npm的准备与操作

1.下载 Node.js官网&#xff1a;Node.jsNode.js is a JavaScript runtime built on Chromes V8 JavaScript engine.https://nodejs.org/en 打开后的界面如下&#xff1a; LTS&#xff08;Long Term Support&#xff09;&#xff1a;长期支持版&#xff0c;稳定版 Current&am…

Vue+ElementUI+C#技巧分享:周数选择器

文章目录 前言一、周数的计算逻辑1.1 周数的定义1.2 年初周数的确定1.3 周数的计算方法 二、VueElementUI代码实现2.1 计算周数2.2 获取周的日期范围2.3 根据周数获取日期范围2.4 控件引用2.4.1 控件引用代码分析2.4.2 初始化变量代码分析 2.5 周数选择器完整代码 三、C#后端代…

10_7iic整体框架流程

在内核中 这边把iic整个流程分成了 4层 iic_dtiver at24_iic_eeprom 也就是我们的自己的驱动 i2c-core.c 核心层 i2c/busses/i2c-s3c2410.c 控制器层 平台总线驱动层,或者也是图中的设备树 硬件描述 我们假设 板子上有三个iic控制器 0 1 2 这里在控制器0 上挂载了gt24c02的eep…

Retrofit怎么返回一个JSON字符串?

项目用已经使用了 Retrofit&#xff0c;定义了接口方法&#xff0c;返回了 JSON 转换后的实体对象&#xff0c;炒鸡方便。但是总有意料之外的时候&#xff0c;比如我不需要返回实体对象&#xff0c;我要返回纯纯的 JSON 字符串&#xff0c;怎么办呢&#xff1f; 先看源码 通过…

ros2智能小车中STM32地盘需要用到PWM的模块

我做的地盘比较简单&#xff0c;使用了一下模块&#xff1a; 4个直流减速电机&#xff0c;&#xff08;每个模块用到了一个PWM&#xff09; 光电对射测速模块&#xff08;不用PWM) 超声波测距模块&#xff08;不用PWM&#xff0c;只需要测量时间&#xff09; sg90转向模块&…

C语言进阶-文件操作

目录 文件分类 程序文件 数据文件 文件的打开和关闭 文件指针 文件的顺序读写 文件读取结束的判定 文件缓冲区 文件版通讯录 实现代码 注意事项 ​编辑 ​编辑 实现效果 文件分类 磁盘上的文件是文件。 但是在程序设计中&#xff0c;我们一般谈的文件有两种&#xff1a;程…

【虚拟机】在VM中安装 CentOS 7

1.2.创建虚拟机 Centos7是比较常用的一个Linux发行版本&#xff0c;在国内的使用比例还是比较高的。 大家首先要下载一个Centos7的iso文件&#xff0c;我在资料中给大家准备了一个mini的版本&#xff0c;体积不到1G&#xff0c;推荐大家使用&#xff1a; 我们在VMware《主页》…

深入理解对象与垃圾回收机制

1、虚拟机中对象创建过程 1.1 对象创建过程 当我们使用 new 创建一个对象时&#xff0c;在 JVM 中进行了如下操作&#xff1a; 类加载&#xff1a;把 class 加载到 JVM 运行时数据区的过程。可以通过本地文件的形式&#xff0c;也可以通过网络加载。 检查加载&#xff1a;首…

【RTP】3: RTPSenderVideo::SendVideo 切片到发送

m98 版本。之前1 2 都是m79.RTPSenderVideo::SendVideo 负责切片,是入口 实际发送要靠: RTPSender* const rtp_sender_; 外部传递的: rtp_rtcp\source\rtp_sender.h 实现了rtp rtcp协议 ,负责实际的打包 新增了一个 TransformableFrameInterface 用的 编码线程 - RTPSend…

【数据库】缓冲区管理器结构,几种常用替换策略分析,pin钉住缓冲区块防止错误的替换,以及缓冲区管理带来的代价优化

缓冲区管理 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏会定期更新&…