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)); }
/// <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)); }
/// <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; }
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); }
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)); }
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))); }
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]); } }
/// <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()); }
/// <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); }
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))); }
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); }
/// <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)); }
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)); }
/// <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); }
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]); } } }
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); }
//----------------------------------------------------------------------------- // 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); }
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; } }