java - 具有圆心、半径和法 vector 的圆圆周上的 3d 点

标签 java android opengl-es 3d geometry

我的问题类似于 How to Make a Point Orbit a Line, 3D但那里的答案似乎并没有解决我的问题。我正在寻找的是一个通用的解决方案。

郑重声明,我正在尝试解决 OpenGL ES (Java/Android) 中的问题。

我有一个圆,其中心为 3D 点,半径为 3D vector ,指定圆所在平面的法线。

我需要找到代表圆周上与“旋转”X 轴(根据法线 vector 旋转)给定角度的点的 3D 点。

我已经在成员函数pointAtCircle类中实现了它,它在有限的情况下工作。具体来说,在我当前的实现中,我假设圆位于 X-Y 平面中并相应地返回一个点,然后,因为我知道圆实际上位于 X-Z 平面中,所以我只需交换返回点中的 Y 和 Z 值即可。 。然而,这不是一个通用的解决方案,这正是我所需要的。

当我尝试 How to Make a Point Orbit a Line, 3D 中给出的算法时,我得到的分数与应有的分数相差甚远。

那么,如何计算这样一个圆的圆周上的点呢?

[编辑] 我想我的解释还不够充分。我的假设是,圆在 X-Y 平面上“正常”,在 Z 方向上的法 vector 为 (0, 0, 1) - 1。如果需要圆周上的点,则该点定义为:

x = R*cos(a) + Cx
y = R*sin(a) + Cy

其中R是半径,CxCyXY code> 圆心坐标,a 是 vector 通过圆心且与 X 轴平行的角度。

现在,如果圆没有指向 Z 轴的法线 vector ,而是某个任意 (x, y, z) vector ,我如何找到同一点?

最佳答案

您需要一个新的坐标系来放置圆。对于任何常见的坐标系,我们希望基 vector 彼此正交,并且长度均为 1。我将把基 vector 命名为 v1v2v3,它们按顺序对应于 x、y 和 z。

替换 z 的新基 vector ,即 v3 由圆的法 vector 给出。如果尚未标准化,您需要在此处对其进行标准化:

     [ v3x ]
v3 = [ v3y ] = normalize(circleNormal)
     [ v3z ]

接下来,我们将选择v1。这可以是与 v3 正交的任意 vector 。由于我们希望它取代 x 轴,因此我们可以选择它的 y 分量为 0:

               [ v3z ]
v1 = normalize([ 0   ])
               [ -v3x]

请注意,该 vector 与 v3 的点积为 0,这意味着这两个 vector 确实是正交的。如果圆的法 vector 恰好指向 y 方向,则 vector 将退化。如果您在使用时担心这个问题,我会让您弄清楚如何处理。

现在我们只需要最后一个 vector ,它可以通过其他两个 vector 的叉积来计算:

v2 = v3 x v1

由于 v1v3 已标准化,因此这已经标准化,并且是正交的。

有了这个新的基础,圆上的点现在可以计算如下:

p = centerPoint + R * (cos(a) * v1 + sin(a) * v2)

让整个事情更接近代码形式(未经测试):

// Only needed if normal vector (nx, ny, nz) is not already normalized.
float s = 1.0f / (nx * nx + ny * ny + nz * nz);
float v3x = s * nx;
float v3y = s * ny;
float v3z = s * nz;

// Calculate v1.
s = 1.0f / (v3x * v3x + v3z * v3z);
float v1x = s * v3z;
float v1y = 0.0f;
float v1z = s * -v3x;

// Calculate v2 as cross product of v3 and v1.
// Since v1y is 0, it could be removed from the following calculations. Keeping it for consistency.
float v2x = v3y * v1z - v3z * v1y;
float v2y = v3z * v1x - v3x * v1z;
float v2z = v3x * v1y - v3y * v1x;

// For each circle point.
px = cx + r * (v1x * cos(a) + v2x * sin(a))
py = cy + r * (v1y * cos(a) + v2y * sin(a))
pz = cz + r * (v1z * cos(a) + v2z * sin(a))

关于java - 具有圆心、半径和法 vector 的圆圆周上的 3d 点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27714014/

相关文章:

java - Android XmlPullParser - 如何解析此 XML 示例文件?

ios - 如何更改渲染对象在屏幕上的放置位置,OpenGL Es 2.0 iOS

android - android opengl游戏的线程纹理加载过程

java - 从 Java 执行 PostgreSQL anon block

java - spring bean 错误

java - 如何在渲染页面后添加组件

java - 在 Eclipse 中,如何访问另一个项目中的资源?

android - 如何在没有请求正文的情况下发出 OKHTTP 发布请求?

java - FragmentPagerAdapter - 设置异步计数和标题

html - 如何在 WebGL/OpenGL 中有效地旋转大量的 gl.LINES?