• 用C#写小工具:将圆柱面贴图映射到半球贴图


    最近在写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、具体的映射转换根据柱面映射和半球映射的方法有所区别,需要按情况分析。

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

  • 相关阅读:
    13年7月memory point
    getDefinitionByName getDefinition 区别
    cocos2d-html5版日历组件
    一个js对象的代码结构
    计算机操作系统复习
    计算机组成原理复习
    最新的hustoj搭建姿势
    推荐算法学习笔记
    BUPT 2012复试机考 4T
    BUPT 2012复试机考 3T
  • 原文地址:https://www.cnblogs.com/h5l0/p/11597931.html
Copyright © 2020-2023  润新知