I completely agree with Tim: we need the "angle" (aperture) of the cone to get an answer.
Let's do some coding! I will use some terminology from here .
Result Creation Function:
/** * @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 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; }
Below are my quick implementations of the basic functions required by the top code for vector management.
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])); }
Good luck
source share