三维模型转求顶和底视图

有一项需求: 求出模型的任意方向的视图

本文写一个求顶视图和底视图的方式,  任意方向的视图只是投影平面方程不同而已

测试模型:

顶视图

底视图

顶部高度图(灰度, 未取材质颜色, 懒没写)

底部高度图(灰度)

本算法原理分以下几部:

1: 求模型外包围盒box, 根据顶视图输出大小计算输出分辨率resx,resy

2: 遍历图像宽高范围内的所有像素, 求每点与模型每个三角面片的交点 z值

3: 一个点可能与多个三角形在Z方向上交, 按照最大最小值记录, 最小值底视图, 最大值顶视图

4: 得到的高度数组根据高度范围拉伸到0-255, 保存为图片

初步估算算法复杂度为n的3次方,  优化空间不大, 除了求接点与三角形外包可用box加速, 目前就剩开omp硬件加速,或者simd加速等非软件方法了.

可以看出求底部的时候中间有一个高度不正常,  检查模型发现是模型有个洞, 所以是正常现象.  关键算法代码如下:

关键代码如下:

void Mesh2HeightMap(Mesh & mesh, int w, int h, ByteBuffer * bufferhm, double hmin, double hmax)
{Help ctb;auto box = mesh.pTriMesh->GetBox();float Width = box[3] - box[0];float Height = box[4] - box[1];double resx = Width / w;double resy = Height / h;if (bufferhm)bufferhm->AllocateT<float>(w*h);float* Head = (float*)bufferhm->BufferHead();
#pragma omp parallel for	for (int i = 0; i < h; i++)for (int j = 0; j < w; j++){double x = box[0] + i * resx + 0.25 * resx;double y = box[4] - j * resy - 0.25 * resy;Point3D pOut(x, y, 0.);double maxvalue = -DBL_MAX;double minvalue = DBL_MAX;for (unsigned int k = 0; k < mesh.pTriMesh->triangles.size(); k++){int nindep1 = mesh.pTriMesh->triangles[k][0];int nindep2 = mesh.pTriMesh->triangles[k][1];int nindep3 = mesh.pTriMesh->triangles[k][2];size_t pointssize = mesh.pTriMesh->points.size();if (nindep1 >= pointssize || nindep1 < 0)continue;if (nindep2 >= pointssize || nindep2 < 0)continue;if (nindep3 >= pointssize || nindep3 < 0)continue;Vec3F p1 = mesh.pTriMesh->points[nindep1];Vec3F p2 = mesh.pTriMesh->points[nindep2];Vec3F p3 = mesh.pTriMesh->points[nindep3];Point3D pt1(p1.X(), p1.Y(), p1.Z());Point3D pt2(p2.X(), p2.Y(), p2.Z());oint3D pt3(p3.X(), p3.Y(), p3.Z());double xmin = std::min(std::min(pt1.X, pt2.X), std::min(pt3.X, pt2.X));double ymin = std::min(std::min(pt1.Y, pt2.Y), std::min(pt3.Y, pt2.Y));double xmax = std::max(std::max(pt1.X, pt2.X), std::max(pt3.X, pt2.X));double ymax = std::max(std::max(pt1.Y, pt2.Y), std::max(pt3.Y, pt2.Y));if (pOut.X < xmin || pOut.Y < ymin || pOut.X > xmax || pOut.Y >ymax)continue;//点在三角形上z值, 就是平面方程求zif (ctb.Point2Ttiangle(pt1, pt2, pt3, pOut)){maxvalue = maxvalue < pOut.Z ? pOut.Z : maxvalue;minvalue = minvalue > pOut.Z ? pOut.Z : minvalue;}}//Head[w * i + j] = maxvalue;Head[w * i + j] = minvalue;}
}
//保存高度数组为图像
void SaveHeight( int w,int h, ByteBuffer*bufferhm)
{ByteBuffer bufftttt;bufftttt.AllocateT<unsigned int>(w*h);unsigned int* buffhead = (unsigned int*)bufftttt.BufferHead();float* f = (float*)bufferhm->BufferHead();double min = DBL_MAX, max = -DBL_MIN;for (int i = 0; i < bufferhm->BufferSizeT<float>(); i++){	if (std::isinf(f[i]))continue;min = min > f[i] ? f[i]: min ;max = max < f[i] ? f[i]: max ;}BitmapPtr ptrIMG = new Bitmap(w, h);for (int i = 0; i < bufferhm->BufferSizeT<float>(); i++){unsigned char* g = (unsigned char*)&buffhead[i];if (std::isinf(f[i])){g[0] = 0;g[1] = 0;g[2] = 0;g[3] = 0;continue;}unsigned char RGB = 255 * (fabs(f[i] / (max - min)));g[0] = RGB;g[1] = RGB;g[2] = RGB;g[3] = 255;}ptrIMG->FillImageData(bufftttt.BufferHead(), bufftttt.BufferSize(), ptrIMG->RGBAType());char file[512];sprintf(&file[0], "D:\\testdata\\%d_%d_%d.png", 0, 0, 0);ptrIMG->SavePNG(file);
}

以上代码vs2015 测过( 高度图赋值颜色就是求z再去三角形种内插颜色即可

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

喜讯 | 经纬恒润整车电子电气测试实验室通过一汽研发总院外部实验室资质认证!

近日&#xff0c;经纬恒润整车电子电气测试实验室成功通过中国一汽研发总院的资质评定&#xff0c;获得外部实验室认可证书。这是继经纬恒润测试实验室获得一汽智能网联开发院车载以太网测试资质认证之后的又一次认可&#xff0c;它将拓宽经纬恒润与红旗新能源及相关零部件供应…

websocket编写聊天室

【黑马程序员】WebSocket打造在线聊天室【配套资料源码】 总时长 02:45:00 共6P 此文章包含第1p-第p6的内容 简介 温馨提示&#xff1a;现在都是第三方支持聊天&#xff0c;如极光&#xff0c;学这个用于自己项目完全没问题&#xff0c;大项目不建议使用 需求分析 代码

adb 无线连接 操作Android设备

最近集五福活动比较热门 可以用这个工具 用自己擅长的语言写一个循环程序 运行起来就可以 自动帮我们 看视频得福卡了 很方便 while (true) {sleep(mt_rand(15, 25));system(adb shell input swipe 500 2000 500 1000 100); } 1. 首先下载 安卓开发工具 adb adb网盘链接 链接…

检测头篇 | 原创自研 | YOLOv8 更换 SEResNeXtBottleneck 头 | 附详细结构图

左图:ResNet 的一个模块。右图:复杂度大致相同的 ResNeXt 模块,基数(cardinality)为32。图中的一层表示为(输入通道数,滤波器大小,输出通道数)。 1. 思路 ResNeXt是微软研究院在2017年发表的成果。它的设计灵感来自于经典的ResNet模型,但ResNeXt有个特别之处:它采用…

【SpringBoot系列】自动装配的魅力:Spring Boot vs 传统Spring

IT行业有哪些证书含金量高? 文章目录 IT行业有哪些证书含金量高?强烈推荐前言区别项目配置&#xff1a;依赖管理&#xff1a;内嵌服务器&#xff1a;开发体验&#xff1a; 实例Spring项目示例&#xff1a;Spring Boot项目示例&#xff1a; 总结强烈推荐专栏集锦写在最后 强烈…

Dubbo框架注册中心-Zookeeper搭建

Dubbo 是阿里巴巴公司开源的高性能、轻量级的Java RPC框架&#xff0c;致力于提供高性能。 Dubbo官网 本篇开始dubbo的第一篇&#xff0c;注册中心 ZooKeeper 环境搭建。 环境前置&#xff1a;由于Zookeeper是基于Java环境&#xff0c;必须安装有JDK。查看命令 java -version。…

中科院国际预警期刊名单发布一周年,共8本期刊被剔除!

据官方消息称&#xff1a;2024年中科院《国际期刊预警名单》将于2024年1月更新&#xff0c;今天已经是2月1号了&#xff0c;距离去年的2023年版《国际期刊预警名单&#xff08;试行&#xff09;》发布已经一周年&#xff0c;在去年被列入预警名单的28本期刊中&#xff0c;截止目…

中国的茶文化:现代生活中的茶文化

中国的茶文化&#xff1a;现代生活中的茶文化 引言 在现代社会的快节奏生活中&#xff0c;茶文化并未随时间流逝而褪色&#xff0c;反而以其独特的方式融入了全球各地人们的日常生活。它超越了饮品本身的范畴&#xff0c;成为一种连接历史、人文与现代生活方式的艺术形式。本文…

Git命令窗口:创建一个.bashrc文件,别名实现git log (代替冗余的指令)查询提交修改日志功能

在我们的用户下创建一个.bashrc文件&#xff0c;然后添加如下代码。即可实现我们命令窗口由于每次想要看到好的效果而输入几条指令的问题。 这里我们就只需要使用 git-log 代替我们的git log。这样在命令窗口看到的效果就清晰明了。

Java后端须知的前端知识

Java后端须知的前端知识 HTML &#xff08;超文本标记语言&#xff09; W3C标准 结构&#xff1a;HTML表现&#xff1a;CSS行为&#xff1a;JavaScript 快速入门 <html><head><title></title></head><body><font color"red&q…

【CSS】常见

一. 溢出隐藏 1.1 单行文本溢出 .content{max-width:200px; /* 定义容器最大宽度 */overflow:hidden; /* 隐藏溢出的内容 */text-overflow:ellipsis; /* 溢出部分...表示 */white-space: nowrap; /* 确保文本在一行内显示 */ }问题&#xff1a;display:flex 和 ellipsis 冲…

其实女士喝羊奶会有很多好处,羊大师带你了解

其实女士喝羊奶会有很多好处&#xff0c;羊大师带你了解 在现代社会中&#xff0c;人们对健康的关注越来越多。作为一种天然的营养食品&#xff0c;羊奶备受关注。不仅在婴儿配方奶粉中使用&#xff0c;现在越来越多的女性也开始喝羊奶。那么&#xff0c;女士喝羊奶到底有什么…

软件价值4-俄罗斯方块

俄罗斯方块也是一个可以简单实现的游戏 代码&#xff1a; import pygame import random import numpy as nppygame.init()# 游戏参数 WIDTH, HEIGHT 300, 600 GRID_SIZE 30 GRID_WIDTH WIDTH // GRID_SIZE GRID_HEIGHT HEIGHT // GRID_SIZE FPS 3# 颜色定义 WHITE (255,…

吉大计网笔记

Osi七层模型 物理层&#xff1a;比特流的透明传输 数据链路层&#xff1a;ip数据包装成帧并传输&#xff0c;处理相邻节点的数据传输。 网络层&#xff1a;选择路由和交换节点&#xff0c;处理任意节点的数据传输。 运输层&#xff1a;主机进程的数据传输服务&#xff0c;端到端…

轻量式RPC调用日志链路设计方案

导语: 调用链跟踪系统,又称为tracing&#xff0c;是微服务设计架构中&#xff0c;从系统层面对整体的monitoring和profiling的一种技术手 背景说明 由于我们的项目是微服务方向&#xff0c;中后台服务调用链路过深&#xff0c;追踪路径过长&#xff0c;其中某个服务报错或者异…

什么样的评论更容易得到别人的关注

要发表吸引人的评论&#xff0c;可以注意这些个方面&#xff1a; 合适的软件&#xff1a;用DT浏览器的笔记本写文本&#xff0c;保存为图片&#xff0c;用图片的方式评论更容易得到别人的关注。 特别的观点&#xff1a;发表与众不同的观点&#xff0c;或者从不同的角度看待问…

solr的原理是什么

1 Java程序里如果有无限for循环的代码导致CPU负载超高&#xff0c;如何排查&#xff1f; 排查Java程序中由于无限循环导致的CPU负载过高的问题&#xff0c;可以按照以下步骤进行&#xff1a; 资源监控&#xff1a; 使用系统命令行工具&#xff08;如Linux上的top或htop&#xf…

C语言第十四弹---函数递归

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 函数递归 1、递归是什么&#xff1f; 1.1、递归的思想 1.2、递归的限制条件 2、递归举例 2.1、举例1&#xff1a;求n的阶乘 2.1.1、分析和代码实现 2.1.2、…

三子棋游戏小课堂

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 今天的主菜是&#xff0c;C语言实现的三子棋小游戏&#xff0c; 所属专栏&#xff1a; C语言知识点 主厨的主页&#xff1a;Chef‘s blog 前言&…

gitlab-runner注册到gitlab时报错:ERROR: Registering runner... failed xxxxxxxx

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…