/// <summary> /// Creates a new instance of a Ray. /// </summary> /// <param name="position">Starting position of the ray.</param> /// <param name="direction">Unit direction vector that the ray is pointing.</param> public Ray(Vector2 position, Vector2 direction, int collisionMask) { _position = position; _direction = direction; _collisionMask = collisionMask; DebugTools.Assert(FloatMath.CloseTo(_direction.LengthSquared, 1)); }
private bool Contains(float x, float y) { var dx = Position.X - x; var dy = Position.Y - y; var d2 = dx * dx + dy * dy; var r2 = Radius * Radius; // Instead of d2 <= r2, use FloatMath.CloseTo to allow for some tolerance. return((d2 < r2) || FloatMath.CloseTo(d2, r2)); }
private static bool EqualsApprox(Angle a, Angle b) { // reduce both angles var aReduced = Reduce(a.Theta); var bReduced = Reduce(b.Theta); var aPositive = FlipPositive(aReduced); var bPositive = FlipPositive(bReduced); // The second two expressions cover an edge case where one number is barely non-negative while the other number is negative. // In this case, the negative number will get FlipPositived to ~2pi and the comparison will give a false negative. return(FloatMath.CloseTo(aPositive, bPositive) || FloatMath.CloseTo(aPositive + MathHelper.TwoPi, bPositive) || FloatMath.CloseTo(aPositive, bPositive + MathHelper.TwoPi)); }
public static float Clamp01(float value) { return(FloatMath.Clamp(value, 0, 1)); }
public bool IsEmpty() { return(FloatMath.CloseTo(Width, 0.0f) && FloatMath.CloseTo(Height, 0.0f)); }
public bool Intersects(Box2 box, out float distance, out Vector2 hitPos) { hitPos = Vector2.Zero; distance = 0; var tmin = 0.0f; // set to -FLT_MAX to get first hit on line var tmax = float.MaxValue; // set to max distance ray can travel (for segment) const float epsilon = 1.0E-07f; // X axis slab { if (Math.Abs(_direction.X) < epsilon) { // ray is parallel to this slab, it will never hit unless ray is inside box if (_position.X < FloatMath.Min(box.Left, box.Right) || _position.X > FloatMath.Max(box.Left, box.Right)) { return(false); } } // calculate intersection t value of ray with near and far plane of slab var ood = 1.0f / _direction.X; var t1 = (FloatMath.Min(box.Left, box.Right) - _position.X) * ood; var t2 = (FloatMath.Max(box.Left, box.Right) - _position.X) * ood; // Make t1 be the intersection with near plane, t2 with far plane if (t1 > t2) { MathHelper.Swap(ref t1, ref t2); } // Compute the intersection of slab intersection intervals tmin = FloatMath.Max(t1, tmin); tmax = FloatMath.Min(t2, tmax); // Is this Min (SE) or Max(Textbook) // Exit with no collision as soon as slab intersection becomes empty if (tmin > tmax) { return(false); } } // Y axis slab { if (Math.Abs(_direction.Y) < epsilon) { // ray is parallel to this slab, it will never hit unless ray is inside box if (_position.Y < FloatMath.Min(box.Top, box.Bottom) || _position.Y > FloatMath.Max(box.Top, box.Bottom)) { return(false); } } // calculate intersection t value of ray with near and far plane of slab var ood = 1.0f / _direction.Y; var t1 = (FloatMath.Min(box.Top, box.Bottom) - _position.Y) * ood; var t2 = (FloatMath.Max(box.Top, box.Bottom) - _position.Y) * ood; // Make t1 be the intersection with near plane, t2 with far plane if (t1 > t2) { MathHelper.Swap(ref t1, ref t2); } // Compute the intersection of slab intersection intervals tmin = FloatMath.Max(t1, tmin); tmax = FloatMath.Min(t2, tmax); // Is this Min (SE) or Max(Textbook) // Exit with no collision as soon as slab intersection becomes empty if (tmin > tmax) { return(false); } } // Ray intersects all slabs. Return point and intersection t value hitPos = _position + _direction * tmin; distance = tmin; return(true); }