当前位置: 首页 > news >正文

GIS开发笔记(7)结合osg及osgEarth实现不同高度下的三个圆形区域形成的三维覆盖轮廓区域绘制

一、实现效果
在这里插入图片描述
二、实现原理
输入四个坐标点,第一个点为中心点,第二三四个点分别以中心点与地面垂线所在线上的各自高度水平面的交点为圆心旋转360°进行圆形区域绘制,然后将三个不同高度上的圆形区域进行结合形成三维覆盖区域的轮廓面。
三、参考代码

void GlobeWidget::draw3dCoverageRegion(const osg::ref_ptr<osg::Vec3Array>& points)
{if (!points || points->size() < 4)return;const osg::Vec3d& centerGeo = (*points)[0];osgEarth::GeoPoint geoCenter(osgEarth::SpatialReference::get("wgs84"),centerGeo.x(), centerGeo.y(), centerGeo.z(),osgEarth::ALTMODE_ABSOLUTE);osg::Vec3d centerWorld;geoCenter.toWorld(centerWorld);osg::Vec3d axis = centerWorld;axis.normalize();// === 圆形 ===const int segments = 60;  // 保证每个圆的分段数量一致std::vector<osg::ref_ptr<osg::Vec3Array>> circles;std::vector<int> layerOffsets;int vertexOffset = 0;// 绘制每个圆for (int i = 1; i <= 3; ++i){const osg::Vec3d& ptGeo = (*points)[i];osgEarth::GeoPoint geoPt(osgEarth::SpatialReference::get("wgs84"),ptGeo.x(), ptGeo.y(), ptGeo.z(),osgEarth::ALTMODE_ABSOLUTE);osg::Vec3d ptWorld;geoPt.toWorld(ptWorld);osg::Vec3d radiusVec = ptWorld - centerWorld;osg::ref_ptr<osg::Vec3Array> circlePts = new osg::Vec3Array();// 使用相同的分段数,避免缺口for (int j = 0; j < segments; ++j){double angle = osg::DegreesToRadians(360.0 * j / segments);osg::Matrixd rot = osg::Matrixd::rotate(angle, axis);osg::Vec3d rotated = radiusVec * rot;circlePts->push_back(centerWorld + rotated);}// 绘制当前圆osg::ref_ptr<osg::Geometry> circleGeom = new osg::Geometry();circleGeom->setVertexArray(circlePts);circleGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, circlePts->size()));osg::ref_ptr<osg::Vec4Array> circleColor = new osg::Vec4Array();circleColor->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));circleGeom->setColorArray(circleColor, osg::Array::BIND_OVERALL);osg::ref_ptr<osg::Geode> circleGeode = new osg::Geode();circleGeode->addDrawable(circleGeom);m_userDrawGroup->addChild(circleGeode);circles.push_back(circlePts);layerOffsets.push_back(vertexOffset);vertexOffset += circlePts->size();}// === 轮廓面 ===osg::ref_ptr<osg::Vec3Array> meshVerts = new osg::Vec3Array();osg::ref_ptr<osg::DrawElementsUInt> meshIndices = new osg::DrawElementsUInt(GL_TRIANGLES);// 合并所有圆的顶点for (auto& c : circles){for (auto& pt : *c)meshVerts->push_back(pt);}// 连接每一层圆之间的三角形for (size_t i = 0; i < circles.size() - 1; ++i){const int offset0 = layerOffsets[i];const int offset1 = layerOffsets[i + 1];// 确保每层圆的点数一致const int count = segments;for (int j = 0; j < count - 1; ++j){// 创建三角形meshIndices->push_back(offset0 + j);meshIndices->push_back(offset1 + j);meshIndices->push_back(offset0 + j + 1);meshIndices->push_back(offset0 + j + 1);meshIndices->push_back(offset1 + j);meshIndices->push_back(offset1 + j + 1);}// 最后一个三角形:补全圆的缺口meshIndices->push_back(offset0 + count - 1);meshIndices->push_back(offset1 + count - 1);meshIndices->push_back(offset0);meshIndices->push_back(offset0);meshIndices->push_back(offset1 + count - 1);meshIndices->push_back(offset1);}osg::ref_ptr<osg::Geometry> meshGeom = new osg::Geometry();meshGeom->setVertexArray(meshVerts);meshGeom->addPrimitiveSet(meshIndices);osg::ref_ptr<osg::Vec4Array> meshColor = new osg::Vec4Array();meshColor->push_back(osg::Vec4(1.0, 1.0, 0.0, 0.4));  // 半透明黄色meshGeom->setColorArray(meshColor, osg::Array::BIND_OVERALL);meshGeom->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);meshGeom->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);meshGeom->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);osg::ref_ptr<osg::Geode> meshGeode = new osg::Geode();meshGeode->addDrawable(meshGeom);m_userDrawGroup->addChild(meshGeode);// === 视角聚焦 ===if (m_osgWidget && m_osgWidget->getOsgViewer()){osgViewer::Viewer* viewer = m_osgWidget->getOsgViewer();osgEarth::Util::EarthManipulator* manip =dynamic_cast<osgEarth::Util::EarthManipulator*>(viewer->getCameraManipulator());if (manip){osgEarth::Viewpoint vp("Focus", centerGeo.x(), centerGeo.y(), centerGeo.z() + 300,0.0, -90.0, 1500.0);manip->setViewpoint(vp, 2.0);}}
}

相关文章:

  • AI 语音公司 ElevenLabs 进军亚太市场设立东京子公司;EverTutor Live :语音交互 AI 教育平台丨日报
  • 应用系统中的报表开发成本知多少?
  • SCA(软件成分分析)技术理念、市场前景及趋势
  • MySQL数据库权限管理
  • 刚刚,DeepSeek公布了推理引擎开源路径,OpenAI也将开始连续一周发布
  • 使用 vxe-table 来格式化任意的金额格式,支持导出与复制单元格格式到 excel
  • AI分析师
  • 高级语言调用C接口(二)回调函数(5)arkts
  • 一站式视频转换,在线转MKV,支持多种格式转换,便捷高效的格式转换之选
  • 客户验收标准模糊,如何明确
  • 爱普生FA1008AN在AI眼镜中的应用
  • 什么是进程?
  • C++之AVL树
  • 智能语音处理+1.3用SpeechLib实现文本转语音(100%教会)
  • 快手OneRec 重构推荐系统:从检索排序到生成统一的跃迁
  • FastAPI与SQLAlchemy数据库集成与CRUD操作
  • 【论文阅读笔记】模型的相似性
  • sonar-scanner (信创环境-arm64)执行报错
  • Android 应用数据分布目录结构解析
  • MCP:构建大型语言模型与外部系统无缝交互的标准协议架构
  • 网站建设要多少钱怎样/百度云盘资源搜索
  • 如何在自己的网站上做友情链接/seo搜索引擎优化推广
  • 公司网站备案查询/新站优化案例
  • 公司制做网站/线下引流推广方法
  • 专业做网站的团队推荐/网页生成
  • 苏州模板建站定制/新媒体营销策略有哪些