Unity3D中球直角坐标与球极坐标映射

news/2024/6/1 21:21:50 标签: unity3d, shader

Unity3D中球直角坐标与球极坐标映射

    • 极坐标与直角坐标映射
    • Unity坐标系下映射
      • 二维纹理坐标转球直角坐标
      • 球直角坐标转球极坐标
      • 球极坐标转球直角坐标
      • 球直角坐标转二维纹理坐标
    • 验证

极坐标与直角坐标映射

在这里插入图片描述
球坐标系(r,θ,φ)与直角坐标系(x,y,z)的转换关系:
x=rsinθcosφ.
y=rsinθsinφ.
z=rcosθ.
反之,直角坐标系(x,y,z)与球坐标系(r,θ,φ)的转换关系为:
在这里插入图片描述
假设P(x,y,z)为空间内一点,则点P也可用这样三个有次序的数(r,θ,φ)来确定,其中r为原点O与点P间的距离;θ为有向线段OP与z轴正向的夹角;φ为从正z轴来看自x轴按逆时针方向转到OM所转过的角,这里M为点P在xOy面上的投影。

Unity坐标系下映射

Unity坐标系如下:
在这里插入图片描述
具体关系请参考:Unity3D中二维纹理与球坐标映射

二维纹理坐标转球直角坐标

//Vector2 viewPoint为二维纹理坐标,w、h为纹理宽高,r为球半径
x_pos = viewPoint.x / (float)w * (2 * M_PI) - M_PI;
y_pos = viewPoint.y / (float)h * (M_PI) - M_PI_2;//注意原点在左下角
Nx = (float)(Math.Cos(y_pos) * Math.Cos(x_pos))*r;
Nz = -1.0f * (float)(Math.Cos(y_pos) * Math.Sin(x_pos))*r;
Ny = (float)Math.Sin(y_pos)*r;

球直角坐标转球极坐标

angel_theta = (float)Math.Acos(Ny / r);//半径为r,弧度值
angel_phi = (float)Math.Atan(Nz / Nx);

球极坐标转球直角坐标

//Vector3 top_s为球直角坐标
top_s.x = (float)(Math.Sin(angel_theta) * Math.Cos(angel_phi))*r;
top_s.z = (float)(Math.Sin(angel_theta) * Math.Sin(angel_phi))*r;
top_s.y = (float)Math.Cos(angel_theta) * r;

球直角坐标转二维纹理坐标

//Vector2 top、viewPoint为二维纹理坐标,w、h为图像宽高,r为圆球半径
top.x = (float)(Math.Atan(-1.0f*top_s.z / top_s.x) / 2.000f / M_PI+0.500f);//纹理坐标,原点在左下角
top.y = (float)(Math.Asin(top_s.y / r) / M_PI + 0.500f);

viewPoint.x = (Int32)(top.x * w);
viewPoint.y = (Int32)(top.y * h);

验证

我们将二维纹理坐标上的点转换到球极坐标,对球极坐标进行角度的操作,再映射会二维纹理坐标,对其进行验证:

x_pos = viewPoint.x / (float)w * (2 * M_PI) - M_PI;
y_pos = viewPoint.y / (float)h * (M_PI) - M_PI_2;//注意原点在左下角

Nx = (float)(Math.Cos(y_pos) * Math.Cos(x_pos))*l;//球半径l
Nz = -1.0f * (float)(Math.Cos(y_pos) * Math.Sin(x_pos))*l;
Ny = (float)Math.Sin(y_pos)*l;
angel_theta = (float)Math.Acos(Ny/l);//半径为1,弧度值
angel_phi = (float)Math.Atan(Nz / Nx);
angel_alpha = (float)Math.Asin(1.0f);//改变角度为90°
//将图像向上旋转90°
top_s.x = (float)(Math.Sin(angel_theta - angel_alpha) * Math.Cos(angel_phi))*l;
top_s.z = (float)(Math.Sin(angel_theta - angel_alpha) * Math.Sin(angel_phi))*l;
top_s.y = (float)Math.Cos(angel_theta - angel_alpha) * l;
top.x = (float)(Math.Atan(-1.0f*top_s.z / top_s.x) / 2.000f / M_PI+0.500f);//纹理坐标,原点在左下角
top.y = (float)(Math.Asin(top_s.y/l) / M_PI + 0.500f);

viewPoint.x = (Int32)(top.x * w);
viewPoint.y = (Int32)(top.y * h);

输入视点坐标(1000.0f, 0.0f, 0.0f),视点图像如下:
在这里插入图片描述
变换后图像如下:
在这里插入图片描述
图像向上旋转了90°


http://www.niftyadmin.cn/n/1339411.html

相关文章

【Unity】镂空图片射线不遮挡

如图,外围米黄色的图片中间部分是透明的,想让中间部分不遮挡射线,从而使透明区域部分的组件可以响应点击事件 // 将图片的alpha命中最小阈值调成0.5,透明度在0.5以下的区域都不会遮挡射线 GetComponent<Image>().alphaHitTestMinimumThreshold 0.5f; // 同时,需要将该…

jQuery的选择器中的通配符

(1)通配符&#xff1a; $("input[id^code]");//id属性以code开始的所有input标签 $("input[id$code]");//id属性以code结束的所有input标签 $("input[id*code]");//id属性包含code的所有input标签 $("input[name^code]");//name属性以…

【Unity】Text组件内换行

代码内直接\n即可换行,但是直接在文本框输入\n是不行的, 可能是因为转义的问题被识别成了 \n,所以需要替换一下 txt.text txt.text.Replace("\\n", "\n");

zabbix开启web界面中文支持(中文乱码问题)

1.开启web界面中文支持#vi /var/www/zabbix/include/locales.inc.php将这一行修改为zh_CN > array(name > _(Chinese(zh_CN)), display > true)2.中文字体乱码问题替换 /var/www/zabbix/fonts/DejaVuSans.ttf即可转载于:https://blog.51cto.com/309173854/1854…

What is 20/20 Snellen fraction?

What is 20/20 Snellen fraction?When we take a driver’s license, we’ll get a number like “20 /?”.This is our visual acuty.But how can we know how much the question mark is? It’s very simple. I’ve figured it out for everyone, please see the table be…

shell--if、case语法详解

1. 条件选择 if 语句选择执行&#xff1a;单分支if 判断条件&#xff1a; then条件为真的分支代码fi双分支if 判断条件; then条件为真的分支代码else条件为假的分支代码fi多分支if CONDITION1; thenif-trueelif CONDITION2; thenif-tureelif CONDITION3; thenif-ture…elseall-…

【Unity】Text组件内空格会导致换行的问题

换行空格Unicode编码为 \u0020&#xff0c;不换行的 \u00A0 str str.Replace(" ", "\u00A0");

C语言第二次作业

转载于:https://www.cnblogs.com/lizi-shaoxiaoye/p/5894261.html