笛卡尔坐标系转极坐标系(3D 坐标)

5
如何在三维空间中转换笛卡尔坐标系和极坐标系(以及相反方向)?最好附带一个C#示例,但任何语言的示例都可以。谢谢!
编辑:考虑到变化的20%(不形成球体)
编辑2:
private void Spherise() {
        for (int i = 0; i < vertices.Count; i++) {
            float radius = this.radius;
            float longitude = 0;
            float latitude = 0;

            float sphereRadius = 32;

            Color color = vertices[i].Color;

            ToPolar(vertices[i].Position - centre, out radius, out longitude, out latitude);
            Vector3 position = ToCartesian(sphereRadius, longitude, latitude) + centre;

            Vector3 normal = vertices[i].Position - centre;
            normal.Normalize();

            const float lerpAmount = 0.6f;
            Vector3 lerp = (position - vertices[i].Position) * lerpAmount + vertices[i].Position;
            vertices[i] = new VertexPositionColorNormal(lerp, color, normal);
        }
    }

    private void ToPolar(Vector3 cart, out float radius, out float longitude, out float latitude) {
        radius = (float)Math.Sqrt((double)(cart.X * cart.X + cart.Y * cart.Y + cart.Z * cart.Z));
        longitude = (float)Math.Acos(cart.X / Math.Sqrt(cart.X * cart.X + cart.Y * cart.Y)) * (cart.Y < 0 ? -1 : 1);
        latitude = (float)Math.Acos(cart.Z / radius) * (cart.Z < 0 ? -1 : 1);
    }

    private Vector3 ToCartesian(float radius, float longitude, float latitude) {
        float x = radius * (float)(Math.Sin(latitude) * Math.Cos(longitude));
        float y = radius * (float)(Math.Sin(latitude) * Math.Sin(longitude));
        float z = radius * (float)Math.Cos(latitude);

        return new Vector3(x, y, z);
    }

enter image description here


最好能展示一下你已经尝试过的内容... - Shai
1
为什么会有人点踩?我问这个是因为我不知道如何做,而且在这个网站上似乎没有包括第三维的问题... - Darestium
你在谈论哪个极坐标系?柱面坐标系?球面坐标系? - Jeff Mercado
@JeffMercado 球形的。 - Darestium
3个回答

7

从笛卡尔坐标到极坐标:

r = sqrt(x * x + y * y + z * z)
long = acos(x / sqrt(x * x + y * y)) * (y < 0 ? -1 : 1)
lat = acos(z / r)

从极坐标到直角坐标:

x = r * sin(lat) * cos(long)
y = r * sin(lat) * sin(long)
z = r * cos(lat)

我还没有测试过它。

您可以重写以减少浮点操作的数量。


谢谢!在第一行第二个块中,我想你是指“x”吧? - Darestium
好的,我已经更新了我的代码 - 它似乎不能正常工作(请参见编辑)。 - Darestium
@Darestium:你能展示一下你的代码吗?请注意,我使用距离、纬度和经度来表示三维极坐标。 - nhahtdh
@Darestium:我发现公式有误,请再检查一遍。 - nhahtdh
我已经再次编辑了我的答案(并且我已经查看了http://en.wikipedia.org/wiki/Spherical_coordinate_system)。如果不起作用,那么我会删除我的答案。 - nhahtdh

2
这取决于方位角是如何测量的 - 是从水平面还是从垂直轴测量。我已经阅读了维基百科文章,但如果您将其测量为地理纬度(赤道= 0,极点= +90和-90),则应使用asin和sin函数。在我使用c#编写的3D建模软件中,方位角是相对于xy平面而不是z轴测量的。在我的情况下,公式如下:纬度 = asin(z / r);x = r * cos(lat)* cos(long);y = r * cos(lat)* sin(long);z = r * sin(lat)。

1

为了考虑到四象限:

r = sqrt(x * x + y * y + z * z)
long = atan2(y,x);
lat = acos(z / r);

那是在下列函数中实现的,我在四个象限中进行了检查:
double modulo(vector <double> xyz) { return sqrt(xyz[0] * xyz[0] + xyz[1] * xyz[1] + xyz[2] * xyz[2] + 1e-130); }
void cartesian_to_polar(vector <double> a, double& r, double& lat, double& lon) { r = modulo(a); lon = atan2(a[1], a[0]); lat = acos(a[2] / r); }
void polar_to_cartesian(double r, double lat, double lon, vector <double>& a) { a[2] = r * cos(lat); a[0] = r * sin(lat) * cos(lon); a[1] = r * sin(lat) * sin(lon); }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接