English 中文(简体)
校验点是否在 3D 空间的锥体内
原标题:Verify if point is inside a cone in 3D space

考虑:

  • X(x1,y1,z1) the point I need to verify if it is inside a cone.
  • M(x2,y2,z2) the vertex of the cone. (the top point of the cone)
  • N(x3,y3,z3) the point in the middle of the cone s base.

我发现,如果一个点X在锥体上, 它需要验证这个方程式:

cos(alfa) * ||X-M|| * ||N|| = dot(X-M,N)

圆点是两个矢量的标量产物,而藻类是这两个矢量之间的角。

根据公式,我计算出:

X-M = (x1-x2,y1-y2,z1-z2)

那么,

cos(alfa)
  * Math.sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2)
  * Math.sqrt(x3^2 + y3^2+z3^2)
= x3(x1-x2) + y3(y1-y2) + z3(z1-z2)

不幸地,上述计算似乎给了我错误的结果。 我做错什么了?

我还怀疑,要检查 X 是否在锥体内,我就必须在公式中加上 ,而不是。这是否正确?

其用法是: 我开发了一个游戏, 当一个物体在它的视野中时, 机关枪必须开始射击 。 这个视图将是一个锥体 。 锥体的顶点在机关枪中, 锥体的底部在前面的某个已知距离。 进入这个锥体的任何物体, 机关枪都会射中它 。

最佳回答

我完全同意蒂姆的观点:我们需要锥形的“缠绕”(aperture)才能得到答案。

让我们来做一些编码!Ill use some telements from

给付结果函数 :

/**
 * @param x coordinates of point to be tested 
 * @param t coordinates of apex point of cone
 * @param b coordinates of center of basement circle
 * @param aperture in radians
 */
static public boolean isLyingInCone(float[] x, float[] t, float[] b, 
                                    float aperture){

    // This is for our convenience
    float halfAperture = aperture/2.f;

    // Vector pointing to X point from apex
    float[] apexToXVect = dif(t,x);

    // Vector pointing from apex to circle-center point.
    float[] axisVect = dif(t,b);

    // X is lying in cone only if it s lying in 
    // infinite version of its cone -- that is, 
    // not limited by "round basement".
    // We ll use dotProd() to 
    // determine angle between apexToXVect and axis.
    boolean isInInfiniteCone = dotProd(apexToXVect,axisVect)
                               /magn(apexToXVect)/magn(axisVect)
                                 >
                               // We can safely compare cos() of angles 
                               // between vectors instead of bare angles.
                               Math.cos(halfAperture);


    if(!isInInfiniteCone) return false;

    // X is contained in cone only if projection of apexToXVect to axis
    // is shorter than axis. 
    // We ll use dotProd() to figure projection length.
    boolean isUnderRoundCap = dotProd(apexToXVect,axisVect)
                              /magn(axisVect)
                                <
                              magn(axisVect);
    return isUnderRoundCap;
}

以下是我快速执行基本功能的情况,这是上代号为操纵矢量而要求的。

static public float dotProd(float[] a, float[] b){
    return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
}

static public float[] dif(float[] a, float[] b){
    return (new float[]{
            a[0]-b[0],
            a[1]-b[1],
            a[2]-b[2]
    });
}

static public float magn(float[] a){
    return (float) (Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]));
}

玩得开心点!

问题回答

您需要检查区别矢量( X- M) 与中心矢量( N) 之间的角是否小于或等于锥体的角( 您在问题中未指明这一点) 。 这将告诉您位置矢量( X) 是否在无限锥体中, 然后您也可以检查距离( 如果您想要的话) 。 因此,

float theta = PI/6; //half angle of cone
if (acos(dot(X-M, N)/(norm(X-M)*norm(N)) <= theta) doSomething();

对于性能,您也可以将 N 身份正常化( 将其转换为长度为 1 的矢量), 并单独存储长度 。 您可以将 < code> norm( X- M) 与长度比较, 给您一个圆底锥形( 我确定它存在一个名称, 但我不知道它的存在 ) 。

编辑 : 忘记逆余弦, 圆点产品等于 norm( U) *norm( V) *cos (Angle) , 所以我们必须颠倒此操作来比较角度。 在此情况下, acos 应该很好, 因为我们想要对正负角度进行同等比较, 但是要注意这一点 。

编辑:Radians。





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签