What are the formulas to define the camera's view cone?
After a couple of quick experiments I determined that for a square camera the following coordinates (expressed in the camera's local coordinate system) would appear in the corners of the image:

x = y = sensor_width/lens /2
[±x, ±y, -1]


For a rectangular image, whichever dimension is larger becomes sensor_width/lens/2, and the smaller dimension is proportionally adjusted.

To define the half-planes in the camera's coordinate system, it's enough to calculate the cross products of the vectors pointing at the vertices of each edge, so

lr = [ x,-y,-1]
ur = [ x, y,-1]
ll = [-x,-y,-1]
ul = [-x, y,-1]
n1 = | lr × ll |
n2 = | ll × ul |
n3 = | ul × ur |
n4 = | ur × lr |


We normalize the vectors to length 1 so that we can use them in distance calculations later on.

When you want to determine if a particular coordinate c is in the camera's view cone convert it to camera local coordinates using

M = cam.matrix_world.inverted()
c2 = M c


Now that we have c2 (in the camera's coordinate system) we can compute the dot product between it and the various half-plane normals.

zi = ni ∙ c2


If all those zis are >=0 then the point is in the camera's view cone.  If the original coordinate is for an object, it's useful to incorporate a fudge factor like the radius of the object's bounding sphere (centered on the coordinate) and make sure that zi >= -fudge .

And this is the python class based on all that math:

class CameraCone:

    def __init__(self, matrix, sensor_width, lens, resolution_x, resolution_y):
        self.matrix = matrix.inverted()
        self.sensor_width = sensor_width
        self.lens = lens

        w = 0.5* sensor_width / lens
        if resolution_x&gt; resolution_y:
            x = w
            y = w*resolution_y/resolution_x
        else:
            x = w*resolution_x/resolution_y
            y = w

        lr = Vector([x,-y,-1])
        ur = Vector([x,y,-1])
        ll = Vector([-x,-y,-1])
        ul = Vector([-x,y,-1])
        self.half_plane_normals = [
            lr.cross(ll).normalized(),
            ll.cross(ul).normalized(),
            ul.cross(ur).normalized(),
            ur.cross(lr).normalized()
        ]

    def from_camera(cam, scn):
        return CameraCone(cam.matrix_world, cam.data.sensor_width, cam.data.lens, scn.render.resolution_x, scn.render.resolution_y)

    def isVisible(self, loc, fudge=0):

        loc2 = self.matrix * loc

        for norm in self.half_plane_normals:
            z2 = loc2.dot(norm)
            if z2 &lt; -fudge:
                return False

        return True