将球体投影到立方体上

时间:2022-06-01 17:55:50

I'm currently working on building a game which is on a planet, the way in which I'm planning to store the data is in 6 2dimensional arrays, which are heightmaps around the sphere (on the faces of a cube). The problem I have is this, given a normalised vector which points outwards from the centre of the sphere how can I determine these two things:

我正在制作一个行星上的游戏,我计划存储数据的方式是6个二维数组,这是围绕球体的高度图(在立方体的面上)。我遇到的问题是,给定一个从球体中心向外指向的归一化向量,我如何确定这两个方面:

  1. The plane which it intersects
  2. 它相交的平面

  3. The x/y coordinates I should look up in my 2d array to get the height.
  4. x / y坐标我应该在我的2d数组中查找以获得高度。

My current solution is this (using XNA):

我目前的解决方案是这个(使用XNA):

  1. Construct a ray pointing out from [0,0] along the direction vector supplied. Loop through each surface and do a ray/plane intersection (which is a method supplied by the XNA framework) to get the distance to the intersection point. Select the closest plane (shortest distance to intersection)
  2. 构造一条沿着提供的方向向量从[0,0]指向的光线。遍历每个表面并执行光线/平面交叉(这是XNA框架提供的方法)以获得到交叉点的距离。选择最近的平面(到交叉点的最短距离)

  3. Take the 3D point, and convert it to a 2D point which can be used as an array lookup to find the radius (this is the bit I cannot work out the maths for, or find any references to through google).
  4. 取3D点,并将其转换为2D点,可用作数组查找以查找半径(这是我无法计算数学的位,或通过谷歌找到任何引用)。

A helpful constraint is that the sphere/cube system is around the origin.

一个有用的约束是球体/立方体系统位于原点附近。

So, the problem which needs solving is this: Given a direction vector, how do I determine where it intersects the surrounding cube. Using this result how do I then get the correct value in a 2D array which is "painted" on the face of this cube?

因此,需要解决的问题是:给定方向向量,如何确定它与周围立方体的交叉点。使用此结果,我如何在这个立方体表面“绘制”的2D数组中获取正确的值?

3 个解决方案

#1


Look at the magnitude of each of the 3 components of the direction. The one with the largest magnitude tells you which face of the cube you hit (and its sign tells you if it's the + or - face.)

看看方向的3个组成部分的大小。幅度最大的那个告诉你你击中的立方体的哪个面(它的符号告诉你它是+或 - 面。)

The other two coordinates give you your 2D mapping values. We need to normalize them, though. If your XYZ direction has X as the highest magnitude, then your 2D face coordinates are just U=Y/X and V=Z/X. These both range from -1 to 1.

另外两个坐标为您提供2D映射值。不过,我们需要对它们进行标准化。如果XYZ方向的X值最大,则2D面部坐标只是U = Y / X和V = Z / X.这些都在-1到1之间。

Be careful of flips from positive to negative sides, you may need to flip the 2D U and/or V values to match your coordinate system.

要注意从正面到负面的翻转,您可能需要翻转2D U和/或V值以匹配您的坐标系。

#2


# edges are called X_AXIS_POS, X_AXIS_NEG, Y_AXIS_POS, Y_AXIS_NEG, Z_AXIS_POS, Z_AXIS_NEG
if (x*x >= y*y) && (x*x >= z*z) : 
    return ( (x>0) ? X_AXIS_POS : X_AXIS_NEG, y/abs(x), z/abs(x))
if (y*y >= z*z) && (y*y >= x*x) : 
    return ( (y>0) ? Y_AXIS_POS : Y_AXIS_NEG, x/abs(y), z/abs(y))
return ( (z>0) ? Z_AXIS_POS : Z_AXIS_NEG, x/abs(z), y/abs(z))

#3


If I'm understanding you correctly, you're trying to pull a pixel off the square and onto the surface of sphere. So I assume you've successfully found the pixel on the cube. Now you scale the vector so it's touching the sphere. So you have an x,y,z on the sphere.

如果我正确理解你,那你就是试图将一个像素从正方形上拉下来并放到球体表面上。所以我假设你已成功找到立方体上的像素。现在你缩放矢量,使它接触球体。所以你在球体上有一个x,y,z。

Spheres are usually texture mapped from a sheet. You can either find a reference to how it's done in XNA (or look at the texture sheet and try to figure it out), or you can do this: make a texture sheet that has increasing red gradient along the x axis and increasing green gradient along y. Map into onto the sphere. See what happens.

球体通常是从纸张映射的纹理。你可以找到它在XNA中的完成方式的参考(或者查看纹理表并尝试弄清楚),或者你可以这样做:制作一个沿x轴增加红色渐变并增加绿色渐变的纹理表沿着y。映射到球体上。走着瞧吧。

#1


Look at the magnitude of each of the 3 components of the direction. The one with the largest magnitude tells you which face of the cube you hit (and its sign tells you if it's the + or - face.)

看看方向的3个组成部分的大小。幅度最大的那个告诉你你击中的立方体的哪个面(它的符号告诉你它是+或 - 面。)

The other two coordinates give you your 2D mapping values. We need to normalize them, though. If your XYZ direction has X as the highest magnitude, then your 2D face coordinates are just U=Y/X and V=Z/X. These both range from -1 to 1.

另外两个坐标为您提供2D映射值。不过,我们需要对它们进行标准化。如果XYZ方向的X值最大,则2D面部坐标只是U = Y / X和V = Z / X.这些都在-1到1之间。

Be careful of flips from positive to negative sides, you may need to flip the 2D U and/or V values to match your coordinate system.

要注意从正面到负面的翻转,您可能需要翻转2D U和/或V值以匹配您的坐标系。

#2


# edges are called X_AXIS_POS, X_AXIS_NEG, Y_AXIS_POS, Y_AXIS_NEG, Z_AXIS_POS, Z_AXIS_NEG
if (x*x >= y*y) && (x*x >= z*z) : 
    return ( (x>0) ? X_AXIS_POS : X_AXIS_NEG, y/abs(x), z/abs(x))
if (y*y >= z*z) && (y*y >= x*x) : 
    return ( (y>0) ? Y_AXIS_POS : Y_AXIS_NEG, x/abs(y), z/abs(y))
return ( (z>0) ? Z_AXIS_POS : Z_AXIS_NEG, x/abs(z), y/abs(z))

#3


If I'm understanding you correctly, you're trying to pull a pixel off the square and onto the surface of sphere. So I assume you've successfully found the pixel on the cube. Now you scale the vector so it's touching the sphere. So you have an x,y,z on the sphere.

如果我正确理解你,那你就是试图将一个像素从正方形上拉下来并放到球体表面上。所以我假设你已成功找到立方体上的像素。现在你缩放矢量,使它接触球体。所以你在球体上有一个x,y,z。

Spheres are usually texture mapped from a sheet. You can either find a reference to how it's done in XNA (or look at the texture sheet and try to figure it out), or you can do this: make a texture sheet that has increasing red gradient along the x axis and increasing green gradient along y. Map into onto the sphere. See what happens.

球体通常是从纸张映射的纹理。你可以找到它在XNA中的完成方式的参考(或者查看纹理表并尝试弄清楚),或者你可以这样做:制作一个沿x轴增加红色渐变并增加绿色渐变的纹理表沿着y。映射到球体上。走着瞧吧。