Search code examples
math3dpseudocode

3D: Check point inside elliptical cone


I seem to have searched the whole internet trying to find an implementation of checking if a 3d point is within an elliptical cone defined by (origin, length, horizontal angle, vertical angle). Unfortunately without success as I only really found one math solution which I did not understand.

Now I am aware on how to use implement it using a normal cone:

inRange = magnitude(point - origin) <= length;
heading = normalized(point - origin);
return dot(forward, heading) >= cos(angle) && inRange;

However there the height detection is far too tall. I would really like to implement a more realistic vision cone for the AI for a game but this requires having the cone shaped more like a human field of view being more wide than tall.

Thanks a lot for any help:)


Solution

  • Given a 3D elliptic cone, with base at B=(x_B,y_B,z_B), height h along the cone axis k=(k_x,k_y,j_z), major base radius a, minor base radius b and direction along the major axis i=(i_x,i_y,i_z) you need to find if a point P=(x,y,z) lies inside the cone. It is your choice on how to parametrize the major axis direction and I think your are trying to use spherical coordinates with two angles.

    Here are the steps to take:

    1. Establish a coordinate system with origin on the base B and with the local x axis along your major axis i. The local z axis should be towards the tip along k. Finally the local y axis should be

      j=cross(k,i)=(i_z*k_y-i_y*k_z, i_x*k_z-i_z*k_x, i_y*k_x-i_x*k_y) j=normalize(j)

      Your 3×3 rotation matrix is defined by the columns E=[i,j,k]

    2. Transform your point P=(x,y,z) into the local coordinates with

      P2 = transpose(E)*(P-B) = (x2,y2,z2)

    3. Now establish how far along the axis of the cone is with s=(h-z2)/h where s=0 at the tip and s=1 at the base.

    4. If s>1 or s<0 then the point is outside

    5. Otherwise if s>0 you need to check that (x2/(s*a))^2+(y2/(s*b))^2<=1 for the point to be inside.

    6. If s=0 then check that x2=0 and y2=0 for the point being exactly at the tip.

    If you cannot do basic vector algebra, like cross products, 3D transformations and normalization that I suggest you have some reading to do before you can understand what is going on here.

    Note:

    //                  | i_x i_y i_z |
    //  transpose(E) =  | j_x j_y j_z |
    //                  | k_x k_y k_z |