public Rectangle(Vector TopLeft, Vector BottomRight) { this.Left = TopLeft.X; this.Top = TopLeft.Y; this.Right = BottomRight.X; this.Bottom = BottomRight.Y; }
/// <summary> /// Draws this shape using the given scale and offset. /// </summary> public void Draw(Render Render, Color4 Color, Vector Offset, double Scale) { Render.Vertex(Destination.TopLeft * Scale + Offset, Source.TopLeft, Color); Render.Vertex(Destination.BottomLeft * Scale + Offset, Source.BottomLeft, Color); Render.Vertex(Destination.BottomRight * Scale + Offset, Source.BottomRight, Color); Render.Vertex(Destination.TopRight * Scale + Offset, Source.TopRight, Color); }
/// <summary> /// Draws an arrow connecting two points. /// </summary> public static void DrawArrow(Render Render, Color4 Color, Vector A, Vector B, double Width) { Vector dif = B - A; double len = dif.Length; Vector dir = dif / len; double linelen = len - ArrowSegment.Destination.Top * Width; LineSegment.Draw(Render, Color, new Transform(A, -dir.Cross * Width, dir * linelen)); ArrowSegment.Draw(Render, Color, new Transform(A + dir * linelen, -dir.Cross * Width, dir * Width)); }
/// <summary> /// Updates the state of the camera by the given time in seconds. /// </summary> public void Update(double Time) { double extent = this.Extent; this.Center += this.Velocity * (extent * Time); this.Velocity *= Math.Pow(Settings.Current.CameraMovementDamping, Time); this.Zoom += this.ZoomVelocity * Time; this.ZoomVelocity *= Math.Pow(Settings.Current.CameraZoomDamping, Time); double minzoom = Settings.Current.CameraMinZoom; if (this.Zoom < minzoom) { this.Zoom = minzoom; this.ZoomVelocity = 0.0; } double maxzoom = Settings.Current.CameraMaxZoom; if (this.Zoom > maxzoom) { this.Zoom = maxzoom; this.ZoomVelocity = 0.0; } }
/// <summary> /// Draws an arrow starting at a given point going in the given direction for the given length. /// </summary> public static void DrawArrow(Render Render, Color4 Color, Vector Start, Vector Direction, double Length, double Width) { double linelen = Length - ArrowSegment.Destination.Top * Width; LineSegment.Draw(Render, Color, new Transform(Start, -Direction.Cross * Width, Direction * linelen)); ArrowSegment.Draw(Render, Color, new Transform(Start + Direction * linelen, -Direction.Cross * Width, Direction * Width)); }
/// <summary> /// Draws a number to the given point. /// </summary> public static void DrawNumber(Render Render, uint Number, Color4 Color, Vector Center, double Size, double Spacing) { List<uint> digits = new List<uint>(5); if (Number == 0) digits.Add(0); else while (Number > 0) { digits.Add(Number % 10); Number /= 10; } double offset = (Spacing * (digits.Count - 1)) / 2.0; foreach (uint digit in digits) { DrawDigit(Render, digit, Color, new Vector(Center.X + offset, Center.Y), Size); offset -= Spacing; } }
/// <summary> /// Draws a line starting at a given point going in the given direction for the given length. /// </summary> public static void DrawLine(Render Render, Color4 Color, Vector Start, Vector Direction, double Length, double Width) { LineSegment.Draw(Render, Color, new Transform(Start, -Direction.Cross * Width, Direction * Length)); }
public Transform(Vector Offset, Vector Right, Vector Up) { this.Offset = Offset; this.Right = Right; this.Up = Up; }
/// <summary> /// Draws a vertex with the given properties. /// </summary> public void Vertex(Vector Position, Vector UV, Color4 Color) { this.Vertex(Position.X, Position.Y, UV.X, UV.Y, Color); }
/// <summary> /// Gets the zone for the given position. /// </summary> private static ZoneIndex _GetZone(Vector Position) { return new ZoneIndex((int)Math.Floor(Position.X / ZoneSize), (int)Math.Floor(Position.Y / ZoneSize)); }
/// <summary> /// Gets a stone at the given location, or null if there's none there. /// </summary> public Stone Pick(Vector Point) { foreach (Stone stone in this._Stones.Values) { if ((Point - stone.Position).Length <= stone.Radius) return stone; } return null; }
/// <summary> /// Inserts a stone for the given entry. There must not be any existing stones for the entry. /// </summary> public Stone Insert(Entry Entry, Vector Position, Vector Velocity) { Stone stone = new Stone(Entry); stone.Position = Position; stone.Velocity = Velocity; this._Introduce(stone, Entry); return stone; }
/// <summary> /// Gets the dot product of two vectors. /// </summary> public static double Dot(Vector A, Vector B) { return A.X * B.X + A.Y * B.Y; }
/// <summary> /// Applies this transform to a vector. /// </summary> public Vector Project(Vector Source) { return this.Offset + this.Right * Source.X + this.Up * Source.Y; }
/// <summary> /// Create a translation transform. /// </summary> public static Transform Translate(Vector Amount) { return new Transform(Amount, new Vector(1.0, 0.0), new Vector(0.0, 1.0)); }
/// <summary> /// Draws a circle. /// </summary> public static void DrawCircle(Render Render, Color4 Color, Vector Center, double Radius) { Circle.Draw(Render, Color, Center, Radius * 2.0); }
/// <summary> /// Draws a digit of the given size to the given point. /// </summary> public static void DrawDigit(Render Render, uint Digit, Color4 Color, Vector Center, double Size) { Digits[Digit].Draw(Render, Color, Center, Size); }
/// <summary> /// Gets the repulsive pressure felt by the given stone. /// </summary> private double _Pressure(Stone Stone, out Vector Direction) { double pressure = 0.0; Direction = Vector.Zero; ZoneIndex centerindex = _GetZone(Stone.Position); for (int x = centerindex.X - 1; x <= centerindex.X + 1; x++) for (int y = centerindex.Y - 1; y <= centerindex.Y + 1; y++) { List<Stone> zone; if (this._Zones.TryGetValue(new ZoneIndex(x, y), out zone)) foreach (Stone other in zone) if (other != Stone) { Vector dif = Stone.Position - other.Position; double len = Math.Max(dif.Length, other.Radius); double mag = 1.0 / (len * len); Vector force = dif * (mag / len); Direction += force; pressure += mag; } } return pressure; }
/// <summary> /// Changes a vector slightly to make it distinct from other vectors. /// </summary> private static void _Tweak(object Object, ref Vector Vector) { int h = Object.GetHashCode(); int x = h & 0xFF; int y = (h & 0xFF00) >> 8; Vector.X += (x - 127.0) * 0.0001; Vector.Y += (y - 127.0) * 0.0001; }
/// <summary> /// Draws a line connecting two points. /// </summary> public static void DrawLine(Render Render, Color4 Color, Vector A, Vector B, double Width) { Vector dif = B - A; double len = dif.Length; Vector dir = dif / len; LineSegment.Draw(Render, Color, new Transform(A, -dir.Cross * Width, dif)); }
/// <summary> /// Zooms the camera to the given target point by the given amount. /// </summary> public void ZoomTo(double Amount, Vector Target) { Amount *= Settings.Current.CameraZoomSpeed; double extent = this.Extent; Vector dif = Target - this.Center; this.ZoomVelocity += Amount; this.Velocity += dif * (Amount * Settings.Current.CameraZoomMovement / extent); }
/// <summary> /// Updates a stone. /// </summary> public void Update(double Time, double Damping) { Stone next = this.Next; if (next != null && this != next) { Vector dif = next.Position - this.Position; double len = dif.Length; double power = len - this.TargetLinkLength; power = Math.Min(10.0, Math.Abs(power) * power); Vector force = dif * (Time * Settings.Current.StoneLinkForce * power / len); this.Velocity += force; next.Velocity -= force; } this.Position += this.Velocity * Time; if (double.IsNaN(this.Position.X) || double.IsNaN(this.Position.Y)) { this.Position = Vector.Zero; this.Velocity = Vector.Zero; } else { this.Velocity *= Damping; } }