示例#1
0
        /// <summary>
        /// Creates a rectangle that includes all the provided points.
        /// </summary>
        /// <param name="points">The points that the rectangle should include.</param>
        /// <returns>The rectangle that includes all the provided points.</returns>
        /// <exception cref="System.ArgumentException">Enumeration is empty!</exception>
        public static RectangleD2D NewRectangleIncludingAllPoints(IEnumerable <PointD2D> points)
        {
            var en = points.GetEnumerator();

            if (!en.MoveNext())
            {
                throw new ArgumentException("Enumeration is empty!", nameof(points));
            }

            var result = new RectangleD2D(en.Current, PointD2D.Empty);

            while (en.MoveNext())
            {
                result.ExpandToInclude(en.Current);
            }

            return(result);
        }
示例#2
0
		/// <summary>
		/// Calculates the dimensions of the greatest (by area) rectangle included in an outer rectangle, where the inner rectangle is rotated/sheared/scaled.
		/// </summary>
		/// <param name="outerRectangle">The outer rectangle.</param>
		/// <param name="sx">SX component of the transformation matrix that is applied to the inner rectangle.</param>
		/// <param name="rx">RX component of the transformation matrix that is applied to the inner rectangle.</param>
		/// <param name="ry">RY component of the transformation matrix that is applied to the inner rectangle.</param>
		/// <param name="sy">SY component of the transformation matrix that is applied to the inner rectangle.</param>
		/// <returns>The inner rectangle with the greatest area that fits (when transformed with the transformation elements) into the outer rectangle.
		/// The position of the returned rectangle is calculated so that it centers into the outer rectangle.</returns>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// X-Size of outer rectangle must be > 0
		/// or
		/// Y-Size of outer rectangle must be > 0
		/// </exception>
		public static RectangleD2D GetIncludedTransformedRectangle(this RectangleD2D outerRectangle, double sx, double rx, double ry, double sy)
		{
			PointD2D outerRectangleSize = outerRectangle.Size;

			if (!(outerRectangleSize.X > 0))
				throw new ArgumentOutOfRangeException("X-Size of outer rectangle must be > 0");
			if (!(outerRectangleSize.Y > 0))
				throw new ArgumentOutOfRangeException("Y-Size of outer rectangle must be > 0");

			double a = Math.Abs(sx);
			double b = Math.Abs(rx);
			double c = Math.Abs(ry);
			double d = Math.Abs(sy);

			double maxArea = 0;
			double sizeX = 0, sizeY = 0;
			double x, y, area;

			{
				// solution 1, which touches all walls
				double bcMad = b * c - a * d;
				if (bcMad != 0)
				{
					x = (b * outerRectangleSize.Y - d * outerRectangleSize.X) / bcMad;
					y = (c * outerRectangleSize.X - a * outerRectangleSize.Y) / bcMad;
					area = x * y;
					if (maxArea < area)
					{
						maxArea = area;
						sizeX = x;
						sizeY = y;
					}
				}
			}

			{
				// solution2 (which does not touch the left and right walls of the outer retangle
				var eps2 = outerRectangleSize.X - outerRectangleSize.Y * (b * c + a * d) / (2 * c * d);
				if (eps2 >= 0 && eps2 < outerRectangleSize.X)
				{
					area = outerRectangleSize.Y * outerRectangleSize.Y / (4 * c * d);
					x = outerRectangleSize.Y / (2 * c);
					y = outerRectangleSize.Y / (2 * d);
					if (maxArea < area)
					{
						maxArea = area;
						sizeX = x;
						sizeY = y;
					}
				}
			}

			{
				// solution3 (which does not touch the top and bottom walls of the outer rectangle
				var eps3 = outerRectangleSize.Y - outerRectangleSize.X * (b * c + a * d) / (2 * a * b);
				if (eps3 >= 0 && eps3 < outerRectangleSize.Y)
				{
					area = outerRectangleSize.X * outerRectangleSize.X / (4 * a * b);
					x = outerRectangleSize.X / (2 * a);
					y = outerRectangleSize.X / (2 * b);
					if (maxArea < area)
					{
						maxArea = area;
						sizeX = x;
						sizeY = y;
					}
				}
			}

			RectangleD2D innerRect = new RectangleD2D();
			innerRect.ExpandToInclude(new PointD2D(sx * sizeX + rx * sizeY, ry * sizeX + sy * sizeY));
			innerRect.ExpandToInclude(new PointD2D(sx * sizeX, ry * sizeX));
			innerRect.ExpandToInclude(new PointD2D(rx * sizeY, sy * sizeY));

			var outerMiddle = outerRectangle.CenterCenter;
			var innerMiddle = innerRect.CenterCenter;

			return new RectangleD2D((outerMiddle.X - innerMiddle.X), (outerMiddle.Y - innerMiddle.Y), sizeX, sizeY);
		}
示例#3
0
		/// <summary>
		/// Creates a rectangle that includes all the provided points.
		/// </summary>
		/// <param name="points">The points that the rectangle should include.</param>
		/// <returns>The rectangle that includes all the provided points.</returns>
		/// <exception cref="System.ArgumentException">Enumeration is empty!</exception>
		public static RectangleD2D NewRectangleIncludingAllPoints(IEnumerable<PointD2D> points)
		{
			var en = points.GetEnumerator();
			if (!en.MoveNext())
				throw new ArgumentException("Enumeration is empty!", nameof(points));

			var result = new RectangleD2D(en.Current, PointD2D.Empty);

			while (en.MoveNext())
			{
				result.ExpandToInclude(en.Current);
			}

			return result;
		}
示例#4
0
        /// <summary>
        /// Calculates the dimensions of the greatest (by area) rectangle included in an outer rectangle, where the inner rectangle is rotated/sheared/scaled.
        /// </summary>
        /// <param name="outerRectangle">The outer rectangle.</param>
        /// <param name="sx">SX component of the transformation matrix that is applied to the inner rectangle.</param>
        /// <param name="rx">RX component of the transformation matrix that is applied to the inner rectangle.</param>
        /// <param name="ry">RY component of the transformation matrix that is applied to the inner rectangle.</param>
        /// <param name="sy">SY component of the transformation matrix that is applied to the inner rectangle.</param>
        /// <returns>The inner rectangle with the greatest area that fits (when transformed with the transformation elements) into the outer rectangle.
        /// The position of the returned rectangle is calculated so that it centers into the outer rectangle.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// X-Size of outer rectangle must be > 0
        /// or
        /// Y-Size of outer rectangle must be > 0
        /// </exception>
        public static RectangleD2D GetIncludedTransformedRectangle(this RectangleD2D outerRectangle, double sx, double rx, double ry, double sy)
        {
            PointD2D outerRectangleSize = outerRectangle.Size;

            if (!(outerRectangleSize.X > 0))
            {
                throw new ArgumentOutOfRangeException("X-Size of outer rectangle must be > 0");
            }
            if (!(outerRectangleSize.Y > 0))
            {
                throw new ArgumentOutOfRangeException("Y-Size of outer rectangle must be > 0");
            }

            double a = Math.Abs(sx);
            double b = Math.Abs(rx);
            double c = Math.Abs(ry);
            double d = Math.Abs(sy);

            double maxArea = 0;
            double sizeX = 0, sizeY = 0;
            double x, y, area;

            {
                // solution 1, which touches all walls
                double bcMad = b * c - a * d;
                if (bcMad != 0)
                {
                    x    = (b * outerRectangleSize.Y - d * outerRectangleSize.X) / bcMad;
                    y    = (c * outerRectangleSize.X - a * outerRectangleSize.Y) / bcMad;
                    area = x * y;
                    if (maxArea < area)
                    {
                        maxArea = area;
                        sizeX   = x;
                        sizeY   = y;
                    }
                }
            }

            {
                // solution2 (which does not touch the left and right walls of the outer retangle
                var eps2 = outerRectangleSize.X - outerRectangleSize.Y * (b * c + a * d) / (2 * c * d);
                if (eps2 >= 0 && eps2 < outerRectangleSize.X)
                {
                    area = outerRectangleSize.Y * outerRectangleSize.Y / (4 * c * d);
                    x    = outerRectangleSize.Y / (2 * c);
                    y    = outerRectangleSize.Y / (2 * d);
                    if (maxArea < area)
                    {
                        maxArea = area;
                        sizeX   = x;
                        sizeY   = y;
                    }
                }
            }

            {
                // solution3 (which does not touch the top and bottom walls of the outer rectangle
                var eps3 = outerRectangleSize.Y - outerRectangleSize.X * (b * c + a * d) / (2 * a * b);
                if (eps3 >= 0 && eps3 < outerRectangleSize.Y)
                {
                    area = outerRectangleSize.X * outerRectangleSize.X / (4 * a * b);
                    x    = outerRectangleSize.X / (2 * a);
                    y    = outerRectangleSize.X / (2 * b);
                    if (maxArea < area)
                    {
                        maxArea = area;
                        sizeX   = x;
                        sizeY   = y;
                    }
                }
            }

            var innerRect = new RectangleD2D();

            innerRect.ExpandToInclude(new PointD2D(sx * sizeX + rx * sizeY, ry * sizeX + sy * sizeY));
            innerRect.ExpandToInclude(new PointD2D(sx * sizeX, ry * sizeX));
            innerRect.ExpandToInclude(new PointD2D(rx * sizeY, sy * sizeY));

            var outerMiddle = outerRectangle.CenterCenter;
            var innerMiddle = innerRect.CenterCenter;

            return(new RectangleD2D((outerMiddle.X - innerMiddle.X), (outerMiddle.Y - innerMiddle.Y), sizeX, sizeY));
        }
		/// <summary>
		/// Handles the mouse move event.
		/// </summary>
		/// <param name="position">Mouse position.</param>
		/// <param name="e">MouseEventArgs as provided by the view.</param>
		/// <returns>The next mouse state handler that should handle mouse events.</returns>
		public override void OnMouseMove(PointD2D position, MouseEventArgs e)
		{
			base.OnMouseMove(position, e);

			if (null != ActiveGrip)
			{
				PointD2D graphCoord = _grac.ConvertMouseToRootLayerCoordinates(position);
				ActiveGrip.MoveGrip(graphCoord);
				_wereObjectsMoved = true;
				_grac.RenderOverlay();
			}
			else if (e.LeftButton == MouseButtonState.Pressed)
			{
				var diffPos = position - _positionLastMouseDownInMouseCoordinates;

				var oldRect = _rectangleSelectionArea_GraphCoordinates;

				if (null != _rectangleSelectionArea_GraphCoordinates ||
						Math.Abs(diffPos.X) >= System.Windows.SystemParameters.MinimumHorizontalDragDistance ||
						Math.Abs(diffPos.Y) >= System.Windows.SystemParameters.MinimumHorizontalDragDistance)
				{
					if (null == _rectangleSelectionArea_GraphCoordinates)
					{
						_grac.CaptureMouse();
					}

					var pt1 = _grac.ConvertMouseToRootLayerCoordinates(_positionLastMouseDownInMouseCoordinates);
					var rect = new RectangleD2D(pt1, PointD2D.Empty);
					rect.ExpandToInclude(_grac.ConvertMouseToRootLayerCoordinates(position));
					_rectangleSelectionArea_GraphCoordinates = rect;
				}
				if (null != _rectangleSelectionArea_GraphCoordinates)
					_grac.RenderOverlay();
			}
		}
示例#6
0
		/// <summary>
		/// Gets the absolute enclosing rectangle, taking into account ScaleX, ScaleY, Rotation and Shear (SSRS).
		/// </summary>
		/// <returns>The enclosing rectangle in absolute values.</returns>
		public RectangleD2D GetAbsoluteEnclosingRectangle()
		{
			MatrixD2D m = new MatrixD2D();
			m.SetTranslationRotationShearxScale(AbsolutePivotPositionX, AbsolutePivotPositionY, -Rotation, ShearX, ScaleX, ScaleY);
			m.TranslatePrepend(AbsoluteVectorPivotToLeftUpper.X, AbsoluteVectorPivotToLeftUpper.Y);

			var s = this.AbsoluteSize;
			var p1 = m.TransformPoint(new PointD2D(0, 0));
			var p2 = m.TransformPoint(new PointD2D(s.X, 0));
			var p3 = m.TransformPoint(new PointD2D(0, s.Y));
			var p4 = m.TransformPoint(new PointD2D(s.X, s.Y));

			var r = new RectangleD2D(p1, PointD2D.Empty);
			r.ExpandToInclude(p2);
			r.ExpandToInclude(p3);
			r.ExpandToInclude(p4);
			return r;
		}