Click here to Skip to main content
15,883,705 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.8K   560   32  
using System;
using System .Collections .Generic;
using System .ComponentModel;
using System .Drawing;
using System .Drawing .Drawing2D;
using System .Windows .Forms;

using MoveGraphLibrary;

namespace GraphicalPrimitives
{
    public class Plug : GraphicalObject
    {
        int m_version = 620;
        Form form;
        Mover supervisor;

        Shape m_shape;
        PointF m_center;
        float m_radius;
        int nVertices;
        double m_angle;
        SolidBrush m_brush;

        PointF ptInnerLimit, ptOuterLimit;
        double scaling, compensation, rMouse;

        static float minRadius = 10;
        int minDelta = 3;

        // -------------------------------------------------
        public Plug (Form frm, Mover mvr, PointF pt, float rad, Color clr)
        {
            form = frm;
            supervisor = mvr;
            m_shape = Shape .Circle;
            m_center = pt;
            m_radius = Math .Max (minRadius, rad);
            nVertices = 0;
            m_angle = 0;
            m_brush = new SolidBrush (clr);
        }
        // -------------------------------------------------
        public Plug (Form frm, Mover mvr, PointF pt, float rad, int nPoints, double angleDegree, Color clr)
        {
            switch (nPoints)
            {
                case 3:
                default:
                    m_shape = Shape .Polyg_3;
                    nVertices = 3;
                    break;
                case 4:
                    m_shape = Shape .Polyg_4;
                    nVertices = 4;
                    break;
                case 5:
                    m_shape = Shape .Polyg_5;
                    nVertices = 5;
                    break;
                case 6:
                    m_shape = Shape .Polyg_6;
                    nVertices = 6;
                    break;
                case 7:
                    m_shape = Shape .Polyg_7;
                    nVertices = 7;
                    break;
                case 8:
                    m_shape = Shape .Polyg_8;
                    nVertices = 8;
                    break;
            }
            form = frm;
            supervisor = mvr;
            m_center = pt;
            m_radius = Math .Max (minRadius, rad);
            nVertices = Math .Max (3, nPoints);
            m_angle = Auxi_Convert .DegreeToRadian (angleDegree);
            m_brush = new SolidBrush (clr);
        }
        // -------------------------------------------------        Shape
        public Shape Shape
        {
            get { return (m_shape); }
        }
        // -------------------------------------------------        RectAround
        new public RectangleF RectAround
        {
            get
            {
                if (m_shape == Shape .Circle)
                {
                    return (RectangleF .FromLTRB (m_center .X - m_radius, m_center .Y - m_radius, m_center .X + m_radius, m_center .Y + m_radius));
                }
                else
                {
                    return (Auxi_Geometry .RectAroundPoints (Vertices));
                }
            }
        }
        // -------------------------------------------------        Center
        public PointF Center
        {
            get { return (m_center); }
            //set { m_center = value; }
        }
        // -------------------------------------------------        Radius
        public float Radius
        {
            get { return (m_radius); }
        }
        // -------------------------------------------------        MinimumRadius
        static public float MinimumRadius
        {
            get { return (minRadius); }
        }
        // -------------------------------------------------        VerticesNumber
        public int VerticesNumber
        {
            get { return (nVertices); }
        }
        // -------------------------------------------------        Angle
        public double Angle
        {
            get { return (m_angle); }
        }
        // -------------------------------------------------        Vertices
        public PointF [] Vertices
        {
            get { return ((m_shape == Shape .Circle) ? null : Auxi_Geometry .RegularPolygon (m_center, m_radius, nVertices, m_angle)); }
        }
        // -------------------------------------------------        Draw
        public void Draw (Graphics grfx)
        {
            if (m_shape == Shape .Circle)
            {
                Auxi_Drawing .FillEllipse (grfx, m_center, Convert .ToInt32 (m_radius), m_brush .Color);
            }
            else
            {
                grfx .FillPolygon (m_brush, Vertices);
            }
        }
        // -------------------------------------------------        StartResizing
        public void StartResizing (Point ptMouse)
        {
            PointF ptCursor;
            double angleBeam;

            if (m_shape == Shape .Circle)
            {
                angleBeam = Auxi_Geometry .Line_Angle (m_center, ptMouse);
                ptCursor = Auxi_Geometry .PointToPoint (m_center, angleBeam, m_radius);
                ptInnerLimit = Auxi_Geometry .PointToPoint (m_center, angleBeam, minRadius);
            }
            else
            {
                PointF [] pts = Vertices;
                Auxi_Geometry .Distance_PointPolyline (ptMouse, pts, true, out ptCursor);
                scaling = m_radius / Auxi_Geometry .Distance (m_center, ptCursor);          // >= 1
                angleBeam = Auxi_Geometry .Line_Angle (m_center, ptCursor);
                ptInnerLimit = Auxi_Geometry .PointToPoint (m_center, angleBeam, minRadius / scaling);
            }
            ptOuterLimit = Auxi_Geometry .PointToPoint (m_center, angleBeam, 4000);
            Cursor .Position = form .PointToScreen (Point .Round (ptCursor));
        }
        // -------------------------------------------------        StartRotation
        public void StartRotation (Point ptMouse)
        {
            double angleMouse = Auxi_Geometry .Line_Angle (m_center, ptMouse);
            compensation = Auxi_Common .LimitedRadian (angleMouse - Angle);
            rMouse = Auxi_Geometry .Distance (m_center, ptMouse);
        }
        // -------------------------------------------------        DefineCover
        public override void DefineCover ()
        {
            CoverNode [] nodes = new CoverNode [2];
            if (m_shape == Shape .Circle)
            {
                nodes [0] = new CoverNode (0, m_center, m_radius - minDelta, Cursors .SizeAll); 
                nodes [1] = new CoverNode (1, m_center, m_radius + minDelta);
            }
            else
            {
                double delta = minDelta / Math .Cos (Math .PI / nVertices);
                PointF [] ptsInside = Auxi_Geometry .RegularPolygon (m_center, m_radius - delta, nVertices, m_angle);
                PointF [] ptsOutside = Auxi_Geometry .RegularPolygon (m_center, m_radius + delta, nVertices, m_angle);
                nodes [0] = new CoverNode (0, ptsInside);
                nodes [1] = new CoverNode (1, ptsOutside, Cursors .Hand);
            }
            cover = new Cover (nodes);
        }
        // -------------------------------------------------
        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 == 0)
                {
                    Move (dx, dy);
                }
                else
                {
                    PointF ptBase, ptNearest;
                    PointOfSegment typeOfNearest;
                    Auxi_Geometry .Distance_PointSegment (ptM, ptInnerLimit, ptOuterLimit, out ptBase, out typeOfNearest, out ptNearest);
                    double dist = Auxi_Geometry .Distance (m_center, ptNearest);
                    if (m_shape == Shape .Circle)
                    {
                        m_radius = Convert .ToSingle (dist);
                    }
                    else
                    {
                        m_radius = Convert .ToSingle (dist * scaling);
                    }
                    bRet = true;
                    Cursor .Position = form .PointToScreen (Point .Round (ptNearest));
                }
            }
            else if (catcher == MouseButtons .Right)
            {
                double angleMouse = Auxi_Geometry .Line_Angle (m_center, ptM);
                m_angle = angleMouse - compensation;
                Cursor .Position = form .PointToScreen (Point .Round (Auxi_Geometry .PointToPoint (m_center, angleMouse, rMouse)));
                bRet = true;
            }
            return (bRet);
        }
    }
}

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