/// <summary> /// Fits this rectangle to the given points. /// </summary> /// <param name="points">The points to wrap the rectangle around.</param> /// <param name="percentage">The margin in percentage.</param> /// <returns></returns> public RectangleF2D Fit(PointF2D[] points, double percentage) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length < 2) { throw new ArgumentOutOfRangeException("Rectangle fit needs at least two points."); } // calculate the center. double[] center = new double[] { points[0][0], points[0][1] }; for (int idx = 1; idx < points.Length; idx++) { center[0] = center[0] + points[idx][0]; center[1] = center[1] + points[idx][1]; } center[0] = center[0] / points.Length; center[1] = center[1] / points.Length; PointF2D centerPoint = new PointF2D(center); LineF2D line = null; // calculate the width. double width = 0; for (int idx = 0; idx < points.Length; idx++) { line = new LineF2D(points[idx], points[idx] + this._vectorY); double distance = line.Distance(centerPoint); if (distance > width) { // the distance is larger. width = distance; } } width = width * 2; // calculate the height. double height = 0; for (int idx = 0; idx < points.Length; idx++) { line = new LineF2D(points[idx], points[idx] + this._vectorX); double distance = line.Distance(centerPoint); if (distance > height) { // this distance is larger. height = distance; } } height = height * 2; // expand with the given percentage. width = width + (width / 100.0 * percentage); height = height + (height / 100.0 * percentage); return(RectangleF2D.FromBoundsAndCenter(width, height, centerPoint[0], centerPoint[1], this.DirectionY)); }
public RectangleF2D Fit(PointF2D[] points, double percentage) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length < 2) { throw new ArgumentOutOfRangeException("Rectangle fit needs at least two points."); } double[] values = new double[2] { points[0][0], points[0][1] }; for (int index = 1; index < points.Length; ++index) { values[0] = values[0] + points[index][0]; values[1] = values[1] + points[index][1]; } values[0] = values[0] / (double)points.Length; values[1] = values[1] / (double)points.Length; PointF2D p = new PointF2D(values); double num1 = 0.0; for (int index = 0; index < points.Length; ++index) { double num2 = new LineF2D(points[index], points[index] + this._vectorY).Distance(p); if (num2 > num1) { num1 = num2; } } double num3 = num1 * 2.0; double num4 = 0.0; for (int index = 0; index < points.Length; ++index) { double num2 = new LineF2D(points[index], points[index] + this._vectorX).Distance(p); if (num2 > num4) { num4 = num2; } } double num5 = num4 * 2.0; return(RectangleF2D.FromBoundsAndCenter(num3 + num3 / 100.0 * percentage, num5 + num5 / 100.0 * percentage, p[0], p[1], this.DirectionY)); }
/// <summary> /// Fits this rectangle to this given points and keeps aspect ratio. /// </summary> /// <param name="points"></param> /// <param name="percentage"></param> /// <returns></returns> public RectangleF2D FitAndKeepAspectRatio(PointF2D[] points, double percentage) { RectangleF2D fitted = this; if (points.Length > 1) { // multiple points can be fitted and zoomed to. fitted = this.Fit(points, percentage); } else if (points.Length == 1) { // a single point can only be moved to. fitted = new RectangleF2D(points[0][0], points[0][1], this.Width, this.Height, this.Angle); } // although this may seem a strange approach, think about // numerical stability before changing this! double width = fitted.Width; double height = fitted.Height; double targetRatio = this.Width / this.Height; // this is the target ratio. if (fitted.Height > fitted.Width) { // the height is bigger. double targetWidth = fitted.Height * targetRatio; if (targetWidth < fitted.Width) { // increase height instead. height = fitted.Width / targetRatio; } else { // ok, the width is increased and ratio's match now. width = targetWidth; } } else { // the width is bigger. double targetHeight = fitted.Width / targetRatio; if (targetHeight < fitted.Height) { // increase width instead. width = fitted.Height * targetRatio; } else { // ok, the height is increase and ratio's match now. height = targetHeight; } } return(RectangleF2D.FromBoundsAndCenter(width, height, fitted.Center[0], fitted.Center[1], fitted.DirectionY)); }
public RectangleF2D FitAndKeepAspectRatio(PointF2D[] points, double percentage) { RectangleF2D rectangleF2D = this; if (points.Length > 1) { rectangleF2D = this.Fit(points, percentage); } else if (points.Length == 1) { rectangleF2D = new RectangleF2D(points[0][0], points[0][1], this.Width, this.Height, this.Angle); } double width = rectangleF2D.Width; double height = rectangleF2D.Height; double num1 = this.Width / this.Height; if (rectangleF2D.Height > rectangleF2D.Width) { double num2 = rectangleF2D.Height * num1; if (num2 < rectangleF2D.Width) { height = rectangleF2D.Width / num1; } else { width = num2; } } else { double num2 = rectangleF2D.Width / num1; if (num2 < rectangleF2D.Height) { width = rectangleF2D.Height * num1; } else { height = num2; } } return(RectangleF2D.FromBoundsAndCenter(width, height, rectangleF2D.Center[0], rectangleF2D.Center[1], rectangleF2D.DirectionY)); }
/// <summary> /// Creates a new RectangleF2D from given bounds, center and angle. /// </summary> /// <param name="centerX"></param> /// <param name="centerY"></param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="angleY">The angle.</param> /// <returns></returns> public static RectangleF2D FromBoundsAndCenter(double width, double height, double centerX, double centerY, Degree angleY) { return(RectangleF2D.FromBoundsAndCenter(width, height, centerX, centerY, VectorF2D.FromAngleY(angleY))); }