osgEarth示例分析——osgearth_terrainprofile

news2024/9/24 21:26:20

前言

osgearth_terrainprofile示例,涉及到一个新的类 TerrainProfileCalculator(地形轮廓计算器类),用来计算两个点连线之间的地形数据。左下角会根据点击的起点和终点进行计算,并更新显示地形信息。

效果

拖动地球,到某一个视角下,左下角的地形线会跟着变化。点击地球上的某处,控制台会输出将经纬高的信息。

拖动地球、缩放地球、点击地球,都会打印下面的内容,但并未找到是哪段程序输出的以下内容:

......
start_lat = 0.829058 start_longitude = 1.50569 start_height = 764.592
end_lat = 0.809018 end_longitude = 1.62256 end_height = 2756.64
start_lat = 0.804757 start_longitude = 1.90578 start_height = 1089.97
end_lat = 1.00064 end_longitude = 1.82342 end_height = 334.665
start_lat = 0.804757 start_longitude = 1.90578 start_height = 1089.97
end_lat = 1.00064 end_longitude = 1.82342 end_height = 307.551
start_lat = 0.749422 start_longitude = 1.89211 start_height = 948.917
end_lat = 0.616939 end_longitude = 1.93604 end_height = 416.177
......

代码分析

1. osg::Camera* createHud(double width, double height); 创建一个HUD相机,位置为左下角。

2. class TerrainProfileGraph 类,绘制地形的剖面高度线
// 组装将要展示在HUD相机内的东西。
redraw() {
// 1. 创建左下角背景节点
createBackground();
// 2. 绘制背景上的线条
// 3. 将4个label也绘制上去
}

3. class DrawProfileEventHandler类,处理鼠标点击事件。
点击起点和终点后,地形轮廓计算器对象_profileCalculator会更新,进而左下角的图线、标签也会更新。
看代码的意思,地球上应该会出现两个点的连线,但是并没有绘制上去。

#include <osg/Notify>
#include <osgGA/StateSetManipulator>
#include <osgGA/GUIEventHandler>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgEarth/MapNode>
#include <osgEarth/XmlUtils>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/AutoClipPlaneHandler>
#include <osgEarthUtil/TerrainProfile>
#include <osgEarth/GeoMath>
#include <osgEarth/Registry>
#include <osgEarth/FileUtils>
#include <osgEarth/GLUtils>
#include <osgEarthFeatures/Feature>
#include <osgEarthAnnotation/FeatureNode>
#include <osgText/Text>
#include <osgText/Font>
#include <osg/io_utils>

using namespace osgEarth;
using namespace osgEarth::Util;
using namespace osgEarth::Symbology;
using namespace osgEarth::Features;
using namespace osgEarth::Annotation;


//Creates a simple HUD camera
// 创建一个HUD相机,放在左下角
osg::Camera* createHud(double width, double height)
{
    osg::Camera* hud = new osg::Camera;
    hud->setProjectionMatrix(osg::Matrix::ortho2D(0,width,0,height));// 左下角,2维投影    
    hud->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    hud->setViewMatrix(osg::Matrix::identity());    // 更新
    hud->setClearMask(GL_DEPTH_BUFFER_BIT);// 设置深度缓存
    hud->setRenderOrder(osg::Camera::POST_RENDER);
    hud->setAllowEventFocus(false);
    osg::StateSet* hudSS = hud->getOrCreateStateSet();
    GLUtils::setLighting(hudSS, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
    hudSS->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF);
    hudSS->setMode( GL_BLEND, osg::StateAttribute::ON);

    return hud;
}

/**
 * Simple terrain profile display
 * 简单的地形剖面显示。
 */
class TerrainProfileGraph : public osg::Group
{
public:
    /*
     * Callback that is fired when the TerrainProfile changes
	 * 当TerrainProfile更改时触发的回调。
     */
    struct GraphChangedCallback : public TerrainProfileCalculator::ChangedCallback
    {
        GraphChangedCallback( TerrainProfileGraph* graph):
        _graph( graph )
      {
      }

      virtual void onChanged(const TerrainProfileCalculator* sender )
      {
        _graph->setTerrainProfile( sender->getProfile() );
      }

      TerrainProfileGraph* _graph;
    };

	// 构造时,传入 地形轮廓计算器对象profileCalculator,同时创建4个标签(仅设置位置、颜色、字体大小)
    TerrainProfileGraph( TerrainProfileCalculator* profileCalculator, double graphWidth = 200, double graphHeight = 200 ):
    _profileCalculator( profileCalculator ),
        _graphWidth( graphWidth ),
        _graphHeight( graphHeight ),
        _color( 1.0f, 1.0f, 0.0f, 1.0f),
        _backcolor(0.0f,0.0f,0.0f,0.5f)
    {
        _graphChangedCallback = new GraphChangedCallback( this );
        _profileCalculator->addChangedCallback( _graphChangedCallback.get() );

        float textSize = 8;
        osg::ref_ptr< osgText::Font> font = osgEarth::Registry::instance()->getDefaultFont();

        osg::Vec4 textColor = osg::Vec4f(1,0,0,1);
        
		// 显示距离最小的标签,在左下角
        _distanceMinLabel = new osgText::Text();
        _distanceMinLabel->setCharacterSize( textSize );
        _distanceMinLabel->setFont( font.get() );
        _distanceMinLabel->setAlignment(osgText::TextBase::LEFT_BOTTOM);
        _distanceMinLabel->setColor(textColor);

		// 显示距离最大的标签,在右下角
        _distanceMaxLabel = new osgText::Text();
        _distanceMaxLabel->setCharacterSize( textSize );
        _distanceMaxLabel->setFont( font.get() );
        _distanceMaxLabel->setAlignment(osgText::TextBase::RIGHT_BOTTOM);
        _distanceMaxLabel->setColor(textColor);

		// 显示最小高程的标签,在右下角
        _elevationMinLabel = new osgText::Text();
        _elevationMinLabel->setCharacterSize( textSize );
        _elevationMinLabel->setFont( font.get() );
        _elevationMinLabel->setAlignment(osgText::TextBase::RIGHT_BOTTOM);
        _elevationMinLabel->setColor(textColor);

		// 显示最大高程的标签,在右上角
        _elevationMaxLabel = new osgText::Text();
        _elevationMaxLabel->setCharacterSize( textSize );
        _elevationMaxLabel->setFont( font.get() );
        _elevationMaxLabel->setAlignment(osgText::TextBase::RIGHT_TOP);
        _elevationMaxLabel->setColor(textColor);
    }

	// 析构时,需要移除回调方法
    ~TerrainProfileGraph()
    {
        _profileCalculator->removeChangedCallback( _graphChangedCallback.get() );
    }

	// 设置 地形轮廓计 对象
    void setTerrainProfile( const TerrainProfile& profile)
    {
        _profile = profile;// 存储地形轮廓计算结果
        redraw();// 绘制
    }

    //Redraws the graph 绘制(或者叫组装)矩形,包括:背景、线、4个标签的内容
    void redraw()
    {
        removeChildren( 0, getNumChildren() );

		// 将创建的背景节点,加入当前节点
        addChild( createBackground( _graphWidth, _graphHeight, _backcolor));

        osg::Geometry* geom = new osg::Geometry;
        geom->setUseVertexBufferObjects(true);

        osg::Vec3Array* verts = new osg::Vec3Array();
        verts->reserve( _profile.getNumElevations() );
        geom->setVertexArray( verts );// 绑定顶点
        if ( verts->getVertexBufferObject() )
            verts->getVertexBufferObject()->setUsage(GL_STATIC_DRAW_ARB);// 静态绘制

		// 绑定颜色
        osg::Vec4Array* colors = new osg::Vec4Array(osg::Array::BIND_OVERALL);
        colors->push_back( _color );
        geom->setColorArray( colors );

		// 从 地形轮廓计算器对象 获取最小高程和最大高程
        double minElevation, maxElevation;
        _profile.getElevationRanges( minElevation, maxElevation );
        double elevationRange = maxElevation - minElevation;// 高程范围

        double totalDistance = _profile.getTotalDistance();// 获取总的距离

        for (unsigned int i = 0; i < _profile.getNumElevations(); i++)
        {
            double distance = _profile.getDistance( i );
            double elevation = _profile.getElevation( i );

			// 根据 距离和高程 占 总距离和总高程 的比,确定xy坐标
            double x = (distance / totalDistance) * _graphWidth;
            double y = ( (elevation - minElevation) / elevationRange) * _graphHeight;
            verts->push_back( osg::Vec3(x, y, 0 ) );// 用此值来初始化顶点坐标
        }

		// 用计算得到的顶点坐标绘制连续线条
        geom->addPrimitiveSet( new osg::DrawArrays( GL_LINE_STRIP, 0, verts->size()) );
        osg::Geode* graphGeode = new osg::Geode;
        graphGeode->addDrawable( geom );
        addChild( graphGeode );

		// 添加4个label,并初始化文本内容
        osg::Geode* labelGeode =new osg::Geode;
        labelGeode->addDrawable( _distanceMinLabel.get());
        labelGeode->addDrawable( _distanceMaxLabel.get());
        labelGeode->addDrawable( _elevationMinLabel.get());
        labelGeode->addDrawable( _elevationMaxLabel.get());

        _distanceMinLabel->setPosition( osg::Vec3(0,0,0));
        _distanceMaxLabel->setPosition( osg::Vec3(_graphWidth-15,0,0));
        _elevationMinLabel->setPosition( osg::Vec3(_graphWidth-5,10,0));
        _elevationMaxLabel->setPosition( osg::Vec3(_graphWidth-5,_graphHeight,0));
        
        _distanceMinLabel->setText("0m");        
        _distanceMaxLabel->setText(toString<int>((int)totalDistance) + std::string("m"));
        
        _elevationMinLabel->setText(toString<int>((int)minElevation) + std::string("m"));
        _elevationMaxLabel->setText(toString<int>((int)maxElevation) + std::string("m"));

        addChild( labelGeode );

    }

	// 创建左下角的背景
    osg::Node* createBackground(double width, double height, const osg::Vec4f& backgroundColor)
    {
        //Create a background quad
        osg::Geometry* geometry = new osg::Geometry();
        geometry->setUseVertexBufferObjects(true);

		// 左下角为(0,0)点位置
        osg::Vec3Array* verts = new osg::Vec3Array();
        verts->reserve( 4 );
        verts->push_back( osg::Vec3(0,0,0));
        verts->push_back( osg::Vec3(width,0,0));
        verts->push_back( osg::Vec3(width,height,0));
        verts->push_back( osg::Vec3(0,height,0));
        geometry->setVertexArray( verts );// 设置顶点坐标
        if ( verts->getVertexBufferObject() )
            verts->getVertexBufferObject()->setUsage(GL_STATIC_DRAW_ARB);// 静态绘制,因为左下角的矩形背景不会动

        osg::Vec4Array* colors = new osg::Vec4Array(osg::Array::BIND_OVERALL);
        colors->push_back( backgroundColor );// 设置背景色
        geometry->setColorArray( colors );

		// 绘制方式为四边形
        geometry->addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 4 ) );

        osg::Geode* geode = new osg::Geode;
        geode->addDrawable( geometry );

        return geode;

    }


    osg::ref_ptr<osgText::Text> _distanceMinLabel, _distanceMaxLabel, _elevationMinLabel, _elevationMaxLabel;

    osg::Vec4f _backcolor;
    osg::Vec4f _color;
    TerrainProfile _profile;
    osg::ref_ptr< TerrainProfileCalculator > _profileCalculator;
    double _graphWidth, _graphHeight;
    osg::ref_ptr< GraphChangedCallback > _graphChangedCallback;
};

/*
 * Simple event handler that draws a line when you click two points with the left mouse button
 * 简单的事件处理程序,当您用鼠标左键单击两点时绘制一条线。
 */
class DrawProfileEventHandler : public osgGA::GUIEventHandler
{
public:
    DrawProfileEventHandler(osgEarth::MapNode* mapNode, osg::Group* root, TerrainProfileCalculator* profileCalculator):
      _mapNode( mapNode ),
          _root( root ),
          _startValid( false ),
          _profileCalculator( profileCalculator )
      {
          _start = profileCalculator->getStart().vec3d();
          _end = profileCalculator->getEnd().vec3d();
          compute();
      }

      bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
      {
		  // 鼠标左键按下,拾取点
          if (ea.getEventType() == ea.PUSH && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
          {
              osg::Vec3d world;// 存储世界坐标系下的坐标点,XY是屏幕坐标点
              if ( _mapNode->getTerrain()->getWorldCoordsUnderMouse( aa.asView(), ea.getX(), ea.getY(), world ))
              {
                  GeoPoint mapPoint;
                  mapPoint.fromWorld( _mapNode->getMapSRS(), world );// 世界坐标转为经纬度坐标
                  //_mapNode->getMap()->worldPointToMapPoint( world, mapPoint );

                  if (!_startValid)// 判断是否为起点
                  {
                      _startValid = true;
                      _start = mapPoint.vec3d();
                      if (_featureNode.valid())
                      {
                          _root->removeChild( _featureNode.get() );
                          _featureNode = 0;
                      }
                  }
                  else
                  {
                      _end = mapPoint.vec3d();
                      compute();// 获取到终点后,开始计算
                      _startValid = false;                    
                  }
              }        
          }
          return false;
      }

	  // 获取起点和终点后,计算
      void compute()
      {
          //Tell the calculator about the new start/end points
		  // 将起点和终点设置到计算器中
          _profileCalculator->setStartEnd( GeoPoint(_mapNode->getMapSRS(), _start.x(), _start.y()),
                                           GeoPoint(_mapNode->getMapSRS(), _end.x(), _end.y()) );
		  // 如果有,则移除特征
          if (_featureNode.valid())
          {
              _root->removeChild( _featureNode.get() );
              _featureNode = 0;
          }

		  // 新建特征线
          LineString* line = new LineString();
          line->push_back( _start );
          line->push_back( _end );
          Feature* feature = new Feature(line, _mapNode->getMapSRS());
          feature->geoInterp() = GEOINTERP_GREAT_CIRCLE; // 大圆弧线   

          //Define a style for the line
          Style style;
          LineSymbol* ls = style.getOrCreateSymbol<LineSymbol>();
          ls->stroke()->color() = Color::Yellow;// 线颜色
          ls->stroke()->width() = 3.0f;// 线宽
          ls->tessellationSize()->set(100.0, Units::KILOMETERS);// 线的细化程度

          AltitudeSymbol* alt = style.getOrCreate<AltitudeSymbol>();
          alt->clamping() = alt->CLAMP_TO_TERRAIN;// 贴地形
          alt->technique() = alt->TECHNIQUE_DRAPE;

          RenderSymbol* render = style.getOrCreate<RenderSymbol>();
          render->lighting() = false;// 关闭灯光

          feature->style() = style;
          _featureNode = new FeatureNode( feature );
          _featureNode->setMapNode(_mapNode);
          _root->addChild( _featureNode.get() );

      }




      osgEarth::MapNode* _mapNode;      
      osg::Group* _root;
      TerrainProfileCalculator* _profileCalculator;// 地形轮廓计算器
      osg::ref_ptr< FeatureNode > _featureNode;
      bool _startValid;
      osg::Vec3d _start;
      osg::Vec3d _end;  
};




int
main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc,argv);
    osgViewer::Viewer viewer(arguments);

    // load the .earth file from the command line. 加载earth文件
    osg::ref_ptr<osg::Node> earthNode = osgDB::readNodeFiles( arguments );
    if (!earthNode.valid())
    {
        OE_NOTICE << "Unable to load earth model" << std::endl;
        return 1;
    }

    osg::Group* root = new osg::Group();

    osgEarth::MapNode * mapNode = osgEarth::MapNode::findMapNode( earthNode.get() );
    if (!mapNode)
    {
        OE_NOTICE << "Could not find MapNode " << std::endl;
        return 1;
    }

	// 添加操作器
    osgEarth::Util::EarthManipulator* manip = new EarthManipulator();    
    viewer.setCameraManipulator( manip );

    root->addChild( earthNode );    

	// 主窗口宽高
    double backgroundWidth = 500;
    double backgroundHeight = 500;

	// 左下角小窗口宽高
    double graphWidth = 200;
    double graphHeight = 100;

    //Add the hud 创建hud相机
    osg::Camera* hud = createHud( backgroundWidth, backgroundHeight );
    root->addChild( hud );

	// TerrainProfileCalculator类:计算两点之间的地形轮廓。监视场景图形中高程的更改并更新轮廓。
	// calculator:简称 地形轮廓计算器
	// 两点坐标已知
    osg::ref_ptr< TerrainProfileCalculator > calculator = new TerrainProfileCalculator(mapNode, 
        GeoPoint(mapNode->getMapSRS(), -124.0, 40.0),
        GeoPoint(mapNode->getMapSRS(), -75.1, 39.2)
        );    

	// 地形轮廓节点,存储的是左下角整个矩形内部的节点
    osg::Group* profileNode = new TerrainProfileGraph( calculator.get(), graphWidth, graphHeight );
    hud->addChild( profileNode );// 所有东西放入hud相机


    viewer.getCamera()->addCullCallback( new AutoClipPlaneCullCallback(mapNode));

	// 设置自定义的事件处理器,处理地球上显示的两个点的连线
    viewer.addEventHandler( new DrawProfileEventHandler( mapNode, mapNode, calculator.get() ) );

    viewer.setSceneData( root );    

    // add some stock OSG handlers:
    viewer.addEventHandler(new osgViewer::StatsHandler());
    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
    viewer.addEventHandler(new osgViewer::ThreadingHandler());
    viewer.addEventHandler(new osgViewer::LODScaleHandler());
    viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));

    return viewer.run();
}

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

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

相关文章

[附源码]Python计算机毕业设计SSM基于的智慧校园安防综合管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

软件安全测试-Web安全测试详解-XSS攻击

目录 1. XSS攻击 1.1 XSS攻击原理 1.2 XSS能做什么 1.3 XSS三种类型 1.4 XSS三种途径 1.5 XSS测试方法 1.5.1 查看代码 1.5.2 准备测试脚本 1.5.3 自动化测试XSS漏洞 1.5.4 XSS注入常用语句 1.6 XSS漏洞防范h3 1.6.1 对输入和URL参数进行过滤(白名单和黑名单) 1.6.…

tensorflow入门(一) 计算图、张量、会话的概念

1、计算图 计算图是tensorflow中最基本的一个概念&#xff0c;tensorflow中的所有计算都被转化成计算图上的节点。tensorflow的名字已经说明了它最重要的两个概念------tensor和flow。张量这个概念在数学或者物理学中可以有不同的解释&#xff0c;在tensorflow中&#xff0c;张…

基于tensorflow的深层神经网络(三)如何用tensorflow优化神经网络

1、神经网络优化算法 梯度下降算法主要用户优化单个参数的取值&#xff0c;而反向传播算法给出了一个高效的方式在所有参数上使用梯度下降算法&#xff0c;从而使神经网络模型在训练数据上的损失函数尽可能小。反向传播算法是训练神经网络的核心算法&#xff0c;它可以根据定义…

红黑树的插入过程

一棵红黑树是一种特殊的二叉查找树&#xff0c;具有以下性质&#xff1a; 每个节点要么是红色&#xff0c;要么是黑色。根节点是黑色。每个叶子节点&#xff08;NIL&#xff09;是黑色。如果一个节点是红色的&#xff0c;那么它的两个儿子都是黑色的。从任意一个节点到其每个叶…

71.qt quick-可伸展菜单-抽屉栏示例 通用QML界面(一键换肤)

在我们之前章节已经提供过了抽屉栏和菜单伸展栏: 63.qt quick-QML侧边滑动栏(不需要任何图片资源,支持自定义左右方向和大小)_诺谦的博客-CSDN博客_qml侧边栏68.qt quick-qml多级折叠下拉导航菜单 支持动态添加/卸载 支持qml/widget加载等_诺谦的博客-CSDN博客_qml下拉菜单 由…

三维家发生工商变更:注册资本减少46%,美凯龙、阿里等股东退出

近日&#xff0c;云工业软件服务商广东三维家信息科技有限公司&#xff08;下称“三维家”&#xff09;发生工商变更&#xff0c;注册资本由16.9254亿元变更为9亿元&#xff0c;同比减少46.83%。同时&#xff0c;包括红星美凯龙、阿里巴巴等多名股东退出&#xff0c;变更时间为…

01.Spring源码整体脉络介绍及源码编译——四

IOC是核心 IOC 容器加载过程【重要】&#xff1a;所有模块都依赖IOC&#xff0c;aop&#xff0c;循环依赖都依赖IOC IOC控制反转&#xff0c;控制理念&#xff0c;来解决层与层之间的耦合。DI注入实现 怎么讲Bean交给IOC容器来管理 配置类xml&#xff0c;注解 加载spring上下…

java计算机毕业设计ssm学院校友信息管理系统的设计与实现5yqhy(附源码、数据库)

java计算机毕业设计ssm学院校友信息管理系统的设计与实现5yqhy&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts…

【Java基础篇】基础知识易错集锦(二)

我们同样用几道例题来回顾相对应的基础知识&#xff1b; 解析&#xff1a; 首先我呢区分一下实例变量和局部变量&#xff1b; 局部变量&#xff1a;定义在方法内部的变量&#xff1b;实例变量&#xff1a;定义在类中但在任何方法之外&#xff0c;你也可以理解为全局变量&…

16.C预处理器和C库

文章目录C预处理器和C库16.1翻译程序的第一步16.2明示常量&#xff1a;#define16.3在#define中使用参数16.3.1用宏参数创建字符串&#xff1a;#运算符16.3.2预处理器黏合剂&#xff1a;##运算符16.3.3变参宏&#xff1a;...和__VA_ARGS__16.4宏和函数的选择16.5文件包含&#x…

NCTF2022 calc题目复现

calc&#xff08;环境变量注入getshell&#xff09; 经典计算器题目&#xff0c;看着有点眼熟&#xff0c;没错&#xff0c;就是buu三月赛的一道题目。由于那时候web可能都算不上入门&#xff0c;所以也就没有复现。比赛时就网上看了看三月赛的wp&#xff0c;但是没有什么用&a…

IEEE 二进制浮点数的表示

今天&#xff0c;我来将 IEEE 二进制浮点数的表示方式进行一个简单的介绍。 浮点数 在 C 语言中&#xff0c;有两种存储浮点数的方式&#xff0c;分别是 float 和 double &#xff0c;当然了还有long double。这几种浮点型所容纳的长度不同&#xff0c;当然它们存储的精度也就…

[附源码]JAVA毕业设计新型药物临床信息管理系统(系统+LW)

[附源码]JAVA毕业设计新型药物临床信息管理系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 …

p5.第一章 Python基础入门 -- 运算符、优先级和表达式 (五)

1.2.3.2.11 False等价 False等价布尔值,相当于bool(value) 空容器 空集合set空字典dict空列表list空元组tuple空字符串None0# bool(value)是布尔函数# In: bool(1), bool(0) # Out: (True

离散数学·支配集、覆盖集、独立集和匹配

支配集 简而言之——V-支配集后剩下的点&#xff0c;都能在支配集中找到相邻的点 支配数的符号是γ0&#xff08;有关点的集&#xff0c;下标为0&#xff09; 例 右下角相同颜色的为同一个支配集 要注意极小性 整个V就是支配集&#xff08;所以说支配集找极大没有意义&#xf…

测试员凡尔赛,工作三年晒出11月工资条,直言加班太累了

最近有工作3年的测试员晒出自己11 月份的工资条&#xff0c;并直言加班太累了。 从工资条上可以看到&#xff0c;这个收入确实不算低&#xff0c;才3年时间&#xff0c;月工资就已经到了二万五了&#xff0c;这个工资已经可以击败绝大多数行业了。 不过二万五只是税前工资&am…

第二证券|系统性稳地产政策加力 租购并举制度加快建立

在房地产职业深度调整期&#xff0c;下一年方针走向备受关注。虽然日前召开的中心政治局会议没提及房地产&#xff0c;可是从其对经济方针的表述能够预见&#xff0c;作为经济支柱产业的房地产职业&#xff0c;下一年将在稳经济中发挥更重要的效果&#xff0c;国家将持续出台系…

[附源码]Python计算机毕业设计SSM基于的装修公司运营管理管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

一文彻底搞懂ssh的端口转发

文章目录背景什么是端口转发&#xff1f;本地端口转发本地端口转发的语法场景1场景二ssh -L参数解释ssh 远程端口的安全问题远程端口转发远程端口转发的语法场景一远程端口转发和本地端口转发要在哪台服务器上执行场景二ssh -R 参数解释端口转发的选项端口转发需要修改哪些ssh配…