上的圆的圆周的3D点具有中心,半径和法向矢量圆周、半径、矢量、中心

2023-09-08 10:47:53 作者:头号可爱

我的问题是类似如何做出点轨道线路,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).

我有一个三维点为它的中心,一个半径的圆,和一个三维矢量指定垂直于平面的圆在于

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.

我需要找到3D点重新presenting圆周上的点以给定角度从'旋转的X轴(按照正常的向量旋转)。

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

我已经有一个类的成员函数的实现, pointAt ,这下有限的情况下工作。具体而言,在我目前的执行情况我假设圈出在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.

当我尝试在如何制作点轨道线路,3D ,我被点pretty的不远的地方,他们应该已被删除。

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?

我想我的解释是不够的。我的假设是,一个圆是正常的在XY平面为(0,0,1)的法线矢量 - 在Z方向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

其中,研究为半径, CX 赛扬 X 坐标圆心,而 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的每个。我将其命名为基矢量 V1 V2 V3 ,其对应于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轴的地方,我们可以选择它为0的y分量:

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

这将已经因为 V1 V3 是正常的,是正交的。

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)

把整个事情接近code表(未经测试):

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