简体   繁体   中英

C# drawing a picture in panel

轮辐的圆圈,沿其边缘有8个较小的编号圆圈

I am trying to draw the above image in a panel. I am using C#. I want the user to be able to enter the number of smaller circle they want. right now it has 1-8 but the user can add more like 1-20 or just do 1-4 . here is the code I have so for: Update 2 !!!

 const double Deg2Rad = Math.PI / 180d;
        const int circle_count = 20;

        int cubePanelSize = Math.Min(this.Cube_Panel.Width, this.Cube_Panel.Height);

        int innerSize = cubePanelSize / 3;
        int outerSize = cubePanelSize / 10;

        int centre_X = this.Cube_Panel.Width / 2 ;
        int centre_Y = this.Cube_Panel.Height / 2;

        float centre_X2 = this.Cube_Panel.Width / 2F - 10F;
        float centre_Y2 = this.Cube_Panel.Height / 2F - 10F; 
        float outerSize_x = 4F;
        float outerSize_y = 4F;

        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        Pen p1 = new Pen(Color.Black, 1);
        double step = 360d / circle_count;

        for (double angle = 0; angle < 360d; angle += step)
        {
            int X = (int)(centre_X + Math.Cos(angle * Deg2Rad) * innerSize);
            int Y = (int)(centre_Y + Math.Sin(angle * Deg2Rad) * innerSize);

            e.Graphics.FillEllipse(Brushes.Green, new Rectangle(X - (outerSize / 2), Y - (outerSize / 2), outerSize / 2, outerSize / 2));
            e.Graphics.DrawLine(p1, centre_X2, centre_Y2, X - (outerSize / outerSize_x) , Y - (outerSize / outerSize_y) );
        }

        Graphics l = e.Graphics;
        Pen p = new Pen(Color.Gray, 5);
        int temp1 = centre_X - (innerSize + -20);
        int temp2 = centre_Y - (innerSize + -20);
        int temp3 = Convert.ToInt16(innerSize * 1.55);
        int temp4 = Convert.ToInt16(innerSize * 1.55);
        l.DrawEllipse(p,temp1 , temp2, temp3 , temp4);
        l.Dispose();

This is how C# is drawing the picture

it is a lot better but is still off some... the lines should stop inside of the inner circle , I have been trying to get that to work but that pic is the best I am seem to get.

also how do I add the numbers ?

Don't know if this helps you at all. I played around with your code a little. I wasn't sure what Cube_Panel was so I just replaced it with (this.) which was the form I was testing with. There's a few other changes, but hopefully they aren't too drastic.

I'm not completely sure what you were trying to do with Math.Sin and Math.Cos, but supplying a fixed 180 degrees probably won't help. You need to work out the angle around the circle that you need to calculate. Bear in mind, too, that Math.Sin and Math.Cos take angle in radians not degrees (180 radians = ~10313.2 degrees).

Instead of looping with the count of circles, I used the angle I wanted the circle to be drawn at. Incrementing with a pre-calculated angle step. Does that make sense?

EDIT: I've added a docked Cube_Panel Panel control to the form and let it handle the painting. I've also changed the code so that it adapts to the size of the Cube_Panel (which should change if the Form is resized).

EDIT2: Hmm. I made a few mistakes in my previous code. It happened to work, but there were still problems with it. I've updated my code and hopefully you'll understand what I'm doing and will be able to adapt your code to suit.

You'll notice I changed the names of some of the variables. This is to give a better idea (hopefully) of what they're actually doing.

So, for the lines... I'll draw your attention to this code:

int dotCentreX = (int)(centre_X + Math.Cos(angle * Deg2Rad) * outerEllipseRadius);
int dotCentreY = (int)(centre_Y + Math.Sin(angle * Deg2Rad) * outerEllipseRadius);

What we're doing is calculating the centre point for the outer dots. centre_X and centre_Y provide an overall offset (the centre of the whole diagram). Math.Cos and Math.Sin work with the angle to give you a normalised (values between -1 and 1) circle. I'm then multiplying this by outerEllipseRadius to expand the size of the circle to where we want.

For the lines, we don't want to go all the way out to the outerEllipseRadius . We want to stop at the inner radius ( innerEllipseRadius ). So we calculate positions for those points:

int lineEndX = (int)(centre_X + Math.Cos(angle * Deg2Rad) * innerEllipseRadius);
int lineEndY = (int)(centre_Y + Math.Sin(angle * Deg2Rad) * innerEllipseRadius);

We can then draw the line from the centre to that point.

For the numbers, you'd need to draw the text at an offset to the dots. You have the centre of the dot and you know how big it is. So you just need to calculate dotCentreX + (whateverOffsetWorksForYouX) and dotCentreY + (whateverOffsetWorksForYouY) .

Hope that helps.

namespace WindowsFormsApp1
{
    using System;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Cube_Panel.Paint += Cube_Panel_Paint;
            this.Cube_Panel.Resize += (s, e) => { this.Cube_Panel.Refresh(); };
        }

        private void Cube_Panel_Paint(object sender, PaintEventArgs e)
        {
            const double Deg2Rad = Math.PI / 180d;
            const int circle_count = 9;

            int cubePanelSize = Math.Min(Cube_Panel.Width, Cube_Panel.Height);

            int innerEllipseRadius = cubePanelSize / 4;
            int outerEllipseRadius = cubePanelSize / 3;
            int outerDotDiameter = cubePanelSize / 14;

            int centre_X = Cube_Panel.Width / 2;
            int centre_Y = Cube_Panel.Height / 2;

            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            Pen p1 = new Pen(Color.Black, 1);

            double step = 360d / circle_count;

            for (double angle = 0; angle < 360d; angle += step)
            {
                int dotCentreX = (int)(centre_X + Math.Cos(angle * Deg2Rad) * outerEllipseRadius);
                int dotCentreY = (int)(centre_Y + Math.Sin(angle * Deg2Rad) * outerEllipseRadius);

                e.Graphics.FillEllipse(Brushes.Green, new Rectangle(dotCentreX - (outerDotDiameter / 2), dotCentreY - (outerDotDiameter / 2), outerDotDiameter, outerDotDiameter));

                int lineEndX = (int)(centre_X + Math.Cos(angle * Deg2Rad) * innerEllipseRadius);
                int lineEndY = (int)(centre_Y + Math.Sin(angle * Deg2Rad) * innerEllipseRadius);

                e.Graphics.DrawLine(p1, centre_X, centre_Y, lineEndX, lineEndY);
            }

            Graphics l = e.Graphics;
            Pen p = new Pen(Color.Gray, 5);
            l.DrawEllipse(p, centre_X - innerEllipseRadius, centre_Y - innerEllipseRadius, innerEllipseRadius * 2, innerEllipseRadius * 2);
            l.Dispose();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM