opengl,从笛卡尔坐标转换球坐标

柯君雨

我尝试从笛卡尔坐标系中的一个点找到球坐标中的角度 theta 和 phi。

我找到的答案,这是不正确的。但我无法弄清楚发生了什么。请帮我。

这是我的代码:

Vector4 g_eye(8.0f, 8.0f, 8.0f);

Vector4 g_lookat(0.0f, 0.0f, 0.0f);

Vector4 g_up(0.0f, -1.0f, 0.0f);

struct spherical_sys
{

    spherical_sys(Vector4& p)
    {
        _dirty = 1;
       _pos = p;
       _pos.w = 0.0f;
       get_spherical(_pos, _theta, _phi, _r);
    }

    float getTheta()
    {
       return _theta;
    }

    float getPhi()
    {
       return _phi;
    }

    void setTheta(float t)
    {
       _theta = t;
       _dirty = 1;
    }

    void setPhi(float t)
    {
       _phi = t;
       _dirty = 1;
    }

    Vector4 get_pos()
    {
       if (_dirty)
       {
           float sin_phi, cos_phi;
           float sin_theta, cos_theta;
           FastMath::SinCos(_phi, sin_phi, cos_phi);
           FastMath::SinCos(_theta, sin_theta, cos_theta);

           _pos.w = 0.0f;
           _pos[0] = _r* cos_phi * cos_theta;
           _pos[1] = _r* sin_phi;
           _pos[2] = _r* cos_phi * sin_theta;
           _dirty = 0;
       }
       return _pos;
   }
private:
   void get_spherical(Vector4& dir, float& theta, float& phi, float& r)
   {
       r = dir.Length();
       dir.Normalize();
       phi = FastMath::ACos(Vector3Dotf(dir, Vector4(0.0f, 1.0f, 0.0f, 0.0f)));
       Vector4 v = Vector3CrossProduct(Vector4(0.0f, 1.0f, 0.0f, 0.0f), dir);
       if (v.x < 0.0f)
       {
           phi *= -1;
           phi = phi + MATH_PI * 0.5f;
       }
       else
       {
           phi = phi - MATH_PI * 0.5f;
       }
        theta = FastMath::ACos(Vector3Dotf(dir, Vector4(1.0f, 0.0f, 0.0f, 0.0f)));
        v = Vector3CrossProduct(Vector4(1.0f, 0.0f, 0.0f, 0.0f), dir);
       if (v.y < 0.0f)
       {
           theta *= -1;
       }
    }
    float _phi;
    float _theta;
    float _r;
    Vector4 _pos;
    int _dirty;
};
spherical_sys _teye(g_eye);
spherical_sys _tup(g_up);

_teye.get_pos().X,_teye.get_pos().Y,_teye.get_pos().Z的答案是6.531521,-7.998896,-9.238880。

显然,有什么地方不对劲。

詹姆斯·波格

看起来有几个问题。我不会评论你的代码结构,只是转换......

作为参考,这里是笛卡尔-球面转换的方程

您从 Spherical 到笛卡尔的转换不正确。它看起来既向后又......错了。这是正确的方程(请参阅下面关于交换 y/z 的注释)

       _pos[0] = _r* sin_theta * cos_phi;
       _pos[1] = _r* sin_theta * sin_phi;
       _pos[2] = _r* cos_theta;

方程中的点积没有用,结果只是y向量分量:

phi = FastMath::ACos(dir.y);

另一个问题是您似乎交换了 Y 轴和 Z 轴。只要您保持一致,这很好。即使进行了这种交换,您从球形到笛卡尔的转换仍然不正确。让我们继续经典。

phi = FastMath::ACos(dir.z);

接下来,您将使用叉积来帮助确定acos函数的范围这是一个“聪明”的技巧,直到您手动计算乘积并发现您实际上只是在检查 Z 坐标。

cross( (0,1,0), (x,y,z) ) => (z,0,-x)

接下来,我们将检查 theta 计算:

theta = FastMath::ACos(Vector3Dotf(dir, Vector4(1.0f, 0.0f, 0.0f, 0.0f)));

再一次,Dot 产品没用,你只是抓住了 x

theta = FastMath::ACos(dir.x);

简而言之,您可以看到您缺少组件并且使用了错误的触发函数。使用 ArcTan 而不是ArcCos。

theta = ATan2(dir.y, dir.x);

同样,看起来您正在使用叉积来修复范围。然而,手工计算产品:

cross ( (1,0,0) , (x,y,z) ) => (0,-z,y)

因此,您再次只需检查dir.z组件的符号,无需额外计算。


我的建议是首先使用经典方程来回转换。不要担心修复范围,您可以稍后在您的代码工作时进行。

一旦工作正常,请修复范围。范围正确后,再担心交换 Z 轴和 Y 轴(或不交换)。

如果您不确定点积或交叉积正在做什么,请手动解决。忽略这些函数的几何意义,您会发现它们在浪费计算并且通常使您的代码复杂化。

祝你好运!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

MatOfPoint笛卡尔坐标

来自分类Dev

将图像从笛卡尔坐标转换为极坐标

来自分类Dev

枫树,从极坐标转换为笛卡尔坐标?

来自分类Dev

将笛卡尔坐标转换为极坐标-Matlab

来自分类Dev

Oracle - 过滤笛卡尔坐标

来自分类Dev

将符号笛卡尔坐标转换为球形

来自分类Dev

霍夫变换:将极坐标转换回笛卡尔坐标,但仍无法绘制它们

来自分类Dev

将3D极坐标转换为笛卡尔坐标

来自分类Dev

如何在3D中将圆柱坐标转换为笛卡尔坐标以进行绘制?

来自分类Dev

如何在PostgreSQL中将球面坐标转换为笛卡尔坐标

来自分类Dev

如何将笛卡尔坐标转换为 360 图像上热点的球面坐标

来自分类Dev

笛卡尔坐标中的饼图

来自分类Dev

简单的笛卡尔坐标计算器

来自分类Dev

如何从极坐标中补偿笛卡尔坐标中的误差

来自分类Dev

有没有办法在 VB.net 中将像素坐标转换为笛卡尔坐标

来自分类Dev

如何将经度,纬度,高程转换为笛卡尔坐标?

来自分类Dev

OpenGL固定坐标转换

来自分类Dev

如何在Python中操纵笛卡尔坐标?

来自分类Dev

C程序,从旋转角度获取笛卡尔坐标

来自分类Dev

numpy,给定范数返回可能的笛卡尔坐标

来自分类Dev

Chart.js的笛卡尔坐标系

来自分类Dev

获取绘图区域ggplot2的笛卡尔坐标

来自分类Dev

C程序,从旋转角度获取笛卡尔坐标

来自分类Dev

如何提取svg图像的笛卡尔坐标(x,y)?

来自分类Dev

matplotlib结合极坐标和笛卡尔网格数据

来自分类Dev

笛卡尔坐标系中的边缘检查

来自分类Dev

如何提取笛卡尔坐标半径内的线

来自分类Dev

极坐标图中元素的matplotlib zorder叠加在笛卡尔坐标图上

来自分类Dev

从笛卡尔坐标到双球坐标的映射的怪异符号问题

Related 相关文章

热门标签

归档