Click here to Skip to main content
15,879,096 members
Articles / Programming Languages / C#

What can be simpler than graphical primitives? Part 3

Rate me:
Please Sign up or sign in to vote.
5.00/5 (8 votes)
8 Apr 2013CPOL43 min read 23.7K   559   32  
using System;
using System .Collections .Generic;
using System .ComponentModel;
using System .Drawing;
using System .Drawing .Drawing2D;
using System .Windows .Forms;
using Microsoft .Win32;

using MoveGraphLibrary;

namespace GraphicalPrimitives
{
    public class Circle : GraphicalObject
    {
        int m_version = 620;
        Form form;
        Mover supervisor;
        PointF m_center;
        float m_radius;
        double m_angle;
        int nNodesOnBorder;

        double [] vals;
        double [] sweep;
        List<Color> clrs = new List<Color> ();          // one color per each sector
        Rotation dirDrawing;

        double compensation;
        PointF ptNearestToCenter, ptFarAway;

        int minRadius = 10;   // min size is set to avoid disappearance while resizing
        int nrSmall = 5;
        int distanceNeighbours = 8;
        Pen penInnerBorder;

        // -------------------------------------------------
        public Circle (Form frm, Mover mvr, PointF ptC, float rad, double angleDegree, double [] fVals)
        {
            form = frm;
            supervisor = mvr;
            m_center = ptC;
            m_radius = Math .Max (rad, minRadius);
            m_angle = Auxi_Convert .DegreeToRadian (angleDegree);
            dirDrawing = Rotation .Clockwise;
            penInnerBorder = new Pen (Color .DarkGray);
            CheckedValues (fVals);
            DefaultColors ();
            NodesOnBorder ();
        }
        // -------------------------------------------------
        public Circle (Form frm, Mover mvr, PointF ptC, float rad, Color clr)
            : this (frm, mvr, ptC, rad, 0, new double [] { 5 })
        {
            clrs [0] = clr;
        }
        // -------------------------------------------------
        public Circle (Form frm, Mover mvr, PointF ptC, float rad, double [] fVals, Color clr_0, Color clr_1)
            : this (frm, mvr, ptC, rad, 0, fVals)
        {
            SetColors (Auxi_Colours .SmoothColorsList (fVals .Length, clr_0, clr_1));
        }
        // -------------------------------------------------        NodesOnBorder
        private void NodesOnBorder ()
        {
            nNodesOnBorder = Convert .ToInt32 ((2 * Math .PI * m_radius) / distanceNeighbours);
        }
        // -------------------------------------------------        CheckedValues
        private void CheckedValues (double [] fVals)
        {
            bool bCorrect = true;
            if (fVals == null || fVals .Length < 1 || Auxi_Common .SumArray (fVals, true) == 0.0)
            {
                bCorrect = false;
            }
            else
            {
                foreach (double val in fVals)
                {
                    if (val <= 0.0)
                    {
                        bCorrect = false;
                        break;
                    }
                }
            }
            if (!bCorrect)
            {
                vals = new double [] { 1, 2, 3, 4 };
            }
            else
            {
                vals = new double [fVals .Length];
                for (int i = 0; i < vals .Length; i++)
                {
                    vals [i] = fVals [i];
                }
            }
            sweep = new double [vals .Length];
            SweepAngles ();
        }
        // -------------------------------------------------        DefaultColors
        public void DefaultColors ()
        {
            clrs .Clear ();
            for (int i = 0; i < vals .Length; i++)
            {
                clrs .Add (Auxi_Colours .ColorPredefined (i + 1));
            }
        }
        // -------------------------------------------------        SweepAngles
        private void SweepAngles ()
        {
            double fSum = Auxi_Common .SumArray (vals, false);
            for (int i = 0; i < vals .Length; i++)
            {
                sweep [i] = 2 * Math .PI * vals [i] / fSum;
            }
            if (dirDrawing == Rotation .Clockwise)
            {
                for (int i = 0; i < vals .Length; i++)
                {
                    sweep [i] *= -1;
                }
            }
        }
        // -------------------------------------------------        Center
        public PointF Center
        {
            get { return (m_center); }
            set
            {
                m_center = value;
                DefineCover ();
            }
        }
        // -------------------------------------------------        Radius
        public float Radius
        {
            get { return (m_radius); }
            set
            {
                m_radius = Math .Max (minRadius, value);
                DefineCover ();
            }
        }
        // -------------------------------------------------        RectAround
        new public RectangleF RectAround
        {
            get { return (new RectangleF (m_center .X - m_radius, m_center .Y - m_radius, 2 * m_radius, 2 * m_radius)); }
        }
        // -------------------------------------------------        Values
        public double [] Values
        {
            get { return (vals); }
        }
        // -------------------------------------------------        Angle
        public double Angle
        {
            get { return (m_angle); }
            set { m_angle = Auxi_Common .LimitedRadian (value); }
        }
        // -------------------------------------------------        Color
        public Color Color
        {
            get { return (clrs [0]); }
            set { clrs [0] = value; }
        }
        // -------------------------------------------------        Colors
        public List<Color> Colors
        {
            get { return (clrs); }
        }
        // -------------------------------------------------        SetColors
        public void SetColors (List<Color> colors)
        {
            if (colors != null)
            {
                for (int i = 0; i < Math .Min (clrs .Count, colors .Count); i++)
                {
                    clrs [i] = colors [i];
                }
            }
        }
        // -------------------------------------------------        SetColors
        public void SetColors (Color [] clrsNew)
        {
            if (clrs .Count == clrsNew .Length)
            {
                for (int i = 0; i < clrs .Count; i++)
                {
                    clrs [i] = clrsNew [i];
                }
            }
        }
        // -------------------------------------------------        DrawingDirection
        public Rotation DrawingDirection
        {
            get { return (dirDrawing); }
            set
            {
                dirDrawing = value;
                SweepAngles ();
            }
        }
        // -------------------------------------------------        ChangeDrawingDirection
        public void ChangeDrawingDirection ()
        {
            dirDrawing = (dirDrawing == Rotation .Clockwise) ? Rotation .Counterclock : Rotation .Clockwise;
            SweepAngles ();
        }
        // -------------------------------------------------        Draw
        public void Draw (Graphics grfx)
        {
            Rectangle rc = Rectangle .Round (RectAround);
            float fStartDegree, fSweepDegree;
            fStartDegree = -(float) Auxi_Convert .RadianToDegree (m_angle);
            for (int i = 0; i < vals .Length; i++)
            {
                fSweepDegree = -(float) Auxi_Convert .RadianToDegree (sweep [i]);
                grfx .FillPie (new SolidBrush (clrs [i]), rc, fStartDegree, fSweepDegree);
                fStartDegree += fSweepDegree;
            }
            grfx .DrawLine (penInnerBorder, m_center, Auxi_Geometry .PointToPoint (m_center, m_angle, m_radius));
        }
        // -------------------------------------------------        StartResizing
        public void StartResizing (Point ptMouse, int iNode)
        {
            double angleBeam = Auxi_Geometry .Line_Angle (m_center, ptMouse);
            PointF ptOnBorder = Auxi_Geometry .PointToPoint (m_center, angleBeam, m_radius);
            Cursor .Position = form .PointToScreen (Point .Round (ptOnBorder));
            ptNearestToCenter = Auxi_Geometry .PointToPoint (m_center, angleBeam, minRadius);
            ptFarAway = Auxi_Geometry .PointToPoint (m_center, angleBeam, 4000);
        }
        // -------------------------------------------------        StopResizing
        public void StopResizing ()
        {
            NodesOnBorder ();
            DefineCover ();
        }
        // -------------------------------------------------        StartRotation
        public void StartRotation (Point ptMouse)
        {
            double angleMouse = Auxi_Geometry .Line_Angle (m_center, ptMouse);
            compensation = Auxi_Common .LimitedRadian (angleMouse - m_angle);
        }
        // -------------------------------------------------        DefineCover
        public override void DefineCover ()
        {
            CoverNode [] nodes = new CoverNode [nNodesOnBorder + 1];
            for (int i = 0; i < nNodesOnBorder; i++)
            {
                nodes [i] = new CoverNode (i, Auxi_Geometry .PointToPoint (m_center, 2 * Math .PI * i / nNodesOnBorder, m_radius), nrSmall);
            }
            nodes [nNodesOnBorder] = new CoverNode (nNodesOnBorder, m_center, m_radius, Cursors .SizeAll);
            cover = new Cover (nodes);
            cover .SetClearance (false);
        }
        // -------------------------------------------------
        public override void Move (int dx, int dy)
        {
            m_center += new Size (dx, dy);
        }
        // -------------------------------------------------        MoveNode
        public override bool MoveNode (int i, int dx, int dy, Point ptM, MouseButtons catcher)
        {
            bool bRet = false;

            if (catcher == MouseButtons .Left)
            {
                if (i == nNodesOnBorder)
                {
                    Move (dx, dy);
                }
                else
                {
                    PointF ptBase, ptNearest;
                    PointOfSegment typeOfNearest;
                    Auxi_Geometry .Distance_PointSegment (ptM, ptNearestToCenter, ptFarAway, out ptBase, out typeOfNearest, out ptNearest);
                    Cursor .Position = form .PointToScreen (Point .Round (ptNearest));
                    m_radius = Convert .ToSingle (Auxi_Geometry .Distance (m_center, ptNearest));
                    bRet = true;
                }
            }
            else if (catcher == MouseButtons .Right)
            {
                double angleMouse = Auxi_Geometry .Line_Angle (m_center, ptM);
                m_angle = angleMouse - compensation;
                bRet = true;
            }
            return (bRet);
        }

        const string nameMain = "Circle_";
        // -------------------------------------------------        IntoRegistry
        public void IntoRegistry (RegistryKey regkey, string strAdd)
        {
            try
            {
                string [] strs = new string [5 + vals .Length + 4 * vals .Length + 1];
                strs [0] = m_version .ToString ();
                strs [1] = m_center .X .ToString ();                            // ptC
                strs [2] = m_center .Y .ToString ();
                strs [3] = m_radius .ToString ();                               // radius
                strs [4] = Auxi_Convert .RadianToDegree (Angle) .ToString ();   // angleDegree
                for (int i = 0; i < vals .Length; i++)                          // vals
                {
                    strs [5 + i] = vals [i] .ToString ();
                }
                int k = 5 + vals .Length;
                for (int i = 0; i < vals .Length; i++)                          // clrs
                {
                    strs [k + i * 4]     = ((int) (clrs [i] .A)) .ToString ();
                    strs [k + i * 4 + 1] = ((int) (clrs [i] .R)) .ToString ();
                    strs [k + i * 4 + 2] = ((int) (clrs [i] .G)) .ToString ();
                    strs [k + i * 4 + 3] = ((int) (clrs [i] .B)) .ToString ();
                }
                k += 4 * vals .Length;
                strs [k] = ((int) dirDrawing) .ToString ();

                regkey .SetValue (nameMain + strAdd, strs, RegistryValueKind .MultiString);
            }
            catch
            {
            }
            finally
            {
            }
        }
        // -------------------------------------------------        FromRegistry
        public static Circle FromRegistry (Form frm, Mover mvr, RegistryKey regkey, string strAdd)
        {
            try
            {
                string [] strs = (string []) regkey .GetValue (nameMain + strAdd);
                if (frm == null || mvr == null ||
                    strs == null || strs .Length < 11 || Convert .ToInt32 (strs [0]) != 620)
                {
                    return (null);
                }
                int nVals = (strs .Length - 6) / 5;
                double [] fVals = new double [nVals];
                List<Color> colors = new List<Color> ();
                int j_vals = 5;
                int j_clrs = j_vals + nVals;
                int j_dir = j_clrs + 4 * nVals;
                for (int i = 0; i < nVals; i++)
                {
                    fVals [i] = Convert .ToDouble (strs [j_vals + i]);
                    colors .Add (Auxi_Convert .ToColor (strs, j_clrs + i * 4));
                }
                Circle circle = new Circle (frm, mvr, 
                                            Auxi_Convert .ToPointF (strs, 1),               // ptC
                                            Convert .ToSingle (strs [3]),                   // radius
                                            Convert .ToDouble (strs [4]),                   // angle
                                            fVals); 
                if (circle != null)
                {
                    circle .SetColors (colors);
                    circle .DrawingDirection = (Rotation) Convert .ToInt32 (strs [j_dir]);
                }
                return (circle);
            }
            catch
            {
                return (null);
            }
            finally
            {
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions