Пример #1
0
        private float ComputeNoise(Vector2F position)
        {
            float t0  = position.X + N;
            int   bx0 = ((int)t0) & _maskB;
            int   bx1 = (bx0 + 1) & _maskB;
            float rx0 = t0 - (int)t0;
            float rx1 = rx0 - 1.0f;

            float t1  = position.Y + N;
            int   by0 = ((int)t1) & _maskB;
            int   by1 = (by0 + 1) & _maskB;
            float ry0 = t1 - (int)t1;
            float ry1 = ry0 - 1.0f;

            int b00 = _permutations[(_permutations[bx0] + by0) & _maskB];
            int b10 = _permutations[(_permutations[bx1] + by0) & _maskB];
            int b01 = _permutations[(_permutations[bx0] + by1) & _maskB];
            int b11 = _permutations[(_permutations[bx1] + by1) & _maskB];

            float sx = ComputeCubicSpline(rx0);

            float u = _magnitudes[b00] * Vector2F.Dot(_gradients[b00], new Vector2F(rx0, ry0));
            float v = _magnitudes[b10] * Vector2F.Dot(_gradients[b10], new Vector2F(rx1, ry0));
            float a = InterpolationHelper.Lerp(u, v, sx);

            u = _magnitudes[b01] * Vector2F.Dot(_gradients[b01], new Vector2F(rx0, ry1));
            v = _magnitudes[b11] * Vector2F.Dot(_gradients[b11], new Vector2F(rx1, ry1));
            float b = InterpolationHelper.Lerp(u, v, sx);

            float sy = ComputeCubicSpline(ry0);

            return(InterpolationHelper.Lerp(a, b, sy));
        }
Пример #2
0
        /// <summary>
        ///   Returns the squared distance of this segment to the passed point
        /// </summary>
        /// <param name="point"> Point which distance to the segment should be checked </param>
        /// <returns> Squared distance to the passed point </returns>
        public float GetSquareDistance(Vector2F point)
        {
            // Computing the closest point to get the distance is possible,
            // but not required
            // return (this.GetClosestPoint(point) - point).GetSquareMagnitude();
            Vector2F segmentVector = this.PointB - this.PointA;
            Vector2F startToPoint  = point - this.PointA;

            // Check if start point closest point
            float e = Vector2F.Dot(startToPoint, segmentVector);

            if (e <= 0.0f)
            {
                return(Vector2F.Dot(startToPoint, startToPoint));
            }

            // Check if end point closest point
            float squareLength = Vector2F.Dot(segmentVector, segmentVector);

            if (e >= squareLength)
            {
                Vector2F endToPoint = point - this.PointB;
                return(Vector2F.Dot(endToPoint, endToPoint));
            }

            // Handle cases where point projects onto segment
            return(Vector2F.Dot(startToPoint, startToPoint) - (e * e / squareLength));
        }
Пример #3
0
    /// <summary>
    /// Resolve the collision by calculating the resulting velocity, using the
    /// given normal and penetration, stored in the intersection.
    /// </summary>
    /// <param name="collision">Intersection instance containing all the collision data.</param>
    public void ApplyImpulse()
    {
        Vector2F dv = bodyB.Velocity - bodyA.Velocity;
        Fix32    vn = Vector2F.Dot(dv, normal);

        Fix32 imp = ((-((Fix32)1 + restitution) * vn + bias)) / totalInvMass;

        imp = Fix32.Max(imp, (Fix32)0);

        Vector2F impulse = normal * imp;

        bodyA.Velocity -= impulse * bodyA.InvMass;
        bodyB.Velocity += impulse * bodyB.InvMass;
    }
Пример #4
0
        public static Vector2F ClosestPointOnLineSegment(Vector2F point, Vector2F lineStart, Vector2F lineEnd)
        {
            Vector2F line    = lineEnd - lineStart;
            float    lineMag = line.X * line.X + line.Y * line.Y;

            if (lineMag == 0f)
            {
                return(lineStart);
            }

            float t = Vector2F.Dot(point - lineStart, line) / lineMag;

            t = Math.Min(Math.Max(0, t), 1);
            return(lineStart + line * t);
        }
Пример #5
0
        public static bool PointInRectangle(Vector2F point, float r1x, float r1y,
                                            float r2x, float r2y,
                                            float r3x, float r3y,
                                            float r4x, float r4y)
        {
            Vector2F corner      = new Vector2F(r1x, r1y);
            Vector2F local_point = point - corner;
            Vector2F side1       = new Vector2F(r2x, r2y) - corner;
            Vector2F side2       = new Vector2F(r4x, r4y) - corner;

            return(0 <= Vector2F.Dot(local_point, side1) &&
                   Vector2F.Dot(local_point, side1) <= Vector2F.Dot(side1, side1) &&
                   0 <= Vector2F.Dot(local_point, side2) &&
                   Vector2F.Dot(local_point, side2) <= Vector2F.Dot(side2, side2));
        }
Пример #6
0
        public void OrthogonalVectors()
        {
            Vector2F v          = Vector2F.UnitX;
            Vector2F orthogonal = v.Orthonormal;

            Assert.IsTrue(Numeric.IsZero(Vector2F.Dot(v, orthogonal)));

            v          = Vector2F.UnitY;
            orthogonal = v.Orthonormal;
            Assert.IsTrue(Numeric.IsZero(Vector2F.Dot(v, orthogonal)));

            v          = new Vector2F(23.0f, 44.0f);
            orthogonal = v.Orthonormal;
            Assert.IsTrue(Numeric.IsZero(Vector2F.Dot(v, orthogonal)));
        }
Пример #7
0
        public void MultiplyVector()
        {
            Vector2F v = new Vector2F(2.34f, 3.45f);

            Assert.AreEqual(v, Matrix22F.Multiply(Matrix22F.Identity, v));
            Assert.AreEqual(Vector2F.Zero, Matrix22F.Multiply(Matrix22F.Zero, v));

            Matrix22F m = new Matrix22F(12, 23, 45, 67);

            Assert.IsTrue(Vector2F.AreNumericallyEqual(v, Matrix22F.Multiply(m * m.Inverse, v)));

            for (int i = 0; i < 2; i++)
            {
                Assert.AreEqual(Vector2F.Dot(m.GetRow(i), v), Matrix22F.Multiply(m, v)[i]);
            }
        }
Пример #8
0
        /// <summary>
        /// Calculates the squared distance between a given point and a given ray.
        /// </summary>
        /// <param name="point">A <see cref="Vector2F"/> instance.</param>
        /// <param name="ray">A <see cref="Ray"/> instance.</param>
        /// <returns>The squared distance between the point and the ray.</returns>
        public static float SquaredDistance(Vector2F point, Ray ray)
        {
            Vector2F diff = point - ray.Origin;
            float    t    = Vector2F.Dot(diff, ray.Direction);

            if (t <= 0.0f)
            {
                t = 0.0f;
            }
            else
            {
                t    /= ray.Direction.GetLengthSquared();
                diff -= t * ray.Direction;
            }

            return(diff.GetLengthSquared());
        }
Пример #9
0
        /// <summary>
        /// Find the intersection of a ray and a sphere.
        /// Only works with unit rays (normalized direction)!!!
        /// </summary>
        /// <remarks>
        /// This is the optimized Ray-Sphere intersection algorithms described in "Real-Time Rendering".
        /// </remarks>
        /// <param name="ray">The ray to test.</param>
        /// <param name="t">
        /// If intersection accurs, the function outputs the distance from the ray's origin
        /// to the closest intersection point to this parameter.
        /// </param>
        /// <returns>Returns True if the ray intersects the sphere. otherwise, <see langword="false"/>.</returns>
        public bool FindIntersections(Ray ray, ref float t)
        {
            // Only gives correct result for unit rays.
            //Debug.Assert(MathUtils.ApproxEquals(1.0f, ray.Direction.GetLength()), "Ray direction should be normalized!");

            // Calculates a vector from the ray origin to the sphere center.
            Vector2F diff = this.center - ray.Origin;
            // Compute the projection of diff onto the ray direction
            float d = Vector2F.Dot(diff, ray.Direction);

            float diffSquared   = diff.GetLengthSquared();
            float radiusSquared = this.radius * this.radius;

            // First rejection test :
            // if d<0 and the ray origin is outside the sphere than the sphere is behind the ray
            if ((d < 0.0f) && (diffSquared > radiusSquared))
            {
                return(false);
            }

            // Compute the distance from the sphere center to the projection
            float mSquared = diffSquared - d * d;

            // Second rejection test:
            // if mSquared > radiusSquared than the ray misses the sphere
            if (mSquared > radiusSquared)
            {
                return(false);
            }

            float q = (float)System.Math.Sqrt(radiusSquared - mSquared);

            // We are interested only in the first intersection point:
            if (diffSquared > radiusSquared)
            {
                // If the origin is outside the sphere t = d - q is the first intersection point
                t = d - q;
            }
            else
            {
                // If the origin is inside the sphere t = d + q is the first intersection point
                t = d + q;
            }
            return(true);
        }
Пример #10
0
        private float GetPhillipsSpectrum(Vector2F k)
        {
            float kLength = k.Length;

            // Avoid division by zero.
            if (kLength < 1e-8f)
            {
                kLength = 1e-8f;
            }

            Vector2F kDirection = k / kLength;

            // Largest possible wave L = V² / g
            float windSpeedSquared = Wind.LengthSquared;
            float windSpeed        = (float)Math.Sqrt(windSpeedSquared);

            if (windSpeed < Numeric.EpsilonF)
            {
                return(0);
            }

            float L = windSpeedSquared / Gravity;

            float l = L * SmallWaveSuppression;

            Vector2F windDirection;

            windDirection.X = Wind.X / windSpeed;
            windDirection.Y = Wind.Z / windSpeed;

            // NOTE: In AMD water:
            //   HeightScale = 0.00000375 with m_fWindVelocity = 9 and N = 128 for slower, calm seas
            //   HeightScale = 0.00001    with N = 128 for calm seas
            //   HeightScale = 0.0000075  with N = 128 gives beautiful, very calm seas
            //   HeightScale = 0.000005   with N = 64, m_fWindVelocity = 9
            // AMD to filter out waves against the wind direction:
            // if (Vector2F.Dot(kDirection, windDirection) < 0) phillips *= 0.25

            // 2 * _directionality is always 2 in Tessendorf's paper. But we can use any multiple of 2.

            return((float)(/*Height * */ // We apply height scale each frame!
                       Math.Exp(-1 / Math.Pow(kLength * L, 2) - Math.Pow(kLength * l, 2))
                       / Math.Pow(kLength, 4)
                       * Math.Pow(Vector2F.Dot(kDirection, windDirection), 2 * _directionality)));
        }
Пример #11
0
        public override void OnEnterRoom()
        {
            if (direction == Directions.Right)
                tileLocation.X -= player.RoomControl.Room.Width;
            if (direction == Directions.Left)
                tileLocation.X += player.RoomControl.Room.Width;
            if (direction == Directions.Down)
                tileLocation.Y -= player.RoomControl.Room.Height;
            if (direction == Directions.Up)
                tileLocation.Y += player.RoomControl.Room.Height;

            Vector2F center = player.Center - playerOffset;
            Point2I startLoc = tileLocation - Directions.ToPoint(direction);
            Vector2F startPosCenter = (startLoc + new Vector2F(0.5f, 0.5f)) * GameSettings.TILE_SIZE;
            Vector2F directionVector = Directions.ToVector(direction);

            moveDistance = directionVector.Dot(center - startPosCenter);
        }
Пример #12
0
        /// <summary>
        ///   Computes the closest point on the line to the passed point
        /// </summary>
        /// <param name="point"> Point to find the closest point on the line segment for </param>
        /// <returns> Closest point on the line segment to the passed point </returns>
        public Vector2F GetClosestPoint(Vector2F point)
        {
            Vector2F segmentDirection = this.PointB - this.PointA;
            float    projectionValue  = Vector2F.Dot(point - this.PointA, segmentDirection);

            if (projectionValue <= 0.0f)
            {
                return(this.PointA);
            }

            float denominator = Vector2F.Dot(segmentDirection, segmentDirection);

            if (projectionValue >= denominator)
            {
                return(this.PointB);
            }

            projectionValue /= denominator;
            return(this.PointA + (segmentDirection * projectionValue));
        }
Пример #13
0
        public void DotProduct()
        {
            // 0�
            Assert.AreEqual(1.0, Vector2F.Dot(Vector2F.UnitX, Vector2F.UnitX));
            Assert.AreEqual(1.0, Vector2F.Dot(Vector2F.UnitY, Vector2F.UnitY));

            // 180�
            Assert.AreEqual(-1.0, Vector2F.Dot(Vector2F.UnitX, -Vector2F.UnitX));
            Assert.AreEqual(-1.0, Vector2F.Dot(Vector2F.UnitY, -Vector2F.UnitY));

            // 90�
            Assert.AreEqual(0.0, Vector2F.Dot(Vector2F.UnitX, Vector2F.UnitY));

            // 45�
            float angle = (float)Math.Acos(Vector2F.Dot(new Vector2F(1f, 1f).Normalized, Vector2F.UnitX));

            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle));
            angle = (float)Math.Acos(Vector2F.Dot(new Vector2F(1f, 1f).Normalized, Vector2F.UnitY));
            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle));
        }
Пример #14
0
        /// <summary>
        /// Calculates the squared distance between a point and a solid oriented box.
        /// </summary>
        /// <param name="point">A <see cref="Vector2F"/> instance.</param>
        /// <param name="obb">An <see cref="OrientedBox"/> instance.</param>
        /// <param name="closestPoint">The closest point in box coordinates.</param>
        /// <returns>The squared distance between a point and a solid oriented box.</returns>
        /// <remarks>
        /// Treating the oriented box as solid means that any point inside the box has
        /// distance zero from the box.
        /// </remarks>
        public static float SquaredDistancePointSolidOrientedBox(Vector2F point, OrientedBox obb, out Vector2F closestPoint)
        {
            Vector2F diff    = point - obb.Center;
            Vector2F closest = new Vector2F(
                Vector2F.Dot(diff, obb.Axis1),
                Vector2F.Dot(diff, obb.Axis2));

            float sqrDist = 0.0f;
            float delta   = 0.0f;

            if (closest.X < -obb.Extent1)
            {
                delta     = closest.X + obb.Extent1;
                sqrDist  += delta * delta;
                closest.X = -obb.Extent1;
            }
            else if (closest.X > obb.Extent1)
            {
                delta     = closest.X - obb.Extent1;
                sqrDist  += delta * delta;
                closest.X = obb.Extent1;
            }

            if (closest.Y < -obb.Extent2)
            {
                delta     = closest.Y + obb.Extent2;
                sqrDist  += delta * delta;
                closest.Y = -obb.Extent2;
            }
            else if (closest.Y > obb.Extent2)
            {
                delta     = closest.Y - obb.Extent2;
                sqrDist  += delta * delta;
                closest.Y = obb.Extent2;
            }

            closestPoint = closest;

            return(sqrDist);
        }
Пример #15
0
        public void MultiplyMatrix()
        {
            Matrix22F m = new Matrix22F(12, 23, 45, 67);

            Assert.AreEqual(Matrix22F.Zero, Matrix22F.Multiply(m, Matrix22F.Zero));
            Assert.AreEqual(Matrix22F.Zero, Matrix22F.Multiply(Matrix22F.Zero, m));
            Assert.AreEqual(m, Matrix22F.Multiply(m, Matrix22F.Identity));
            Assert.AreEqual(m, Matrix22F.Multiply(Matrix22F.Identity, m));
            Assert.IsTrue(Matrix22F.AreNumericallyEqual(Matrix22F.Identity, Matrix22F.Multiply(m, m.Inverse)));
            Assert.IsTrue(Matrix22F.AreNumericallyEqual(Matrix22F.Identity, Matrix22F.Multiply(m.Inverse, m)));

            Matrix22F m1     = new Matrix22F(columnMajor, MatrixOrder.ColumnMajor);
            Matrix22F m2     = new Matrix22F(12, 23, 45, 67);
            Matrix22F result = Matrix22F.Multiply(m1, m2);

            for (int column = 0; column < 2; column++)
            {
                for (int row = 0; row < 2; row++)
                {
                    Assert.AreEqual(Vector2F.Dot(m1.GetRow(row), m2.GetColumn(column)), result[row, column]);
                }
            }
        }
Пример #16
0
        public void Dot()
        {
            Vector2F a = new Vector2F(1.0f, 2.0f);
            Vector2F b = new Vector2F(4.0f, 5.0f);

            float dot = a.Dot(b);
            Assert.AreEqual(1.0f * 4.0f + 2.0f * 5.0f, dot, 1e-7);
        }
Пример #17
0
        //-----------------------------------------------------------------------------
        // Internal Collision Tests
        //-----------------------------------------------------------------------------

        // Returns true if the entity moving down the ledge.
        public bool IsMovingDownLedge(Tile ledgeTile)
        {
            return(velocity.Dot(Directions.ToVector(ledgeTile.LedgeDirection)) > 0.0f);
        }
Пример #18
0
        private void UpdateMovement()
        {
            // Update movement.
            if (isMoving)
            {
                velocity = (Vector2F)moveDirection * movementSpeed;

                if (offset.Dot(moveDirection) >= 0.0f)
                {
                    currentMoveDistance++;
                    offset -= (Vector2F)(moveDirection * GameSettings.TILE_SIZE);

                    if (currentMoveDistance >= moveDistance)
                    {
                        offset        = Vector2F.Zero;
                        velocity      = Vector2F.Zero;
                        moveDirection = Point2I.Zero;
                        isMoving      = false;
                        CheckSurfaceTile();
                        if (IsDestroyed)
                        {
                            return;
                        }
                        OnCompleteMovement();
                    }
                    else
                    {
                        roomControl.MoveTile(this, location + moveDirection, layer);
                    }
                }
                else if (currentMoveDistance + 1 >= moveDistance)
                {
                    // Don't overshoot the destination.
                    float overshoot = (offset + velocity).Dot(moveDirection);
                    if (overshoot >= 0.0f)
                    {
                        velocity -= overshoot * (Vector2F)moveDirection;
                    }
                }
            }
            // Update path following.
            else if (path != null)
            {
                TilePathMove move = path.Moves[pathMoveIndex];

                // Begin the next move in the path after the delay has been passed.
                if (pathTimer >= move.Delay)
                {
                    Move(move.Direction, move.Distance, move.Speed);
                    pathTimer = 0;
                    pathMoveIndex++;
                    if (pathMoveIndex >= path.Moves.Count)
                    {
                        if (path.Repeats)
                        {
                            pathMoveIndex = 0;
                        }
                        else
                        {
                            path = null;
                        }
                    }
                }

                pathTimer++;
            }

            // Integrate velocity.
            if (isMoving)
            {
                offset += velocity;
            }
            else
            {
                velocity = Vector2F.Zero;
            }
        }