Flowerpower! Drawing in polar coordinates in C#.

ddanbe 2 Tallied Votes 998 Views Share

What polar coordinates are is explained here.
I wanted to draw some polar functions myself, so I changed my plotting class a bit and added a polar struct to a new project.. Just posted code for the Plot class and the polar point structure here. You can find an example of output as well, and the complete project in a zip file.
This is just a basic thingy, so error correction is also basic. Enjoy! :)

kvprajapati commented: cool! +15
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace PolarFlowers
{
    /// <summary>
    /// class to plot x and y values on a Form or Panel
    /// 
    /// Because on the form coordinates start at the upper left corner with 0,0
    /// with the y coordinate going down, a little transformation is done here
    /// so that x,y coordinates act as normal carthesian coordinates, with 0,0
    /// in the center of the Form or Panel
    /// </summary>
    class Plot
    {
        
        struct PlotPort
        {
            public int minX;
            public int maxX;
            public int minY;
            public int maxY;
        };

        private PlotPort _PlotW;    //"window" of carthesian coordinates
        private Size _ClientArea;   //keeps the pixels info
        private float _Xspan;
        private float _Yspan;

        public Plot() { }

        public Plot(Size Plotarea)
        {
            _ClientArea = Plotarea;
        }

        public Size ClientArea { set { _ClientArea = value; } }

        /// <summary>
        /// Set the bounderies of the form(screen) to real(world) coordinates.
        /// </summary>
        /// <param name="minx">lowest x value</param>
        /// <param name="maxx">highest x value</param>
        /// <param name="miny">lowest y value</param>
        /// <param name="maxy">highest y value</param>
        public void SetPlotPort(int minx, int maxx, int miny, int maxy)
        {
            //set the bounderies of the form(screen) to real coordinates.
            _PlotW.minX = minx;
            _PlotW.maxX = maxx;
            _PlotW.minY = miny;
            _PlotW.maxY = maxy;
            _Xspan = _PlotW.maxX - _PlotW.minX;
            _Yspan = _PlotW.maxY - _PlotW.minY;
        }

        public void PlotPixel(PointF P, Color C, Graphics G)
        {
            //workhorse of this class
            Bitmap bm = new Bitmap(1, 1);
            bm.SetPixel(0, 0, C);
            P = ToScreen(P);
            G.DrawImageUnscaled(bm, (int)P.X, (int)P.Y);
        }

        public void PlotAxes(Graphics G)
        {
            Pen AxisPen = new Pen(Color.Red);
            AxisPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
            // X-Axis
            PointF X0 = new PointF( _PlotW.minX, _PlotW.minY + _Yspan / 2f);
            PointF X1 = new PointF( _PlotW.maxX, _PlotW.minY + _Yspan / 2f);
            //Y-Axis
            PointF Y0 = new PointF(_PlotW.minX + _Xspan / 2f, _PlotW.maxY);
            PointF Y1 = new PointF(_PlotW.minX + _Xspan / 2f, _PlotW.minY);

            G.DrawLine(AxisPen, ToScreen(X0), ToScreen(X1));
            G.DrawLine(AxisPen, ToScreen(Y0), ToScreen(Y1));

        }

        /// <summary>
        /// Plot a list of carthesian points on the screen
        /// </summary>
        /// <param name="thePts"></param>
        /// <param name="G"></param>
        public void PlotPoints(List<PointF> thePts,Pen P, Graphics G)
        {
            //for (int k = 1; k < thePts.Count; k++)
            //{
            //    G.DrawLine(P, ToScreen(thePts[k - 1]), ToScreen(thePts[k]));
            //}
            PointF[] PtAr = thePts.ToArray();
            for (int k = 0; k < PtAr.Length; k++)
            {
                PtAr[k] = ToScreen(PtAr[k]);
            }
            G.DrawLines(P, PtAr);
        }

        /// <summary>
        /// Transform a point incarthesian coordinates to a point on the screen
        /// </summary>
        /// <param name="ptC">The point in carthesian(world) coordinates</param>
        /// <returns>Transformed point to be plotted on the screen</returns>
        private PointF ToScreen(PointF ptC)
        {
            PointF aP = new PointF();
            aP.X = _ClientArea.Width / _Xspan * ptC.X + _ClientArea.Width / 2f;
            aP.Y = _ClientArea.Height / _Yspan * ptC.Y + _ClientArea.Height / 2f;
            return aP;
        }
    }
}

//******************************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace PolarFlowers
{
    /// <summary>
    /// A polar point defined by the radius (r) and the angle (Theta)
    /// </summary>
    public struct PolarPointF
    {        
        public PolarPointF(float r, float Theta) : this()
        {
            this.r = r;
            this.Theta = Theta;
        }
        
        public float r { get; set; }

        public float Theta { get; set; }

        /// <summary>
        /// Converts a polar point to a carthesian coordinates, with Theta expressed in radians
        /// </summary>
        /// <returns>A PointF structure</returns>
        public PointF ToCarthesian()
        {
            return new PointF((float)(this.r * Math.Cos(this.Theta)), (float)(this.r * Math.Sin(this.Theta)));
        }

        /// <summary>
        /// Converts a PointF, representing carthesian coordinates to a PolarPointF
        /// </summary>
        /// <param name="P"></param>
        /// <returns></returns>
        public static PolarPointF FromCarthesian(PointF P)
        {
            float r = (float)Math.Sqrt(P.X * P.X + P.Y * P.Y);
            float Theta = (float)Math.Atan2(P.X, P.Y); // arctan with a "twist", see the Math class
            return new PolarPointF(r, Theta);
        }
    }
}