<commit_before>/*global define*/
define([
        './BoundingSphere',
        './Cartesian3',
        './defaultValue',
        './defined',
        './defineProperties',
        './DeveloperError',
        './Rectangle'
    ], function(
        BoundingSphere,
        Cartesian3,
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Rectangle) {
    "use strict";

    /**
     * Determine whether or not other objects are visible or hidden behind the visible horizon defined by
     * an {@link Ellipsoid} and a camera position.  The ellipsoid is assumed to be located at the
     * origin of the coordinate system.  This class uses the algorithm described in the
     * {@link http://cesiumjs.org/2013/04/25/Horizon-culling/|Horizon Culling} blog post.
     *
     * @alias EllipsoidalOccluder
     *
     * @param {Ellipsoid} ellipsoid The ellipsoid to use as an occluder.
     * @param {Cartesian3} [cameraPosition] The coordinate of the viewer/camera.  If this parameter is not
     *        specified, {@link EllipsoidalOccluder#cameraPosition} must be called before
     *        testing visibility.
     *
     * @constructor
     *
     * @example
     * // Construct an ellipsoidal occluder with radii 1.0, 1.1, and 0.9.
     * var cameraPosition = new Cesium.Cartesian3(5.0, 6.0, 7.0);
     * var occluderEllipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9);
     * var occluder = new Cesium.EllipsoidalOccluder(occluderEllipsoid, cameraPosition);
     *
     * @private
     */
    var EllipsoidalOccluder = function(ellipsoid, cameraPosition) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(ellipsoid)) {
            throw new DeveloperError('ellipsoid is required.');
        }
        //>>includeEnd('debug');

        this._ellipsoid = ellipsoid;
        this._cameraPosition = new Cartesian3();
        this._cameraPositionInScaledSpace = new Cartesian3();
        this._distanceToLimbInScaledSpaceSquared = 0.0;

        // cameraPosition fills in the above values
        if (defined(cameraPosition)) {
            this.cameraPosition = cameraPosition;
        }
    };

    defineProperties(EllipsoidalOccluder.prototype, {
        /**
         * Gets the occluding ellipsoid.
         * @memberof EllipsoidalOccluder.prototype
         * @type {Ellipsoid}
         */
        ellipsoid : {
            get: function() {
                return this._ellipsoid;
            }
        },
        /**
         * Gets or sets the position of the camera.
         * @memberof EllipsoidalOccluder.prototype
         * @type {Cartesian3}
         */
        cameraPosition : {
            get : function() {
                return this._cameraPosition;
            },
            set : function(cameraPosition) {
                // See http://cesiumjs.org/2013/04/25/Horizon-culling/
                var ellipsoid = this._ellipsoid;
                var cv = ellipsoid.transformPositionToScaledSpace(cameraPosition, this._cameraPositionInScaledSpace);
                var vhMagnitudeSquared = Cartesian3.magnitudeSquared(cv) - 1.0;

                Cartesian3.clone(cameraPosition, this._cameraPosition);
                this._cameraPositionInScaledSpace = cv;
                this._distanceToLimbInScaledSpaceSquared = vhMagnitudeSquared;
            }
        }
    });

    var scratchCartesian = new Cartesian3();

    /**
     * Determines whether or not a point, the <code>occludee</code>, is hidden from view by the occluder.
     *
     * @param {Cartesian3} occludee The point to test for visibility.
     * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>.
     *
     * @example
     * var cameraPosition = new Cesium.Cartesian3(0, 0, 2.5);
     * var ellipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9);
     * var occluder = new Cesium.EllipsoidalOccluder(ellipsoid, cameraPosition);
     * var point = new Cesium.Cartesian3(0, -3, -3);
     * occluder.isPointVisible(point); //returns true
     */
    EllipsoidalOccluder.prototype.isPointVisible = function(occludee) {
        var ellipsoid = this._ellipsoid;
        var occludeeScaledSpacePosition = ellipsoid.transformPositionToScaledSpace(occludee, scratchCartesian);
        return this.isScaledSpacePointVisible(occludeeScaledSpacePosition);
    };

    /**
     * Determines whether or not a point expressed in the ellipsoid scaled space, is hidden from view by the
     * occluder.  To transform a Cartesian X, Y, Z position in the coordinate system aligned with the ellipsoid
     * into the scaled space, call {@link Ellipsoid#transformPositionToScaledSpace}.
     *
     * @param {Cartesian3} occludeeScaledSpacePosition The point to test for visibility, represented in the scaled space.
     * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>.
     *
     * @example
     * var cameraPosition = new Cesium.Cartesian3(0, 0, 2.5);
     * var ellipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9);
     * var occluder = new Cesium.EllipsoidalOccluder(ellipsoid, cameraPosition);
     * var point = new Cesium.Cartesian3(0, -3, -3);
     * var scaledSpacePoint = ellipsoid.transformPositionToScaledSpace(point);
     * occluder.isScaledSpacePointVisible(scaledSpacePoint); //returns true
     */
    EllipsoidalOccluder.prototype.isScaledSpacePointVisible = function(occludeeScaledSpacePosition) {
        // See http://cesiumjs.org/2013/04/25/Horizon-culling/
        var cv = this._cameraPositionInScaledSpace;
        var vhMagnitudeSquared = this._distanceToLimbInScaledSpaceSquared;
        var vt = Cartesian3.subtract(occludeeScaledSpacePosition, cv, scratchCartesian);
        var vtDotVc = -Cartesian3.dot(vt, cv);
        var isOccluded = vtDotVc > vhMagnitudeSquared &&
                         vtDotVc * vtDotVc / Cartesian3.magnitudeSquared(vt) > vhMagnitudeSquared;
        return !isOccluded;
    };

    /**
     * Computes a point that can be used for horizon culling from a list of positions.  If the point is below
     * the horizon, all of the positions are guaranteed to be below the horizon as well.  The returned point<commit_msg>Only use the ellipsoid as an occluder if the camera is above the surface of the ellipsoid.<commit_after>/*global define*/
define([
        './BoundingSphere',
        './Cartesian3',
        './defaultValue',
        './defined',
        './defineProperties',
        './DeveloperError',
        './Rectangle'
    ], function(
        BoundingSphere,
        Cartesian3,
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Rectangle) {
    "use strict";

    /**
     * Determine whether or not other objects are visible or hidden behind the visible horizon defined by
     * an {@link Ellipsoid} and a camera position.  The ellipsoid is assumed to be located at the
     * origin of the coordinate system.  This class uses the algorithm described in the
     * {@link http://cesiumjs.org/2013/04/25/Horizon-culling/|Horizon Culling} blog post.
     *
     * @alias EllipsoidalOccluder
     *
     * @param {Ellipsoid} ellipsoid The ellipsoid to use as an occluder.
     * @param {Cartesian3} [cameraPosition] The coordinate of the viewer/camera.  If this parameter is not
     *        specified, {@link EllipsoidalOccluder#cameraPosition} must be called before
     *        testing visibility.
     *
     * @constructor
     *
     * @example
     * // Construct an ellipsoidal occluder with radii 1.0, 1.1, and 0.9.
     * var cameraPosition = new Cesium.Cartesian3(5.0, 6.0, 7.0);
     * var occluderEllipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9);
     * var occluder = new Cesium.EllipsoidalOccluder(occluderEllipsoid, cameraPosition);
     *
     * @private
     */
    var EllipsoidalOccluder = function(ellipsoid, cameraPosition) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(ellipsoid)) {
            throw new DeveloperError('ellipsoid is required.');
        }
        //>>includeEnd('debug');

        this._ellipsoid = ellipsoid;
        this._cameraPosition = new Cartesian3();
        this._cameraPositionInScaledSpace = new Cartesian3();
        this._distanceToLimbInScaledSpaceSquared = 0.0;

        // cameraPosition fills in the above values
        if (defined(cameraPosition)) {
            this.cameraPosition = cameraPosition;
        }
    };

    defineProperties(EllipsoidalOccluder.prototype, {
        /**
         * Gets the occluding ellipsoid.
         * @memberof EllipsoidalOccluder.prototype
         * @type {Ellipsoid}
         */
        ellipsoid : {
            get: function() {
                return this._ellipsoid;
            }
        },
        /**
         * Gets or sets the position of the camera.
         * @memberof EllipsoidalOccluder.prototype
         * @type {Cartesian3}
         */
        cameraPosition : {
            get : function() {
                return this._cameraPosition;
            },
            set : function(cameraPosition) {
                // See http://cesiumjs.org/2013/04/25/Horizon-culling/
                var ellipsoid = this._ellipsoid;
                var cv = ellipsoid.transformPositionToScaledSpace(cameraPosition, this._cameraPositionInScaledSpace);
                var vhMagnitudeSquared = Cartesian3.magnitudeSquared(cv) - 1.0;

                Cartesian3.clone(cameraPosition, this._cameraPosition);
                this._cameraPositionInScaledSpace = cv;
                this._distanceToLimbInScaledSpaceSquared = vhMagnitudeSquared;
            }
        }
    });

    var scratchCartesian = new Cartesian3();

    /**
     * Determines whether or not a point, the <code>occludee</code>, is hidden from view by the occluder.
     *
     * @param {Cartesian3} occludee The point to test for visibility.
     * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>.
     *
     * @example
     * var cameraPosition = new Cesium.Cartesian3(0, 0, 2.5);
     * var ellipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9);
     * var occluder = new Cesium.EllipsoidalOccluder(ellipsoid, cameraPosition);
     * var point = new Cesium.Cartesian3(0, -3, -3);
     * occluder.isPointVisible(point); //returns true
     */
    EllipsoidalOccluder.prototype.isPointVisible = function(occludee) {
        var ellipsoid = this._ellipsoid;
        var occludeeScaledSpacePosition = ellipsoid.transformPositionToScaledSpace(occludee, scratchCartesian);
        return this.isScaledSpacePointVisible(occludeeScaledSpacePosition);
    };

    /**
     * Determines whether or not a point expressed in the ellipsoid scaled space, is hidden from view by the
     * occluder.  To transform a Cartesian X, Y, Z position in the coordinate system aligned with the ellipsoid
     * into the scaled space, call {@link Ellipsoid#transformPositionToScaledSpace}.
     *
     * @param {Cartesian3} occludeeScaledSpacePosition The point to test for visibility, represented in the scaled space.
     * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>.
     *
     * @example
     * var cameraPosition = new Cesium.Cartesian3(0, 0, 2.5);
     * var ellipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9);
     * var occluder = new Cesium.EllipsoidalOccluder(ellipsoid, cameraPosition);
     * var point = new Cesium.Cartesian3(0, -3, -3);
     * var scaledSpacePoint = ellipsoid.transformPositionToScaledSpace(point);
     * occluder.isScaledSpacePointVisible(scaledSpacePoint); //returns true
     */
    EllipsoidalOccluder.prototype.isScaledSpacePointVisible = function(occludeeScaledSpacePosition) {
        if (this._distanceToLimbInScaledSpaceSquared < 0.0) {
            return true;
        }

        // See http://cesiumjs.org/2013/04/25/Horizon-culling/
        var cv = this._cameraPositionInScaledSpace;
        var vhMagnitudeSquared = this._distanceToLimbInScaledSpaceSquared;
        var vt = Cartesian3.subtract(occludeeScaledSpacePosition, cv, scratchCartesian);
        var vtDotVc = -Cartesian3.dot(vt, cv);
        var isOccluded = vtDotVc > vhMagnitudeSquared &&
                         vtDotVc * vtDotVc / Cartesian3.magnitudeSquared(vt) > vhMagnitudeSquared;
        return !isOccluded;
    };

    /**
     * Computes a point that can be used for horizon culling from a list of positions.  If the point is below
     * the horizon, all of the positions are guaranteed to be below the horizon as well.  The returned point
{'fraction_non_alphanumeric': 0.09509764846552411, 'fraction_numerical': 0.014667198086887207, 'mean_word_length': 2.489847009735744, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7300258', 'n_tokens_mistral': 4003, 'n_tokens_neox': 3748, 'n_words': 938}