【问题标题】:Calculate the XYZ point of a sphere, given a UV coordinate of its texture给定球体纹理的 UV 坐标,计算球体的 XYZ 点
【发布时间】:2011-12-12 00:43:16
【问题描述】:

我有一个 3D 球体。在运行时,我正在为它生成一个动态的 2048x1024 纹理。在这个纹理上画了一个小圆圈,它可以在任何地方。我在纹理上有这个圆的 x/y,因此有相应的 UV 坐标。现在,我想插入这个小圆圈在我的球体上的确切位置。

这是我一直在使用的代码,但它似乎总是偏离 +/-90 度

// U, V are original UV obtained from dynamic texture.

_u =  Math.PI * U;  
_v =  -2 * Math.PI * V;

_x = Math.cos(_u) * Math.sin(_v) * radius;
_y = Math.sin(_u) * Math.sin(_v) * radius;
_z = Math.cos(_v) * radius;

感谢您的帮助!

【问题讨论】:

    标签: 3d geometry coordinates uv-mapping


    【解决方案1】:

    根据您在 cmets 中发布的代码,这里是如何生成 X、Y 和 Z 值的。

    theta = 2 * PI * U;
    phi = PI * V;
    
    _x = Math.cos(theta) * Math.sin(phi) * radius;
    _y = Math.sin(theta) * Math.sin(phi) * radius;
    _z = -Math.cos(phi) * radius;
    

    旧答案:

    您的代码很好。你确定球体是以同样的方式生成的,并且两极像这样沿着 Z 轴吗? “通常”球体是沿 Y 轴的极点生成的。检查一下。

    否则,如果您总是偏离 +/- 90°,请使用定义 x 和 y 的 sin 和 cos。例如:

    _x = -Math.sin(_u) * Math.sin(_v) * radius;
    _y = Math.cos(_u) * Math.sin(_v) * radius;
    

    是原件的 90° 旋转。

    您可以通过 8 种不同的方式计算这两个分量的正弦/余弦,并使用不同的符号。在不知道您的球体是如何生成的情况下,您必须全部尝试。 他们走了

    (x = sin(u), y = cos(u));
    (x = sin(u), y = -cos(u));
    (x = -sin(u), y = cos(u));
    (x = -sin(u), y = -cos(u));
    
    (x = cos(u), y = sin(u));
    (x = cos(u), y = -sin(u));
    (x = -cos(u), y = sin(u));
    (x = -cos(u), y = -sin(u));
    

    然而,这既痛苦又棘手,我强烈建议您尝试找出您的球体是如何生成的。它们通常通过遍历 U 和 V 来生成 x、y、z 位置。

    【讨论】:

    • 谢谢你 - 极点在 Y 轴上(Y-UP 也是),如果这有什么改变的话。
    • 恐怕还是没明白:(
    • 有很多方法可以将 UV 坐标映射到球体上,这取决于球体的生成方式。你的球体来自哪里?您使用的是 OpenGL 还是 DirectX?
    • 以下是 UV 的生成方式(抱歉没有适当的间距): numUvs = 0; for (j = 0; j
    • 这没有多大帮助。如果您发布整个球体生成代码,我几乎可以向您保证正确的算法;)。只需再次编辑您的问题并添加球体生成代码。
    【解决方案2】:

    确保您定义了正确的轴,即:

    ENU - 东北向上 NED - 东北向下

    NED 和 ENU 的变换通常是不同的,因为方位角的定义方式相同,即相对于北的顺时针方向 ..

    在每个的 theta 上做一个 90- 或使用同角规则。

    尝试自己推导公式是可能的。确保你知道正在使用什么约定

    【讨论】:

      【解决方案3】:

      您用来生成球体的方程是将极点视为 Z 轴。如果您使用 GLUT 之类的东西,默认坐标系的 Z 加上垂直于屏幕,“向上”是 Y 轴。如果您交换 Z 和 Y,它可能对您有用。我刚刚完成了类似的操作,我对结果很满意。

      我使用了以下。

      double theta = ((2 * PI) / lWidth) * u;
      double phi = (PI / lHeight) * v;
      
      double dX = std::cos(theta) * std::sin(phi) * radius;
      double dZ = std::sin(theta) * std::sin(phi) * radius;
      double dY = std::cos(phi) * radius;
      

      lWidth 和 lHeight 是我映射到球体的位图的尺寸。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-19
        • 1970-01-01
        • 2012-07-18
        • 2012-05-04
        • 2020-01-03
        • 1970-01-01
        • 2014-04-06
        相关资源
        最近更新 更多