具有中心、半径和法向量的圆圆周上的 3d 点 [英] 3d point on circumference of a circle with a center, radius and normal vector

查看:28
本文介绍了具有中心、半径和法向量的圆圆周上的 3d 点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题类似于如何制作点轨道a Line, 3D 但那里的答案似乎并没有解决我的问题.而我正在寻找的是一个通用的解决方案.

My question is similar to How to Make a Point Orbit a Line, 3D but the answer there didn't seem to solve my problem. And what I am looking for is a general solution.

作为记录,我正在尝试解决 OpenGL ES (Java/Android) 中的问题.

For the record I am trying to solve an issue in OpenGL ES (Java/Android).

我有一个圆,圆的中心有一个 3D 点、一个半径和一个 3D 矢量,指定了圆所在平面的法线.

I have a circle with a 3D point for its center, a radius, and a 3D vector specifying the normal to the plane the circle lies in.

我需要找到表示圆周上与旋转"X 轴(根据法向量旋转)成给定角度的点的 3D 点.

I need to find the 3D point representing the point on the circumference at a given angle from the 'rotated' X-axis (rotated according to the normal vector).

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

I already have an implementation in a Circle class of a member function, pointAt, which works under limited circumstances. Specifically, in my current implementation I assume the circle lies in the X-Y plane and return a point accordingly and then, since I know the circle is actually lying in the X-Z plane I simply swap the Y and Z values in the returned point and it works. However, this is not a general solution and that is what I am going to need.

当我尝试如何制作Point Orbit a Line, 3D,我得到的点离它们应该在的地方很远.

When I tried the algorithm given in How to Make a Point Orbit a Line, 3D, I got points pretty far removed from where they should have been.

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

So, how, can I calculate a point on the circumference of such a circle?

我想我的解释是不够的.我的假设是一个圆在 X-Y 平面中正常",在 Z 方向上的法向量为 (0, 0, 1) - 1.如果需要圆周上的一个点,该点定义为:

I guess my explanation wasn't sufficient. My assumption is that a circle is 'normally' in the X-Y plane with a normal vector of (0, 0, 1) - 1 in the Z direction. If a point on the circumference is needed the point is defined by:

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

其中 R 是半径,CxCyXY圆心坐标,a是一个向量通过圆心点并与X轴平行的角度.

where R is the radius, Cx and Cy are the X and Y coordinates of the center of the circle, and a is the angle from a vector through the circle's center point and parallel with the X-axis.

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

Now, if the circle doesn't have a normal vector pointing along the Z-axis but, instead, is some arbitrary (x, y, z) vector, how do I find that same point?

推荐答案

您需要一个新的坐标系来放置圆.作为任何公共坐标系,我们希望基向量彼此正交,并且每个基向量的长度为 1.我将命名基向量 v1v2v3,它们依次对应于 x、y 和 z.

What you need is a new coordinate system to place the circle. As any common coordinate system, we'll want the base vectors to be orthogonal to each other, and have length 1 each. I'll name the base vectors v1, v2, and v3, which correspond to x, y, and z in order.

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

The new base vector that replaces z, which is v3 is given by the normal vector of the circle. If it's not normalized yet, you'll want to normalize it here:

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

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

Next, we'll chose v1. This can be an arbitrary vector that is orthogonal to v3. Since we want it to take the place of the x-axis, we can choose it to have an y-component of 0:

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

注意这个向量与v3的点积为0,这意味着这两个向量确实是正交的.如果圆的法向量正好指向 y 方向,则向量将退化.如果您在使用中遇到问题,我会让您弄清楚如何处理.

Note that the dot product of this vector with v3 is 0, which means that the two vectors are indeed orthogonal. The vector will be degenerate if the normal vector of the circle points exactly in the y-direction. I'll let you figure out how to handle that if it's a concern in your usage.

现在我们只需要最后一个向量,它可以计算为另外两个的叉积:

Now we just need the last vector, which can be calculated as the cross product of the other two:

v2 = v3 x v1

由于 v1v3 已经标准化并且是正交的,所以这已经标准化了.

This will already be normalized since v1 and v3 were normalized, and are orthogonal.

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

With this new basis, points on the circle can now be calculated as:

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

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

Putting the whole thing closer to code form (untested):

// 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))

这篇关于具有中心、半径和法向量的圆圆周上的 3d 点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆