Given the parameters for a frustum returns a 4x4 perspective
    projection matrix 
    
    Parameters:
      float scale: 
      float znear,zfar: near/far plane z, float

    Return: a 4x4 perspective matrix
337003
def simple_clip_matrix(scale, znear, zfar, aspectratio=1.0):
    '''
    '''
    m = numpy.zeros((4,4))
    m[0,0] = scale/aspectratio
    m[1,1] = scale
    m[2,2] = (zfar + znear) / (znear - zfar)
    m[2,3] = 2*zfar*znear / (znear - zfar)
    m[3,2] = -1

    return m
1370210
public Matrix4 setToOrtho (
        double left, double right, double bottom, double top,
        double near, double far, IVector3 nearFarNormal) {
        double rlr = 1f / (left - right);
        double rbt = 1f / (bottom - top);
        double rnf = 1f / (near - far);
        double s = 2f / (near*nearFarNormal.z() - far*nearFarNormal.z());
        return set(-2f * rlr, 0f, 0f, (right + left) * rlr,
                   0f, -2f * rbt, 0f, (top + bottom) * rbt,
                   s * nearFarNormal.x(), s * nearFarNormal.y(), 2f * rnf, (far + near) * rnf,
                   0f, 0f, 0f, 1f);
    }
802745
private void ar2gvr(float[] poseMatrix, float scale) {
        // Real world scale
        Matrix.scaleM(poseMatrix, 0, scale, scale, scale);
        poseMatrix[12] = poseMatrix[12] * scale;
        poseMatrix[13] = poseMatrix[13] * scale;
        poseMatrix[14] = poseMatrix[14] * scale;
    }
329541
public Matrix4f scaleLocal(float xyz, Matrix4f dest) {
        return scaleLocal(xyz, xyz, xyz, dest);
    }
92389
public Matrix4f reflect(float nx, float ny, float nz, float px, float py, float pz, Matrix4f dest) {
        float invLength = 1.0f / (float) Math.sqrt(nx * nx + ny * ny + nz * nz);
        float nnx = nx * invLength;
        float nny = ny * invLength;
        float nnz = nz * invLength;
        /* See: http://mathworld.wolfram.com/Plane.html */
        return reflect(nnx, nny, nnz, -nnx * px - nny * py - nnz * pz, dest);
    }
25649
def _update_projection_matrix(self):
        """"""

        # replace gluPerspective (https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml)
        ff = 1./np.tan(np.radians(self.fov_y / 2.)) # cotangent(fovy/2)
        zn, zf = self.z_near, self.z_far

        persp_mat =  np.array([[ff/self.aspect,    0.,              0.,                 0.],
                              [             0.,    ff,              0.,                 0.],
                              [             0.,    0., (zf+zn)/(zn-zf), (2.*zf*zn)/(zn-zf)],
                              [             0.,    0.,             -1.,                 0.]], dtype=np.float32)

        self.projection_matrix[:] = np.dot(persp_mat, self._get_shift_matrix())
817448
public Matrix3f scale(float x, float y, float z, Matrix3f dest) {
        // scale matrix elements:
        // m00 = x, m11 = y, m22 = z
        // all others = 0
        dest.m00 = m00 * x;
        dest.m01 = m01 * x;
        dest.m02 = m02 * x;
        dest.m10 = m10 * y;
        dest.m11 = m11 * y;
        dest.m12 = m12 * y;
        dest.m20 = m20 * z;
        dest.m21 = m21 * z;
        dest.m22 = m22 * z;
        return dest;
    }
4339
public Matrix4 setToScale (IVector3 scale) {
        return setToScale(scale.x(), scale.y(), scale.z());
    }
431863
public Matrix4x3d mulOrtho(Matrix4x3dc view, Matrix4x3d dest) {
        double nm00 = m00 * view.m00();
        double nm01 = m11 * view.m01();
        double nm02 = m22 * view.m02();
        double nm10 = m00 * view.m10();
        double nm11 = m11 * view.m11();
        double nm12 = m22 * view.m12();
        double nm20 = m00 * view.m20();
        double nm21 = m11 * view.m21();
        double nm22 = m22 * view.m22();
        double nm30 = m00 * view.m30() + m30;
        double nm31 = m11 * view.m31() + m31;
        double nm32 = m22 * view.m32() + m32;
        dest.m00 = nm00;
        dest.m01 = nm01;
        dest.m02 = nm02;
        dest.m10 = nm10;
        dest.m11 = nm11;
        dest.m12 = nm12;
        dest.m20 = nm20;
        dest.m21 = nm21;
        dest.m22 = nm22;
        dest.m30 = nm30;
        dest.m31 = nm31;
        dest.m32 = nm32;
        dest.properties = 0;
        return dest;
    }
11171
def affine_mat(self)->AffineMatrix:
        ""
        if self._affine_mat is None:
            self._affine_mat = torch.eye(3).to(self.device)
        return self._affine_mat
365340
private void convertFromARtoVRSpace(float scale) {
        mPose.update(mARPlane.getCenterPose(), scale);
        getTransform().setModelMatrix(mPose.getPoseMatrix());
    }
883931
def get_matrix(self):
        
        # Init matrix (remember, a matrix, not an array)
        a = np.zeros((4, 4), dtype=np.float32)
        w, x, y, z = self.w, self.x, self.y, self.z
        # First row
        a[0, 0] = - 2.0 * (y * y + z * z) + 1.0
        a[1, 0] = + 2.0 * (x * y + z * w)
        a[2, 0] = + 2.0 * (x * z - y * w)
        a[3, 0] = 0.0
        # Second row
        a[0, 1] = + 2.0 * (x * y - z * w)
        a[1, 1] = - 2.0 * (x * x + z * z) + 1.0
        a[2, 1] = + 2.0 * (z * y + x * w)
        a[3, 1] = 0.0
        # Third row
        a[0, 2] = + 2.0 * (x * z + y * w)
        a[1, 2] = + 2.0 * (y * z - x * w)
        a[2, 2] = - 2.0 * (x * x + y * y) + 1.0
        a[3, 2] = 0.0
        # Fourth row
        a[0, 3] = 0.0
        a[1, 3] = 0.0
        a[2, 3] = 0.0
        a[3, 3] = 1.0
        return a
423320
function () {
        if (!this.height) { return; }

        var cameraToCenterDistance = 0.5 / Math.tan(FOV / 2) * this.height * WORLD_SCALE;
        // Convert to radian.
        var pitch = Math.max(Math.min(this.pitch, this.maxPitch), 0) / 180 * Math.PI;

        // Find the distance from the center point [width/2, height/2] to the
        // center top point [width/2, 0] in Z units, using the law of sines.
        // 1 Z unit is equivalent to 1 horizontal px at the center of the map
        // (the distance between[width/2, height/2] and [width/2 + 1, height/2])
        var halfFov = FOV / 2;
        var groundAngle = Math.PI / 2 + pitch;
        var topHalfSurfaceDistance = Math.sin(halfFov) * cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov);

        // Calculate z distance of the farthest fragment that should be rendered.
        var furthestDistance = Math.cos(Math.PI / 2 - pitch) * topHalfSurfaceDistance + cameraToCenterDistance;
        // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance`
        var farZ = furthestDistance * 1.1;
        // Forced to be 1000
        if (this.pitch > 50) {
            farZ = 1000;
        }

        // matrix for conversion from location to GL coordinates (-1 .. 1)
        var m = [];
        mat4.perspective(m, FOV, this.width / this.height, 1, farZ);
        this.viewGL.camera.projectionMatrix.setArray(m);
        this.viewGL.camera.decomposeProjectionMatrix();

        var m = mat4.identity([]);
        var pt = this.dataToPoint(this.center);
        // Inverse
        mat4.scale(m, m, [1, -1, 1]);
        // Translate to altitude
        mat4.translate(m, m, [0, 0, -cameraToCenterDistance]);
        mat4.rotateX(m, m, pitch);
        mat4.rotateZ(m, m, -this.bearing / 180 * Math.PI);
        // Translate to center.
        mat4.translate(m, m, [-pt[0] * this.getScale() * WORLD_SCALE, -pt[1] * this.getScale() * WORLD_SCALE, 0]);

        this.viewGL.camera.viewMatrix.array = m;
        var invertM = [];
        mat4.invert(invertM, m);
        this.viewGL.camera.worldTransform.array = invertM;
        this.viewGL.camera.decomposeWorldTransform();

        // scale vertically to meters per pixel (inverse of ground resolution):
        // worldSize / (circumferenceOfEarth * cos(lat * π / 180))
        var worldSize = TILE_SIZE * this.getScale();
        var verticalScale;

        if (this.altitudeExtent && !isNaN(this.boxHeight)) {
            var range = this.altitudeExtent[1] - this.altitudeExtent[0];
            verticalScale = this.boxHeight / range * this.getScale() / Math.pow(2, this._initialZoom - this.zoomOffset);
        }
        else {
            verticalScale = worldSize / (2 * Math.PI * 6378000 * Math.abs(Math.cos(this.center[1] * (Math.PI / 180))))
                * this.altitudeScale * WORLD_SCALE;
        }
        // Include scale to avoid relayout when zooming
        // FIXME Camera scale may have problem in shadow
        this.viewGL.rootNode.scale.set(
            this.getScale() * WORLD_SCALE, this.getScale() * WORLD_SCALE, verticalScale
        );
    }
1132669
def tiltFactor(self, midpointdepth=None,
                   printAvAngle=False):
        '''
        
        '''
        # TODO: can also be only def. with FOV, rot, tilt
        beta2 = self.viewAngle(midpointdepth=midpointdepth)
        try:
            angles, vals = getattr(
                emissivity_vs_angle, self.opts['material'])()
        except AttributeError:
            raise AttributeError("material[%s] is not in list of know materials: %s" % (
                self.opts['material'], [o[0] for o in getmembers(emissivity_vs_angle)
                                        if isfunction(o[1])]))
        if printAvAngle:
            avg_angle = beta2[self.foreground()].mean()
            print('angle: %s DEG' % np.degrees(avg_angle))

        # use averaged angle instead of beta2 to not overemphasize correction
        normEmissivity = np.clip(
            InterpolatedUnivariateSpline(
                np.radians(angles), vals)(beta2), 0, 1)
        return normEmissivity
287525
def _perspective_warp(c, magnitude:partial(uniform,size=8)=0, invert=False):
    ""
    magnitude = magnitude.view(4,2)
    targ_pts = [[x+m for x,m in zip(xs, ms)] for xs, ms in zip(_orig_pts, magnitude)]
    return _do_perspective_warp(c, targ_pts, invert)
338283
public double perspectiveFov() {
        /*
         * Compute the angle between the bottom and top frustum plane normals.
         */
        double n1x, n1y, n1z, n2x, n2y, n2z;
        n1x = m03 + m01; n1y = m13 + m11; n1z = m23 + m21; // bottom
        n2x = m01 - m03; n2y = m11 - m13; n2z = m21 - m23; // top
        double n1len = Math.sqrt(n1x * n1x + n1y * n1y + n1z * n1z);
        double n2len = Math.sqrt(n2x * n2x + n2y * n2y + n2z * n2z);
        return Math.acos((n1x * n2x + n1y * n2y + n1z * n2z) / (n1len * n2len));
    }
587615
public Matrix4x3f scale(Vector3fc xyz, Matrix4x3f dest) {
        return scale(xyz.x(), xyz.y(), xyz.z(), dest);
    }