最近在写GBA的程序。GBA运行的是C的裸机代码,而中途使用的很多小工具则用C#写的,例如:图片转换到.h头文件,制作三角函数表,还有像这次介绍的将圆柱面贴图映射到半球贴图的小工具。这样的小功能,用C#写就是一小会的事,效率非常高。

这时候就能体现出来——各语言有各自的用途,C用来做硬件开发,C++做软件开发,C#做快速功能。

这次要解决的问题是:

制作3D时,一个球体的贴图,我们通常映射成一个柱面,就像我们常见的世界地图一样。如图(这张图片是从NASA上下载的卫星图)

但是如果我们想用半球映射来贴图,例如分成北半球和南半球分别映射,那不一定能找到合适的贴图。

但我们可以很简单的将柱面贴图转换成半球贴图。如图(半球之外的区域我也映射了):

代码如下:

using System;
using System.Drawing;
using System.Drawing.Imaging;  

public void ToSphereMap(int spWidth, int spHeight)
{
//加载bmp柱面贴图
Bitmap bmp = newBitmap("CylinderMap.png");
//创建球面贴图
Bitmap sphereMap = new Bitmap(spWidth, spHeight * 2); int clHeight = bmp.Height;
int clWidth = bmp.Width; double a, b; //半球面贴图平面上xy坐标(a,b)
double z; //对应球体上点(x,y,z)的z轴坐标
double s; //轴面角度
int clX, clY1, clY2;

  for (int spY = 0; spY < spHeight; spY++)
  {
    for (int spX = 0; spX < spWidth; spX++)
    {
      //r = sqrt(a^2+b^2) = x^2+y^2 = 1-z^2
      a = spX * 2 / (float)spWidth - 1;
      b = spY * 2 / (float)spHeight - 1;
      z = 1 - Math.Sqrt(a * a + b * b);
      //if (z < 0) z = -Math.Sqrt(-z);
      //else z = Math.Sqrt(z);       s = Math.Atan2(y, x) + Math.PI;
      clX = s * clWidth / (2 * Math.PI);
      clY1 = (int)((1 - z) * clHeight * 0.5);
      clY2 = (int)((1 + z) * clHeight * 0.5);       if (clX < 0) clX = 0;
      else if (clX > clWidth - 1) clX = clWidth - 1;
      if (clY1 < 0) clY1 = 0;
      else if (clY1 > clHeight - 1) clY1 = clHeight - 1;
      if (clY2 < 0) clY2 = 0;
      else if (clY2 > clHeight - 1) clY2 = clHeight - 1;       sphereMap.SetPixel(spX, spY, bmp.GetPixel(clX, clY1));
      sphereMap.SetPixel(spX, spY + spHeight, bmp.GetPixel(clX, clY2));       }
    }

  //保存图片
  sphereMap.Save("SphereMap.png", ImageFormat.Png);
}

  

补充一些注释:

1、转换后的半球贴图分上下两部分,分别是北南半球。

2、转换的主要思路是从半球贴图上的位置寻找对应的柱面贴图坐标。

  (a, b)是半球平面上的坐标,对应于球体上的点坐标(x, y, z);

3、具体的映射转换根据柱面映射和半球映射的方法有所区别,需要按情况分析。

  这里使用的映射方法稍后我会上一张图解释。

最新文章

  1. Git中如何利用生成SSH个人公钥访问git仓库
  2. Kinect开发资源汇总
  3. C#操作mysql数据库
  4. Hadoop学习记录
  5. Sequential List
  6. MVC 之 Partial View 用法
  7. 接触Matlab10年后的一个总结,随时使用Matlab要掌握的一些要点
  8. 【Todo】Python字符编码学习
  9. java如何追加写入txt文件
  10. RestFul &amp;&amp; HATEOAS &amp;&amp; Spring-Data-Rest介绍
  11. C#中 字符串的处理
  12. HTTP缓存 1.0 vs 1.1
  13. opencv菜鸟学习之旅cvNorm
  14. T-SQL流程控制
  15. Luogu P3919 【模板】可持久化数组 可持久化线段树
  16. mysql中 REPLACE INTO 和 INSERT INTO 的区别
  17. Vue(八)发送跨域请求
  18. solr建立pdf/word/excel索引的方法
  19. [leetcode]Surrounded Regions @ Python
  20. vs2013 查找进行的过程中被停止

热门文章

  1. 感谢ZhangYu dalao回关
  2. windows下如何安装Python虚拟环境
  3. 如何修改git上传代码的作者姓名
  4. 爬虫学习--Requests库详解 Day2
  5. 安装Windows和Ubuntu双系统--Ubuntu安装过程识别不了硬盘
  6. JavaScript BOM学习
  7. Python 基础之socket编程(三)
  8. CentOS 6.4 configure error的解决方法
  9. libpcap的下载与安装(apt-get安装unable to locate package 的解决方法(Ubantu))
  10. 创建OData Service(基于ASP.NET 4.6.1, EF 6),Part I:Project initialize