/ManejadorDeMapa/ManejadorDeMapa/PolygonF.cs
# · C# · 464 lines · 297 code · 58 blank · 109 comment · 26 complexity · b2b7848bc8d60d8d827bb0b49a36535f MD5 · raw file
- // From http://www.developingfor.net/free-code/polygonf
-
- using System;
- using System.Drawing;
- using System.Collections.Generic;
- using System.Text;
-
- namespace SWallTech.Drawing.Shapes
- {
- /// <summary>
- /// A Class representing a Polygon formed by an array of PointF objects.
- /// PolygonF objects are immutable.
- /// </summary>
- public class PolygonF
- {
- private PointF[] _pts;
- private float _minx = 0;
- private float _miny = 0;
- private float _maxx = 0;
- private float _maxy = 0;
- private float _xlength = 0;
- private float _ylength = 0;
-
- private PolygonF()
- {
-
- }
-
- /// <summary>
- /// Creates a new instance of a PolygonF based on the PointF[].
- /// </summary>
- /// <param name="pts">The array of PointF used to create the PolygonF.</param>
- public PolygonF(PointF[] pts)
- {
- Points = pts;
- }
-
- private PointF[] Points
- {
- get { return _pts; }
- set
- {
- _pts = value;
- _minx = _pts[0].X;
- _maxx = _pts[0].X;
- _miny = _pts[0].Y;
- _maxy = _pts[0].Y;
-
- foreach (PointF pt in _pts)
- {
- if (pt.X < _minx)
- {
- _minx = pt.X;
- }
-
- if (pt.X > _maxx)
- {
- _maxx = pt.X;
- }
-
- if (pt.Y < _miny)
- {
- _miny = pt.Y;
- }
-
- if (pt.Y > _maxy)
- {
- _maxy = pt.Y;
- }
- }
-
- _xlength = Math.Abs(_maxx - _minx);
- _ylength = Math.Abs(_maxy - _miny);
- }
- }
-
- /// <summary>
- /// The Rectangular Bounds of the Polygon.
- /// </summary>
- public RectangleF Bounds
- {
- get
- {
- return new RectangleF(_minx, _miny, _maxx - _minx, _maxy - _miny);
- }
- }
-
- /// <summary>
- /// The Minimum X coordinate value in the PointF collection.
- /// </summary>
- public float MinimumX
- {
- get { return _minx; }
- }
-
- /// <summary>
- /// The Maximum X coordinate value in the PointF collection.
- /// </summary>
- public float MaximumX
- {
- get { return _maxx; }
- }
-
- /// <summary>
- /// The Minimum Y coordinate value in the PointF collection.
- /// </summary>
- public float MinimumY
- {
- get { return _miny; }
- }
-
- /// <summary>
- /// The Maximum Y coordinate value in the PointF collection.
- /// </summary>
- public float MaximumY
- {
- get { return _maxy; }
- }
-
- /// <summary>
- /// The number of Points in the Polygon.
- /// </summary>
- public int NumberOfPoints
- {
- get { return _pts.Length; }
- }
-
- /// <summary>
- /// Compares the supplied point and determines whether or not it is inside the Rectangular Bounds
- /// of the Polygon.
- /// </summary>
- /// <param name="pt">The PointF to compare.</param>
- /// <returns>True if the PointF is within the Rectangular Bounds, False if it is not.</returns>
- public bool IsInBounds(PointF pt)
- {
- return Bounds.Contains(pt);
- }
-
- /// <summary>
- /// Compares the supplied point and determines whether or not it is inside the Actual Bounds
- /// of the Polygon.
- /// </summary>
- /// <remarks>The calculation formula was converted from the C version available at
- /// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
- /// </remarks>
- /// <param name="pt">The PointF to compare.</param>
- /// <returns>True if the PointF is within the Actual Bounds, False if it is not.</returns>
- public bool Contains(PointF pt)
- {
- bool isIn = false;
-
- if (IsInBounds(pt))
- {
- int i, j = 0;
-
- // The following code is converted from a C version found at
- // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
- for (i = 0, j = NumberOfPoints - 1; i < NumberOfPoints; j = i++)
- {
- if (
- (
- ((_pts[i].Y <= pt.Y) && (pt.Y < _pts[j].Y)) || ((_pts[j].Y <= pt.Y) && (pt.Y < _pts[i].Y))
- ) &&
- (pt.X < (_pts[j].X - _pts[i].X) * (pt.Y - _pts[i].Y) / (_pts[j].Y - _pts[i].Y) + _pts[i].X)
- )
- {
- isIn = !isIn;
- }
- }
- }
-
- return isIn;
- }
-
- /// <summary>
- /// Returns the PointF that represents the center of the Rectangular Bounds of the Polygon.
- /// </summary>
- public PointF CenterPointOfBounds
- {
- get
- {
- float x = _minx + (_xlength / 2);
- float y = _miny + (_ylength / 2);
- return new PointF(x, y);
- }
- }
-
- /// <summary>
- /// NOT YET IMPLEMENTED. Currently returns the same as CenterPointOfBounds.
- /// This is intended to be the Visual Center of the Polygon, and will be implemented
- /// once I can figure out how to calculate that Point.
- /// </summary>
- public PointF CenterPoint
- {
- get
- {
- PointF pt = CenterPointOfBounds;
-
-
- return pt;
- }
- }
-
- /// <summary>
- /// Calculates the Area of the Polygon.
- /// </summary>
- public decimal Area
- {
- get
- {
- decimal xy = 0M;
- for (int i = 0; i < _pts.Length; i++)
- {
- PointF pt1;
- PointF pt2;
- if (i == _pts.Length - 1)
- {
- pt1 = _pts[i];
- pt2 = _pts[0];
- }
- else
- {
- pt1 = _pts[i];
- pt2 = _pts[i + 1];
- }
- xy += Convert.ToDecimal(pt1.X * pt2.Y);
- xy -= Convert.ToDecimal(pt1.Y * pt2.X);
- }
-
- decimal area = Convert.ToDecimal(Math.Abs(xy)) * .5M;
-
- return area;
- }
- }
- }
-
- /// <summary>
- /// A Class representing a Polygon formed by an array of Point objects.
- /// Polygon objects are immutable.
- /// </summary>
- public class Polygon
- {
- private Point[] _pts;
- private int _minx = 0;
- private int _miny = 0;
- private int _maxx = 0;
- private int _maxy = 0;
- private int _xlength = 0;
- private int _ylength = 0;
-
- private Polygon()
- {
-
- }
-
- /// <summary>
- /// Creates a new instance of a Polygon based on the Point[].
- /// </summary>
- /// <param name="pts">The array of Point used to create the Polygon.</param>
- public Polygon(Point[] pts)
- {
- Points = pts;
- }
-
- private Point[] Points
- {
- get { return _pts; }
- set
- {
- _pts = value;
- _minx = _pts[0].X;
- _maxx = _pts[0].X;
- _miny = _pts[0].Y;
- _maxy = _pts[0].Y;
-
- foreach (Point pt in _pts)
- {
- if (pt.X < _minx)
- {
- _minx = pt.X;
- }
-
- if (pt.X > _maxx)
- {
- _maxx = pt.X;
- }
-
- if (pt.Y < _miny)
- {
- _miny = pt.Y;
- }
-
- if (pt.Y > _maxy)
- {
- _maxy = pt.Y;
- }
- }
-
- _xlength = Math.Abs(_maxx - _minx);
- _ylength = Math.Abs(_maxy - _miny);
- }
- }
-
- /// <summary>
- /// The Rectangular Bounds of the Polygon.
- /// </summary>
- public Rectangle Bounds
- {
- get
- {
- return new Rectangle(_minx, _miny, _maxx - _minx, _maxy - _miny);
- }
- }
-
- /// <summary>
- /// The Minimum X coordinate value in the PointF collection.
- /// </summary>
- public int MinimumX
- {
- get { return _minx; }
- }
-
- /// <summary>
- /// The Maximum X coordinate value in the PointF collection.
- /// </summary>
- public int MaximumX
- {
- get { return _maxx; }
- }
-
- /// <summary>
- /// The Minimum Y coordinate value in the PointF collection.
- /// </summary>
- public int MinimumY
- {
- get { return _miny; }
- }
-
- /// <summary>
- /// The Maximum Y coordinate value in the PointF collection.
- /// </summary>
- public int MaximumY
- {
- get { return _maxy; }
- }
-
- /// <summary>
- /// The number of Points in the Polygon.
- /// </summary>
- public int NumberOfPoints
- {
- get { return _pts.Length; }
- }
-
- /// <summary>
- /// Compares the supplied point and determines whether or not it is inside the Rectangular Bounds
- /// of the Polygon.
- /// </summary>
- /// <param name="pt">The PointF to compare.</param>
- /// <returns>True if the PointF is within the Rectangular Bounds, False if it is not.</returns>
- public bool IsInBounds(Point pt)
- {
- return Bounds.Contains(pt);
- }
-
- /// <summary>
- /// Compares the supplied point and determines whether or not it is inside the Actual Bounds
- /// of the Polygon.
- /// </summary>
- /// <remarks>The calculation formula was converted from the C version available at
- /// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
- /// </remarks>
- /// <param name="pt">The PointF to compare.</param>
- /// <returns>True if the PointF is within the Actual Bounds, False if it is not.</returns>
- public bool Contains(Point pt)
- {
- bool isIn = false;
-
- if (IsInBounds(pt))
- {
- int i, j = 0;
-
- // The following code is converted from a C version found at
- // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
- for (i = 0, j = NumberOfPoints - 1; i < NumberOfPoints; j = i++)
- {
- if (
- (
- ((_pts[i].Y <= pt.Y) && (pt.Y < _pts[j].Y)) || ((_pts[j].Y <= pt.Y) && (pt.Y < _pts[i].Y))
- ) &&
- (pt.X < (_pts[j].X - _pts[i].X) * (pt.Y - _pts[i].Y) / (_pts[j].Y - _pts[i].Y) + _pts[i].X)
- )
- {
- isIn = !isIn;
- }
- }
- }
-
- return isIn;
- }
-
- /// <summary>
- /// Returns the PointF that represents the center of the Rectangular Bounds of the Polygon.
- /// </summary>
- public Point CenterPointOfBounds
- {
- get
- {
- int x = _minx + (_xlength / 2);
- int y = _miny + (_ylength / 2);
- return new Point(x, y);
- }
- }
-
- /// <summary>
- /// NOT YET IMPLEMENTED. Currently returns the same as CenterPointOfBounds.
- /// This is intended to be the Visual Center of the Polygon, and will be implemented
- /// once I can figure out how to calculate that Point.
- /// </summary>
- public Point CenterPoint
- {
- get
- {
- Point pt = CenterPointOfBounds;
-
-
- return pt;
- }
- }
-
- /// <summary>
- /// Calculates the Area of the Polygon.
- /// </summary>
- public decimal Area
- {
- get
- {
- decimal xy = 0M;
- for (int i = 0; i < _pts.Length; i++)
- {
- Point pt1;
- Point pt2;
- if (i == _pts.Length - 1)
- {
- pt1 = _pts[i];
- pt2 = _pts[0];
- }
- else
- {
- pt1 = _pts[i];
- pt2 = _pts[i + 1];
- }
- xy += Convert.ToDecimal(pt1.X * pt2.Y);
- xy -= Convert.ToDecimal(pt1.Y * pt2.X);
- }
-
- decimal area = Convert.ToDecimal(Math.Abs(xy)) * .5M;
-
- return area;
- }
- }
- }
-
- }