Example #1
0
 /// <summary>
 ///     Determines whether this <see cref="FarRectangle"/> contains the specified <see cref="FarPosition"/>.
 /// </summary>
 /// <param name="value">
 ///     The <see cref="FarPosition"/> to evaluate.
 /// </param>
 /// <param name="result">
 ///     On exit, is true if this <see cref="FarRectangle"/> entirely contains the specified
 ///     <see cref="FarPosition"/>, or false if not.
 /// </param>
 public void Contains(ref FarPosition value, out bool result)
 {
     result = X <= value.X &&
              value.X < (X + Width) &&
              Y <= value.Y &&
              value.Y < (Y + Height);
 }
Example #2
0
 /// <summary>
 ///     Determines whether this <see cref="FarRectangle"/> contains the specified <see cref="FarPosition"/>.
 /// </summary>
 /// <param name="value">
 ///     The <see cref="FarPosition"/> to evaluate.
 /// </param>
 /// <returns>
 ///     <c>true</c> if the rectangle contains the specified value; otherwise, <c>false</c>.
 /// </returns>
 public bool Contains(FarPosition value)
 {
     return(X <= value.X &&
            value.X < (X + Width) &&
            Y <= value.Y &&
            value.Y < (Y + Height));
 }
Example #3
0
        /// <summary>Clamps the specified value between the specified minimum and maximum.</summary>
        /// <param name="value">The value to clamp.</param>
        /// <param name="min">The minimum of the interval to clamp to.</param>
        /// <param name="max">The maximum of the interval to clamp to.</param>
        /// <returns>The clamped value.</returns>
        public static FarPosition Clamp(FarPosition value, FarPosition min, FarPosition max)
        {
            FarPosition result;

            FarValue.Clamp(ref value.X, ref min.X, ref max.X, out result.X);
            FarValue.Clamp(ref value.Y, ref min.Y, ref max.Y, out result.Y);
            return(result);
        }
Example #4
0
        /// <summary>Returns the component-wise maximum of the two specified values.</summary>
        /// <param name="value1">The first value.</param>
        /// <param name="value2">The second value.</param>
        /// <returns>The component-wise maximum.</returns>
        public static FarPosition Max(FarPosition value1, FarPosition value2)
        {
            FarPosition result;

            result.X = (value1.X > value2.X) ? value1.X : value2.X;
            result.Y = (value1.Y > value2.Y) ? value1.Y : value2.Y;
            return(result);
        }
Example #5
0
        /// <summary>Transforms the specified position by the specified matrix.</summary>
        /// <param name="position">The position to transform.</param>
        /// <param name="transform">The transformation to apply.</param>
        /// <returns>The result of the transformation.</returns>
        public static FarPosition Transform(FarPosition position, Matrix transform)
        {
            FarPosition result;

            result.X = position.X * transform.M11 + position.Y * transform.M21 + transform.M41;
            result.Y = position.X * transform.M12 + position.Y * transform.M22 + transform.M42;
            return(result);
        }
Example #6
0
        /// <summary>
        ///     Performs a <see href="https://en.wikipedia.org/wiki/Smoothstep"/>
        ///     interpolation between the specified values.
        /// </summary>
        /// <param name="value1">The value to interpolate from.</param>
        /// <param name="value2">The value to interpolate towards.</param>
        /// <param name="amount">The amount to interpolate.</param>
        /// <returns>The interpolated value.</returns>
        public static FarPosition SmoothStep(FarPosition value1, FarPosition value2, float amount)
        {
            FarPosition result;

            FarValue.SmoothStep(ref value1.X, ref value2.X, amount, out result.X);
            FarValue.SmoothStep(ref value1.Y, ref value2.Y, amount, out result.Y);
            return(result);
        }
Example #7
0
        /// <summary>Advance the sweep forward, yielding a new initial state.</summary>
        /// <param name="alpha">the new initial time</param>
        public void Advance(float alpha)
        {
            System.Diagnostics.Debug.Assert(Alpha0 < 1.0f);

            var beta = (alpha - Alpha0) / (1.0f - Alpha0);

            CenterOfMass0 = (1.0f - beta) * CenterOfMass0 + beta * CenterOfMass;
            Angle0        = (1.0f - beta) * Angle0 + beta * Angle;
            Alpha0        = alpha;
        }
Example #8
0
        /// <summary>
        ///     Computes the dot product of the specified <see cref="FarPosition"/> and <see cref="Vector2"/>.
        /// </summary>
        /// <param name="value1">The first value.</param>
        /// <param name="value2">The second value.</param>
        /// <returns>The dot product.</returns>
        public static FarValue Dot(Vector2 value1, FarPosition value2)
        {
            return(value1.X * value2.X + value1.Y * value2.Y);

            // We could save two FarValue multiplications (one FarPosition multiplication),
            // but that would come at the cost of precision for positions primarily far
            // along a single axis:
            //  ax + by
            //= ax + bx + by - bx
            //= x(a + b) + b(y - x)
            //= (a + b)(x + b/(a + b)(y - x))
            //return (value1.X + value1.Y) * (value2.X + value1.Y / (value1.X + value1.Y) * (float)(value2.Y - value2.X));
        }
Example #9
0
        /// <summary>Transforms a global coordinate to a local one.</summary>
        /// <param name="v">The world coordinate to apply the inverse transform to.</param>
        /// <returns>The result of the inverse transform (a local coordinate).</returns>
        public Vector2 ToLocal(WorldPoint v)
        {
// ReSharper disable RedundantCast Necessary for FarPhysics.
            var px = (float)(v.X - Translation.X);
            var py = (float)(v.Y - Translation.Y);
// ReSharper restore RedundantCast

            Vector2 result;

            result.X = Rotation.Cos * px + Rotation.Sin * py;
            result.Y = -Rotation.Sin * px + Rotation.Cos * py;
            return(result);
        }
Example #10
0
        /// <summary>
        ///     Perform a line query on this index. This will return all entries in the index that are intersecting with the
        ///     specified query line.
        /// </summary>
        /// <param name="start">The start point.</param>
        /// <param name="end">The end point.</param>
        /// <param name="t">The fraction along the line to consider.</param>
        /// <param name="results">The list to put the results into.</param>
        /// <returns></returns>
        public void Find(TPoint start, TPoint end, float t, ISet <T> results)
        {
            foreach (var cell in ComputeCells(IntersectionExtensions.BoundsFor(start, end, t)))
            {
                if (_cells.ContainsKey(cell.Item1))
                {
                    // Convert the query to the tree's local coordinate space.
// ReSharper disable RedundantCast Necessary for FarCollections.
                    var relativeStart = (Vector2)(start + cell.Item2);
                    var relativeEnd   = (Vector2)(end + cell.Item2);
// ReSharper restore RedundantCast

                    // And do the query.
                    _cells[cell.Item1].Find(relativeStart, relativeEnd, t, results);
                }
            }
        }
Example #11
0
        /// <summary>
        ///     Perform a circular query on this index. This will return all entries in the index that are in the specified range
        ///     of the specified point, using the euclidean distance function (i.e. <c>sqrt(x*x+y*y)</c>).
        /// </summary>
        /// <param name="center">The query point near which to get entries.</param>
        /// <param name="radius">The maximum distance an entry may be away from the query point to be returned.</param>
        /// <param name="callback">The method to call for each found hit.</param>
        /// <returns></returns>
        /// <remarks>
        ///     This checks for intersections of the query circle and the bounds of the entries in the index. Intersections
        ///     (i.e. bounds not fully contained in the circle) will be returned, too.
        /// </remarks>
        public bool Find(TPoint center, float radius, SimpleQueryCallback <T> callback)
        {
            // Getting the full list and then iterating it seems to actually be faster
            // than injecting a delegate...

            /*
             *
             * // HashSet we might use for filtering duplicate results. We initialize it lazily.
             * HashSet<T> filter = null;
             *
             * // Compute the area bounds for that query to get the involved trees.
             * var queryBounds = IntersectionExtensions.BoundsFor(ref center, radius);
             * foreach (var cell in ComputeCells(queryBounds))
             * {
             *  // Only if the cell exists.
             *  if (_entries.ContainsKey(cell.Item1))
             *  {
             *      // Convert the query to the tree's local coordinate space.
             *      var relativePoint = (Vector2)(center + cell.Item2);
             *
             *      // And do the query.
             *      if (!_entries[cell.Item1].Find(relativePoint, radius,
             *          value => !Filter(value, ref filter) || callback(value)))
             *      {
             *          return false;
             *      }
             *  }
             * }
             *
             * /*/

            ISet <T> results = new HashSet <T>();

            Find(center, radius, results);
            foreach (var result in results)
            {
                if (!callback(result))
                {
                    return(false);
                }
            }

            //*/

            return(true);
        }
Example #12
0
        /// <summary>
        ///     Perform a circular query on this index. This will return all entries in the index that are in the specified range
        ///     of the specified point, using the euclidean distance function (i.e. <c>sqrt(x*x+y*y)</c>).
        /// </summary>
        /// <param name="center">The query point near which to get entries.</param>
        /// <param name="radius">The maximum distance an entry may be away from the query point to be returned.</param>
        /// <param name="results"> </param>
        /// <remarks>
        ///     This checks for intersections of the query circle and the bounds of the entries in the index. Intersections
        ///     (i.e. bounds not fully contained in the circle) will be returned, too.
        /// </remarks>
        public void Find(TPoint center, float radius, ISet <T> results)
        {
            // Compute the area bounds for that query to get the involved trees.
            var queryBounds = IntersectionExtensions.BoundsFor(center, radius);

            foreach (var cell in ComputeCells(queryBounds))
            {
                // Only if the cell exists.
                if (_cells.ContainsKey(cell.Item1))
                {
                    // Convert the query to the tree's local coordinate space.
// ReSharper disable RedundantCast Necessary for FarCollections.
                    var relativePoint = (Vector2)(center + cell.Item2);
// ReSharper restore RedundantCast

                    // And do the query.
                    _cells[cell.Item1].Find(relativePoint, radius, results);
                }
            }
        }
Example #13
0
        /// <summary>
        ///     Perform a line query on this index. This will return all entries in the index that are intersecting with the
        ///     specified query line.
        ///     <para>
        ///         Note that the callback will be passed the fraction along the line that the hit occurred at, and may return
        ///         the new maximum fraction up to which the search will run. If the returned fraction is exactly zero the search
        ///         will be stopped. If the returned fraction is negative the hit will be ignored, that is the max fraction will
        ///         not change.
        ///     </para>
        /// </summary>
        /// <param name="start">The start of the line.</param>
        /// <param name="end">The end of the line.</param>
        /// <param name="t">The fraction along the line to consider.</param>
        /// <param name="callback">The method to call for each found hit.</param>
        /// <returns></returns>
        public bool Find(TPoint start, TPoint end, float t, LineQueryCallback <T> callback)
        {
            // HashSet we might use for filtering duplicate results. We initialize it lazily.
            HashSet <T> filter = null;

            foreach (var cell in ComputeCells(IntersectionExtensions.BoundsFor(start, end, t)))
            {
                if (_cells.ContainsKey(cell.Item1))
                {
                    // Convert the query to the tree's local coordinate space.
// ReSharper disable RedundantCast Necessary for FarCollections.
                    var relativeStart = (Vector2)(start + cell.Item2);
                    var relativeEnd   = (Vector2)(end + cell.Item2);
// ReSharper restore RedundantCast

                    // And do the query.
                    if (!_cells[cell.Item1].Find(
                            relativeStart,
                            relativeEnd,
                            t,
                            (value, fraction) =>
                    {
                        if (!Filter(value, ref filter))
                        {
                            return(-1f);
                        }
                        return(t = callback(value, fraction));
                    }))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #14
0
 /// <summary>Transforms the specified position by the specified matrix.</summary>
 /// <param name="position">The position to transform.</param>
 /// <param name="transform">The transformation to apply.</param>
 /// <param name="result">The result.</param>
 /// <returns>The result of the transformation.</returns>
 public static void Transform(ref FarPosition position, ref Matrix transform, out FarPosition result)
 {
     result.X = position.X * transform.M11 + position.Y * transform.M21 + transform.M41;
     result.Y = position.X * transform.M12 + position.Y * transform.M22 + transform.M42;
 }
Example #15
0
        /// <summary>Transforms the specified position by the specified matrix and translation.</summary>
        /// <param name="position">The position to transform.</param>
        /// <param name="transform">The transformation to apply.</param>
        /// <param name="result">The result of the transformation.</param>
        public static void Transform(ref FarPosition position, ref FarTransform transform, out FarPosition result)
        {
            var translatedPosition = position + transform.Translation;

            Transform(ref translatedPosition, ref transform.Matrix, out result);
        }
Example #16
0
 /// <summary>Transforms the specified position by the specified matrix and translation.</summary>
 /// <param name="position">The position to transform.</param>
 /// <param name="transform">The transformation to apply.</param>
 /// <returns>The result of the transformation.</returns>
 public static FarPosition Transform(FarPosition position, FarTransform transform)
 {
     return(Transform(position + transform.Translation, transform.Matrix));
 }
Example #17
0
 /// <summary>Calculates the distance between two points.</summary>
 /// <param name="value1">The first point.</param>
 /// <param name="value2">The second point.</param>
 /// <returns>The distance between the two points.</returns>
 public static float Distance(FarPosition value1, FarPosition value2)
 {
     return(((Vector2)(value2 - value1)).Length());
 }
Example #18
0
 /// <summary>
 ///     Performs a <see href="https://en.wikipedia.org/wiki/Smoothstep"/>
 ///     interpolation between the specified values.
 /// </summary>
 /// <param name="value1">The value to interpolate from.</param>
 /// <param name="value2">The value to interpolate towards.</param>
 /// <param name="amount">The amount to interpolate.</param>
 /// <param name="result">The interpolated value.</param>
 public static void SmoothStep(
     ref FarPosition value1, ref FarPosition value2, float amount, out FarPosition result)
 {
     FarValue.SmoothStep(ref value1.X, ref value2.X, amount, out result.X);
     FarValue.SmoothStep(ref value1.Y, ref value2.Y, amount, out result.Y);
 }
Example #19
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="FarTransform"/> struct.
 /// </summary>
 /// <param name="translation">The initial translation.</param>
 /// <param name="matrix">The initial matrix.</param>
 public FarTransform(FarPosition translation, Matrix matrix)
 {
     Translation = translation;
     Matrix      = matrix;
 }
Example #20
0
 /// <summary>
 ///     Changes the position of the <see cref="FarRectangle"/>.
 /// </summary>
 /// <param name="amount">
 ///     The value to adjust the position of the <see cref="FarRectangle"/> by.
 /// </param>
 public void Offset(FarPosition amount)
 {
     X += amount.X;
     Y += amount.Y;
 }
Example #21
0
 /// <summary>Writes the specified rectangle value.</summary>
 /// <param name="packet">The packet to write to.</param>
 /// <param name="data">The value to write.</param>
 /// <returns>This packet, for call chaining.</returns>
 public static IWritablePacket Write(this IWritablePacket packet, FarPosition data)
 {
     return(packet.Write(data.X).Write(data.Y));
 }
Example #22
0
 /// <summary>
 ///     Computes the dot product of the specified <see cref="FarPosition"/> and <see cref="Vector2"/>.
 /// </summary>
 /// <param name="value1">The first value.</param>
 /// <param name="value2">The second value.</param>
 /// <returns>The dot product.</returns>
 public static FarValue Dot(FarPosition value1, Vector2 value2)
 {
     return(Dot(value2, value1));
 }
Example #23
0
 /// <summary>Returns the component-wise maximum of the two specified values.</summary>
 /// <param name="value1">The first value.</param>
 /// <param name="value2">The second value.</param>
 /// <param name="result">The component-wise maximum.</param>
 public static void Max(ref FarPosition value1, ref FarPosition value2, out FarPosition result)
 {
     result.X = (value1.X > value2.X) ? value1.X : value2.X;
     result.Y = (value1.Y > value2.Y) ? value1.Y : value2.Y;
 }
Example #24
0
 /// <summary>
 ///     Compares two <see cref="FarPosition"/>s for equality.
 /// </summary>
 /// <param name="other">
 ///     The other <see cref="FarPosition"/>.
 /// </param>
 /// <returns>
 ///     <c>true</c> if the <see cref="FarPosition"/>s are equal; otherwise, <c>false</c>.
 /// </returns>
 public bool Equals(FarPosition other)
 {
     return(X == other.X && Y == other.Y);
 }
Example #25
0
 /// <summary>Calculates the squared distance between two points.</summary>
 /// <param name="value1">The first point.</param>
 /// <param name="value2">The second point.</param>
 /// <returns>The squared distance between the two points.</returns>
 public static float DistanceSquared(FarPosition value1, FarPosition value2)
 {
     return(((Vector2)(value1 - value2)).LengthSquared());
 }
Example #26
0
 /// <summary>Reads a far position value.</summary>
 /// <param name="packet">The packet to read from.</param>
 /// <param name="data">The read value.</param>
 /// <returns>This packet, for call chaining.</returns>
 /// <exception cref="PacketException">The packet has not enough available data for the read operation.</exception>
 public static IReadablePacket Read(this IReadablePacket packet, out FarPosition data)
 {
     data = packet.ReadFarPosition();
     return(packet);
 }
Example #27
0
 /// <summary>Clamps the specified value between the specified minimum and maximum.</summary>
 /// <param name="value">The value to clamp.</param>
 /// <param name="min">The minimum of the interval to clamp to.</param>
 /// <param name="max">The maximum of the interval to clamp to.</param>
 /// <param name="result">The clamped value.</param>
 public static void Clamp(
     ref FarPosition value, ref FarPosition min, ref FarPosition max, out FarPosition result)
 {
     FarValue.Clamp(ref value.X, ref min.X, ref max.X, out result.X);
     FarValue.Clamp(ref value.Y, ref min.Y, ref max.Y, out result.Y);
 }