// Input argument: the center of the projection
        public GnomonicProjection(Dictionary <String, double> parameters)
            : base(parameters)
        {
            _center = SpatialUtil.SphericalRadToCartesian(InputLatitude("latitude1", 90), InputLongitude("longitude1", 360));

            // This projection is designed for numerical computations rather than cartography.
            // The choice of coordinate basis for the tangent plane - which affects the
            // orientation of the projection in the xy plane - is optimized for accuracy rather
            // than good looks. The first basis vector is obtained by dropping the smallest coordinate,
            // switching the other two, and flipping the sign of one of them. The second one is
            // obtained by cross product.

            double[] center = { _center.X, _center.Y, _center.Z };
            var      vector = new double[3];

            var k = GetMinEntry(center);
            var j = (k + 2) % 3;
            var i = (j + 2) % 3;

            vector[i] = -center[j];
            vector[j] = center[i];
            vector[k] = 0;

            _xAxis = new Vector3(vector[0], vector[1], vector[2]).Unitize();

            _yAxis = _center.CrossProduct(_xAxis);
        }
        protected internal override void Unproject(double x, double y, out double latitude, out double longitude)
        {
            var vector = _center + _xAxis * x + _yAxis * y;

            latitude  = SpatialUtil.Latitude(vector);
            longitude = SpatialUtil.Longitude(vector);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Calculates the offset distance.
        /// </summary>
        /// <param name="offset">The offset.</param>
        /// <param name="offsetBearing"></param>
        /// <param name="offsetAngle"></param>
        private static double CalculateOffsetDistance(double offset, double offsetBearing, double offsetAngle)
        {
            // offset / (SIN(RADIANS(((OffsetBearing - OffsetAngleLeft) + 360) % 360)))
            var denominator = (Math.Sin(SpatialUtil.ToRadians(((offsetBearing - offsetAngle) + 360) % 360)));

            return(offset / denominator);
        }
Ejemplo n.º 4
0
 public static double InputLong(double longDeg, double max, string name)
 {
     if (double.IsNaN(longDeg) || longDeg < -max || longDeg > max)
     {
         throw new ArgumentOutOfRangeException(nameof(longDeg), string.Format(CultureInfo.InvariantCulture, Resource.InputLongitudeIsOutOfRange, longDeg, max));
     }
     return(NormalizeLongitudeRad(SpatialUtil.ToRadians(longDeg)));
 }
Ejemplo n.º 5
0
 public static double InputLat(double latDeg, double max, string name)
 {
     if (double.IsNaN(latDeg) || latDeg < -max || latDeg > max)
     {
         throw new ArgumentOutOfRangeException(name, string.Format(CultureInfo.InvariantCulture, Resource.InputLatitudeIsOutOfRange, latDeg, max));
     }
     return(Clamp(Math.PI / 2, SpatialUtil.ToRadians(latDeg)));
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets the second point radian.
        /// </summary>
        /// <param name="nextPoint">The next point.</param>
        /// <param name="middlePoint">The middle point.</param>
        /// <returns></returns>
        private double GetSecondPointRadian(LRSPoint nextPoint, LRSPoint middlePoint)
        {
            var atan = GetAtanInDegree(middlePoint, nextPoint);

            atan = 90 - atan;
            atan = atan <= 0 ? 360 + atan : atan;

            return(SpatialUtil.ToRadians(180 - atan));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Gets the first point radian.
        /// </summary>
        /// <param name="previousPoint">The previous point.</param>
        /// <param name="middlePoint">The middle point.</param>
        /// <returns></returns>
        private double GetFirstPointRadian(LRSPoint previousPoint, LRSPoint middlePoint)
        {
            var atan = GetAtanInDegree(middlePoint, previousPoint);

            atan = 90 - atan;
            atan = atan <= 0 ? 360 + atan : atan;

            return(SpatialUtil.ToRadians(360 - atan));
        }
        public static AffineTransform Rotate(double angleDeg)
        {
            var angle     = SpatialUtil.ToRadians(angleDeg);
            var transform = new AffineTransform {
                _ax = Math.Cos(angle), _ay = Math.Sin(angle)
            };

            transform._bx = -transform._ay;
            transform._by = transform._ax;
            return(transform);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Gets the parallel point.
        /// </summary>
        /// <returns>Point parallel to the current point.</returns>
        private LRSPoint GetParallelPoint()
        {
            var newX = X + (OffsetDistance * Math.Cos(SpatialUtil.ToRadians(90 - _offsetAngle)));
            var newY = Y + (OffsetDistance * Math.Sin(SpatialUtil.ToRadians(90 - _offsetAngle)));

            return(new LRSPoint(
                       newX,
                       newY,
                       null,
                       M,
                       _srid
                       ));
        }
        public void AddLine(double latitude, double longitude, double?z, double?m)
        {
            // Transforming from geodetic coordinates to a unit vector.
            var endPoint = SpatialUtil.SphericalDegToCartesian(latitude, longitude);

            var angle = endPoint.Angle(_startPoint);

            if (angle > MinAngle)
            {
                // _startPoint and endPoint are the unit vectors that correspond to the input
                // start and end points.  In their 3D space we operate in a local coordinate system
                // where _startPoint is the x axis and the xy plane contains endPoint. Every
                // point is now generated from the previous one by a fixed rotation in the local
                // xy plane, and converted back to geodetic coordinates.

                // Construct the local z and y axes.
                var zAxis = (_startPoint + endPoint).CrossProduct(_startPoint - endPoint).Unitize();
                var yAxis = (_startPoint).CrossProduct(zAxis);

                // Calculating how many points we need.
                var count = Convert.ToInt32(Math.Ceiling(angle / SpatialUtil.ToRadians(_angle)));

                // Scaling the angle so that points are equally placed.
                var exactAngle = angle / count;

                var cosine = Math.Cos(exactAngle);
                var sine   = Math.Sin(exactAngle);

                // Setting the first x and y points in our local coordinate system.
                var x = cosine;
                var y = sine;

                for (var i = 0; i < count - 1; i++)
                {
                    var newPoint = (_startPoint * x + yAxis * y).Unitize();

                    // Adding the point.
                    _sink.AddLine(SpatialUtil.LatitudeDeg(newPoint), SpatialUtil.LongitudeDeg(newPoint), null, null);

                    // Rotating to get next point.
                    var r = x * cosine - y * sine;
                    y = x * sine + y * cosine;
                    x = r;
                }
            }
            _sink.AddLine(latitude, longitude, z, m);

            // Remembering last point we added.
            _startPoint = endPoint;
        }
        protected internal override void Project(double latitude, double longitude, out double x, out double y)
        {
            var vector = SpatialUtil.SphericalRadToCartesian(latitude, longitude);
            var r      = vector * _center;

            if (r < _tolerance)
            {
                throw new ArgumentOutOfRangeException(nameof(latitude), "Input point is too far away from the center of projection.");
            }
            vector = vector / r;

            x = vector * _xAxis;
            y = vector * _yAxis;
        }
Ejemplo n.º 12
0
 private static GameEffectWorldMethod CreateMethod_SpawnMinionThrow(string actorDefId, int level, float range, float amount)
 {
     return(delegate(EffectContext context)
     {
         Actor sourceActor = context.sourceActor;
         WeaponBody sourceWeapon = context.sourceWeapon;
         if (!LazySingletonBehavior <NetworkManager> .Instance.IsSimulationServer)
         {
             return;
         }
         SpawnMinions spawnMinions = sourceWeapon as SpawnMinions;
         for (int i = 0; i < (int)amount; i++)
         {
             Vector3 zero = Vector3.zero;
             Quaternion rotation = sourceActor.Rotation;
             if (!SpatialUtil.TryFindRandomSpotCircle(context.hitPoint, context.Radius, range, sourceActor.Height, out zero))
             {
                 Debug.Log("Couln't find valid spawn spot");
             }
             else
             {
                 LazySingletonBehavior <ActorManager> .Instance.Spawn(actorDefId, level, Actor.Faction.Player, /*context.hitPoint*/ zero, /*context.hitRot*/ rotation, delegate(Actor actor)
                 {
                     if (spawnMinions != null && spawnMinions.minionPrefab != null)
                     {
                         GameObject gameObject = spawnMinions.minionPrefab.Spawn(actor.transform);
                         Minion component = gameObject.GetComponent <Minion>();
                         if (component != null)
                         {
                             spawnMinions.AttachMinion(component);
                         }
                     }
                     Debug.Log(string.Concat(new object[]
                     {
                         "Spawned ",
                         actor.DebugName,
                         " at ",
                         actor.transform.position
                     }), actor);
                 });
             }
         }
     });
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Gets the deviation angle of 3 points.
        /// </summary>
        /// <param name="pointA">The point a.</param>
        /// <param name="pointO">The point o.</param>
        /// <param name="pointB">The point b.</param>
        /// <param name="isNegativeOffset">if set to <c>true</c> [is negative offset].</param>
        /// <returns></returns>
        private double GetAOBAngle(LRSPoint pointA, LRSPoint pointO, LRSPoint pointB, bool isNegativeOffset)
        {
            const double angleCorrection = Math.PI / 2;
            const double angleConversion = 2 * Math.PI;

            var atanAo = pointA.GetAtanInRadian(pointO) + angleCorrection;
            var atanBo = pointB.GetAtanInRadian(pointO) + angleCorrection;

            // angle conversion
            atanAo = SpatialUtil.ToDegrees(atanAo <= 0 ? angleConversion + atanAo : atanAo);
            atanBo = SpatialUtil.ToDegrees(atanBo <= 0 ? angleConversion + atanBo : atanBo);

            var deviationAngle =
                360 - (atanAo > atanBo
                    ? 360 - (atanAo - atanBo)
                    : atanBo - atanAo);

            // for positive offset; offset curve will be to the left of input geom;
            // so for positive deviation angle the computed angle should be subtracted from 360
            // for negative offset; offset curve will be to the right of input geom
            return(isNegativeOffset ? deviationAngle : 360 - deviationAngle);
        }
Ejemplo n.º 14
0
 // Angle in degrees between vectors a and b.
 public double AngleInDegrees(Vector3 a)
 {
     return(SpatialUtil.ToDegrees(Angle(a)));
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Gets the atan2 in degrees.
        /// This does angle correct when atan2 value is negative
        /// </summary>
        /// <param name="point1">The point1.</param>
        /// <param name="point2">The point2.</param>
        /// <returns>Atan2 in degrees</returns>
        private double GetAtanInDegree(LRSPoint point1, LRSPoint point2)
        {
            var atan = point1.GetAtanInRadian(point2);

            return(SpatialUtil.ToDegrees(atan <= 0 ? (2 * Math.PI) + atan : atan));
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Find the point that is the given distance from the start point in the direction of the end point.
        /// The distance must be less than the distance between these two points.
        /// </summary>
        /// <param name="start">Start Geography Point</param>
        /// <param name="end">End Geography Point</param>
        /// <param name="distance">Distance at which the point to be located</param>
        /// <returns></returns>
        public static SqlGeography InterpolateBetweenGeog(SqlGeography start, SqlGeography end, double distance)
        {
            // We need to check a few prerequisite.
            // We only operate on points.
            if (!start.IsPoint() || !end.IsPoint())
            {
                throw new ArgumentException(ErrorMessage.PointCompatible);
            }

            // The SRIDs also have to match
            var srid = start.STSrid.Value;

            if (srid != end.STSrid.Value)
            {
                throw new ArgumentException(ErrorMessage.SRIDCompatible);
            }

            // Finally, the distance has to fall between these points.
            var length = start.STDistance(end).Value;

            if (distance > length)
            {
                throw new ArgumentException(ErrorMessage.DistanceMustBeBetweenTwoPoints);
            }

            if (distance < 0)
            {
                throw new ArgumentException(ErrorMessage.DistanceMustBePositive);
            }

            // We'll just do this by binary search---surely this could be more efficient,
            // but this is relatively easy.
            //
            // Note that we can't just take the take the linear combination of end vectors because we
            // aren't working on a sphere.

            // We are going to do our binary search using 3D Cartesian values, however
            var startCart = SpatialUtil.GeographicToCartesian(start);
            var endCart   = SpatialUtil.GeographicToCartesian(end);

            SqlGeography current;
            double       currentDistance;

            // Keep refining until we slip below the THRESHOLD value.
            do
            {
                var currentCart = (startCart + endCart) / 2;
                current         = SpatialUtil.CartesianToGeographic(currentCart, srid);
                currentDistance = start.STDistance(current).Value;

                if (distance <= currentDistance)
                {
                    endCart = currentCart;
                }
                else
                {
                    startCart = currentCart;
                }
            } while (Math.Abs(currentDistance - distance) > Constants.Tolerance);

            return(current);
        }
 public void BeginFigure(double latitude, double longitude, double?z, double?m)
 {
     // Starting the figure, remembering the vector that corresponds to the first point.
     _startPoint = SpatialUtil.SphericalDegToCartesian(latitude, longitude);
     _sink.BeginFigure(latitude, longitude, z, m);
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Calculates the offset bearing.
 /// </summary>
 /// <param name="nextPoint">The next point.</param>
 private double CalculateOffsetBearing(LRSPoint nextPoint)
 {
     _angle = SpatialUtil.ToDegrees(GetAtanInRadian(nextPoint));
     return((90 - _angle + 360) % 360);
 }