public Room(Project project) : base(project) { Name = "Cave"; Size = new Vector(3 * Settings.GridSize, 2 * Settings.GridSize); Position = new Vector(-Size.X / 2, -Size.Y / 2); // connections may connect to any of our "corners" PortList.Add(new CompassPort(CompassPoint.North, this)); PortList.Add(new CompassPort(CompassPoint.NorthNorthEast, this)); PortList.Add(new CompassPort(CompassPoint.NorthEast, this)); PortList.Add(new CompassPort(CompassPoint.EastNorthEast, this)); PortList.Add(new CompassPort(CompassPoint.East, this)); PortList.Add(new CompassPort(CompassPoint.EastSouthEast, this)); PortList.Add(new CompassPort(CompassPoint.SouthEast, this)); PortList.Add(new CompassPort(CompassPoint.SouthSouthEast, this)); PortList.Add(new CompassPort(CompassPoint.South, this)); PortList.Add(new CompassPort(CompassPoint.SouthSouthWest, this)); PortList.Add(new CompassPort(CompassPoint.SouthWest, this)); PortList.Add(new CompassPort(CompassPoint.WestSouthWest, this)); PortList.Add(new CompassPort(CompassPoint.West, this)); PortList.Add(new CompassPort(CompassPoint.WestNorthWest, this)); PortList.Add(new CompassPort(CompassPoint.NorthWest, this)); PortList.Add(new CompassPort(CompassPoint.NorthNorthWest, this)); }
/// <summary> /// Shorten this line segment, moving the end point towards the start point. /// </summary> /// <param name="amount">The amount by which to shorten.</param> public bool Shorten(float amount) { var delta = Delta; var length = delta.Length; delta.Normalize(); if (length > amount) { length -= amount; End = Start + delta * length; return true; } else { // don't shorten past zero length End = Start; return false; } }
public static CompassPoint GetCompassPointFromAutomapDirectionVector(Vector vector) { if (vector.X < 0) { if (vector.Y < 0) { return CompassPoint.NorthWest; } if (vector.Y > 0) { return CompassPoint.SouthWest; } return CompassPoint.West; } if (vector.X > 0) { if (vector.Y < 0) { return CompassPoint.NorthEast; } if (vector.Y > 0) { return CompassPoint.SouthEast; } return CompassPoint.East; } if (vector.Y < 0) { return CompassPoint.North; } if (vector.Y > 0) { return CompassPoint.South; } Debug.Assert(false, "Automap direction vector should not be zero."); return CompassPoint.North; }
public float Distance(Vector pos) { return pos.DistanceFromRect(visualBounds); }
private void RebuildCachedLayout(XGraphics graphics, Font font, ref Vector pos, ref Vector size, XStringFormat baseFormat) { // for diagnostic purposes ++s_rebuildCount; // store current settings to help us tell if we need a rebuild next time around m_requestedFormat = new XStringFormat(); m_requestedFormat.Alignment = baseFormat.Alignment; m_requestedFormat.FormatFlags = baseFormat.FormatFlags; m_requestedFormat.LineAlignment = baseFormat.LineAlignment; m_actualFormat = new XStringFormat(); m_actualFormat.Alignment = baseFormat.Alignment; m_actualFormat.FormatFlags = baseFormat.FormatFlags; m_actualFormat.LineAlignment = baseFormat.LineAlignment; m_pos = pos; m_size = size; var text = m_text; if (text.IndexOf('\n') == -1 && size.X > 0 && size.Y > 0 && graphics.MeasureString(text, font).Width > size.X) { // wrap single-line text to fit in rectangle // measure a space, countering the APIs unwillingness to measure spaces var spaceLength = (float)(graphics.MeasureString("M M", font).Width - graphics.MeasureString("M", font).Width * 2); var words = new List<Word>(); foreach (var word in text.Split(' ')) { if (words.Count != 0) { words.Add(new Word(" ", spaceLength)); } words.Add(new Word(word, (float)graphics.MeasureString(word, font).Width)); } var lineLength = 0.0f; var total = string.Empty; var line = string.Empty; foreach (var word in words) { if (word.Text != " " && word.Length > Math.Max(0, size.X - lineLength) && lineLength > 0) { if (line.Length > 0) { if (total.Length > 0) { total += "\n"; } total += line; lineLength = word.Length + spaceLength; line = word.Text; } } else { line += word.Text; lineLength += word.Length + spaceLength; } } if (line.Length > 0) { if (total.Length > 0) { total += "\n"; } total += line; } text = total; } m_lineHeight = font.GetHeight(); m_lines.Clear(); m_lines.AddRange(text.Split('\n')); switch (m_actualFormat.LineAlignment) { case XLineAlignment.Near: default: m_origin = pos; m_delta = new Vector(0, m_lineHeight); break; case XLineAlignment.Far: m_origin = new Vector(pos.X, pos.Y + size.Y - m_lineHeight); if (size.Y > 0) { var count = m_lines.Count; while (m_origin.Y - m_lineHeight >= pos.Y && --count > 0) { m_origin.Y -= m_lineHeight; } } else { m_origin.Y -= (m_lines.Count - 1) * m_lineHeight; } m_delta = new Vector(0, m_lineHeight); break; case XLineAlignment.Center: m_origin = new Vector(pos.X, pos.Y + size.Y / 2 - (m_lines.Count - 1) * m_lineHeight / 2 - m_lineHeight / 2); m_delta = new Vector(0, m_lineHeight); break; } m_actualFormat.LineAlignment = XLineAlignment.Near; switch (m_actualFormat.Alignment) { case XStringAlignment.Far: m_origin.X = pos.X + size.X; break; case XStringAlignment.Center: m_origin.X = pos.X + size.X / 2; break; } }
public float Distance(Vector other) { return Distance(this, other); }
public static float Dot(Vector a, Vector b) { return a.X * b.X + a.Y * b.Y; }
public static float DistanceFromLineSegment(LineSegment line, Vector pos) { var delta = line.End - line.Start; var direction = Vector.Normalize(delta); float distanceAlongSegment = Vector.Dot(pos, direction) - Vector.Dot(line.Start, direction); Vector nearest; if (distanceAlongSegment < 0) { nearest = line.Start; } else if (distanceAlongSegment > delta.Length) { nearest = line.End; } else { nearest = line.Start + distanceAlongSegment * direction; } return Vector.Distance(nearest, pos); }
public override void SetPosition(Vector pos) { Vertex.Position = pos; Connection.RaiseChanged(); }
public static void AddLine(XGraphicsPath path, LineSegment segment, Random random, bool straightEdges) { if (Settings.HandDrawn && !straightEdges) { var dx = segment.End.X - segment.Start.X; var dy = segment.End.Y - segment.Start.Y; var distance = (float) Math.Sqrt(dx*dx + dy*dy); var points = random.Next(Math.Max(3, (int) (distance/15)), Math.Max(6, (int) (distance/8))); var lines = points - 1; var last = segment.Start; for (var line = 0; line < lines; ++line) { Vector next; if (line == 0) { next = last; } else if (line == lines - 1) { next = segment.End; } else { var fraction = line/(float) (lines - 1); var x = segment.Start.X + (segment.End.X - segment.Start.X)*fraction; var y = segment.Start.Y + (segment.End.Y - segment.Start.Y)*fraction; x += random.Next(-1, 2); y += random.Next(-1, 2); next = new Vector(x, y); } path.AddLine(last.ToPointF(), next.ToPointF()); last = next; } } else { path.AddLine(segment.Start.ToPointF(), segment.End.ToPointF()); } }
public void Load(XmlElementReader element) { Name = element.Attribute("name").Text; ClearDescriptions(); AddDescription(element.Attribute("description").Text); Position = new Vector(element.Attribute("x").ToFloat(), element.Attribute("y").ToFloat()); Size = new Vector(element.Attribute("w").ToFloat(), element.Attribute("h").ToFloat()); IsDark = element.Attribute("isDark").ToBool(); Objects = element["objects"].Text.Replace("|","\r\n").Replace("\\\r\n", "|"); ObjectsPosition = element["objects"].Attribute("at").ToCompassPoint(ObjectsPosition); }
public override float Distance(Vector pos, bool includeMargins) { var bounds = UnionBoundsWith(Rect.Empty, includeMargins); return pos.DistanceFromRect(bounds); }
public LineSegment(Vector start, Vector end) { Start = start; End = end; }
public LineSegmentIntersect(LineSegmentIntersectType type, Vector pos) { Type = type; Position = pos; }
public Rect(Vector pos, Vector size) : this(pos.X, pos.Y, size.X, size.Y) { }
public override float Distance(Vector pos, bool includeMargins) { var distance = float.MaxValue; foreach (var segment in GetSegments()) { distance = Math.Min(distance, pos.DistanceFromLineSegment(segment)); } return distance; }
public static float Distance(Vector a, Vector b) { return Math.Abs((b - a).Length); }
private void PositionRelativeTo(Room room, Room existing, CompassPoint existingCompassPoint, out Vector delta) { delta = CompassPointHelper.GetAutomapDirectionVector(existingCompassPoint); delta.X *= Settings.PreferredDistanceBetweenRooms + room.Width; delta.Y *= Settings.PreferredDistanceBetweenRooms + room.Height; var newRoomCenter = existing.InnerBounds.Center + delta; room.Position = Settings.Snap(new Vector(newRoomCenter.X - room.Width/2, newRoomCenter.Y - room.Height/2)); }
public static float DistanceFromRect(Rect rect, Vector pos) { if (rect.Contains(pos)) { return 0; } var nw = rect.GetCorner(CompassPoint.NorthWest); var ne = rect.GetCorner(CompassPoint.NorthEast); var sw = rect.GetCorner(CompassPoint.SouthWest); var se = rect.GetCorner(CompassPoint.SouthEast); var distanceFromTop = DistanceFromLineSegment(new LineSegment(nw, ne), pos); var distanceFromRight = DistanceFromLineSegment(new LineSegment(ne, se), pos); var distanceFromBottom = DistanceFromLineSegment(new LineSegment(se, sw), pos); var distanceFromLeft = DistanceFromLineSegment(new LineSegment(sw, nw), pos); return Math.Min(distanceFromTop, Math.Min(distanceFromLeft, Math.Min(distanceFromBottom, distanceFromRight))); }
private void ShiftMap(Rect deltaOrigin, Vector delta) { // move all elements to the left/right of the origin left/right by the given delta foreach (var element in Project.Current.Elements) { if (element is Room) { var room = (Room) element; var bounds = room.InnerBounds; if (delta.X < 0) { if (bounds.Center.X < deltaOrigin.Right) { room.Position = new Vector(room.Position.X + delta.X, room.Position.Y); } } else if (delta.X > 0) { if (bounds.Center.X > deltaOrigin.Left) { room.Position = new Vector(room.Position.X + delta.X, room.Position.Y); } } } } // move all elements above/below the origin up/down by the given delta foreach (var element in Project.Current.Elements) { if (element is Room) { var room = (Room) element; var bounds = room.InnerBounds; if (delta.Y < 0) { if (bounds.Center.Y < deltaOrigin.Bottom) { room.Position = new Vector(room.Position.X, room.Position.Y + delta.Y); } } else if (bounds.Center.Y > deltaOrigin.Top) { if (bounds.Bottom > deltaOrigin.Y) { room.Position = new Vector(room.Position.X, room.Position.Y + delta.Y); } } } } }
public static Vector Normalize(Vector v) { Vector n = v; n.Normalize(); return n; }
public bool HitTest(Vector pos) { return bounds.Contains(pos); }
public float Dot(Vector other) { return Dot(this, other); }
/// <summary> /// Clamp a vector so that it falls within the rectangle. /// </summary> public Vector Clamp(Vector v) { v.X = Math.Max(X, Math.Min(X + Width, v.X)); v.Y = Math.Max(Y, Math.Min(Y + Height, v.Y)); return v; }
/// <summary> /// Draw a multi-line string as it would be drawn by GDI+. /// Compensates for issues and draw-vs-PDF differences in PDFsharp. /// </summary> /// <param name="graphics">The graphics with which to draw.</param> /// <param name="text">The text to draw, which may contain line breaks.</param> /// <param name="font">The font with which to draw.</param> /// <param name="brush">The brush with which to draw.</param> /// <param name="pos">The position at which to draw.</param> /// <param name="size">The size to which to limit the drawn text; or Vector.Zero for no limit.</param> /// <param name="format">The string format to use.</param> /// <remarks> /// PDFsharp cannot currently render multi-line text to PDF files; it comes out as single line. /// This method simulates standard Graphics.DrawString() over PDFsharp. /// It always has the effect of StringFormatFlags.LineLimit (which PDFsharp does not support). /// </remarks> public void Draw(XGraphics graphics, Font font, Brush brush, Vector pos, Vector size, XStringFormat format) { // do a quick test to see if text is going to get drawn at the same size as last time; // if so, assume we don't need to recompute our layout for that reason. var sizeChecker = graphics.MeasureString("M q", font); if (sizeChecker != m_sizeChecker || pos != m_pos || m_size != size || m_requestedFormat.Alignment != format.Alignment || m_requestedFormat.LineAlignment != format.LineAlignment || m_requestedFormat.FormatFlags != format.FormatFlags) { m_invalidLayout = true; } m_sizeChecker = sizeChecker; if (m_invalidLayout) { // something vital has changed; rebuild our cached layout data RebuildCachedLayout(graphics, font, ref pos, ref size, format); m_invalidLayout = false; } var state = graphics.Save(); if (size != Vector.Zero) { graphics.IntersectClip(new RectangleF(pos.X, pos.Y, size.X, size.Y)); } // disable smoothing whilst rendering text; // visually this is no different, but is faster var smoothingMode = graphics.SmoothingMode; graphics.SmoothingMode = XSmoothingMode.HighSpeed; var origin = m_origin; for (var index=0; index<m_lines.Count; ++index) { if (size.Y > 0 && size.Y < m_lineHeight) break; // not enough remaining vertical space for a whole line var line = m_lines[index]; graphics.DrawString(line, font, brush, origin.X, origin.Y, m_actualFormat); origin += m_delta; size.Y -= m_lineHeight; } graphics.SmoothingMode = smoothingMode; graphics.Restore(state); }
public bool Contains(Vector pos) { return pos.X >= Left && pos.X <= Right && pos.Y >= Top && pos.Y <= Bottom; }
public abstract void SetPosition(Vector pos);
public Rect Union(Vector v) { if (this == Empty) { // the union of this empty rectangle and a vector is that vector return new Rect(v, Vector.Zero); } var newRect = this; newRect.X = Math.Min(v.X, X); newRect.Y = Math.Min(v.Y, Y); newRect.Width = Math.Max(v.X, X + Width) - newRect.X; newRect.Height = Math.Max(v.Y, Y + Height) - newRect.Y; return newRect; }
public Vertex(Vector position) { Position = position; }
/// <summary> /// Reverse the direction of this line segment. /// </summary> public void Reverse() { var temp = End; End = Start; Start = temp; }