Home > Net >  How to draw a circle or a line that will always start from the center of the pictureBox?
How to draw a circle or a line that will always start from the center of the pictureBox?

Time:01-12

public void DrawLine(PictureBox pb, Graphics g)
        {
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.DrawEllipse(new Pen(Color.Red, 2f),
                200, 200 , 100, 100);
        }

this is drawing a circle around the center. but i'm not sure why and if the coordinates 200,200 are right i just tried many times until it looked in the center.

but if i'm changing the width and height from 100, 100 for example to 200, 200 now the circle will be drawn a bit to the right and lower and not in the center.

i tried also :

public void DrawLine(PictureBox pb, Graphics g)
        {
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.DrawEllipse(new Pen(Color.Red, 2f),
                pb.Width / 2, pb.Height / 2 , 100, 100);
        }

but that put the image also a bit to the right and lower.

i want to make that no mater what the circle size is 100,100 or 200,200 or 5,5 that it will draw the circle around the center.

after trying the solution the result is that the circle is not accurate.

this screenshot show on the left when the circle is should be at the size of the 200 kilometers circle on the image it is on the left size but not on the right size.

and when i'm making the circle much smaller the circle is not exactly around the center of the image(the center of the image is where the black lines collide meet).

circle

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;

namespace Images_Circles
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            pictureBox1.Image = Properties.Resources.clean_radar_image;

            pictureBox1.Padding = new Padding(10);
            pictureBox1.Anchor = (AnchorStyles)0xF;
            pictureBox1.SizeChanged  = (sender, e) => pictureBox1.Invalidate();
            pictureBox1.MouseWheel  = PictureBox1_MouseWheel;
        }

        const int WHEEL_DELTA = 120;
        double scale = 1.0;
        private void PictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            var notches = e.Delta / WHEEL_DELTA;
            scale = scale - (0.2 * notches);
            pictureBox1.Invalidate();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            var x = (int)(pictureBox1.Padding.Left * scale);
            var y = (int)(pictureBox1.Padding.Top * scale);

            using (var pen = new Pen(Color.Red, 2f))
            {
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                e.Graphics.DrawEllipse(
                    pen,
                    x,
                    y,
                    width: e.ClipRectangle.Width - (x * 2),
                    height: e.ClipRectangle.Height - (y * 2));
            }
        }

        private void pictureBox1_MouseEnter(object sender, EventArgs e)
        {
            pictureBox1.Focus();
        }
    }
}

i forgot to mention another thing that might change everything. what i want to do is to calculate the distance in kilometers units that are on the image and convert them to the circle size. so if the i use the wheel it will change the circle size according to kilometers so if for example the wheel is on the 200 km circle the circle should fit this and if the circle size is 5,5 for example then the radius is 5 kilometers from the image center. i tried with 1km is 2.74 pixels but it didn't work fine i tried also 1km as 1.09 pixels but it didn't work fine either.

CodePudding user response:

Here's how I like to make rectangles of various sizes that are centered on a specific point. You first create a 1x1 rectangle at that position, then you simply demo

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        var path = Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory,
            "Images",
            "image.png"
        );
        pictureBox.Image = new Bitmap(Image.FromFile(path));
        pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
        pictureBox.Paint  = onPaintPictureBox;
        pictureBox.Padding = new Padding(10);
        pictureBox.Anchor = (AnchorStyles)0xF;
        pictureBox.SizeChanged  = (sender, e) => pictureBox.Invalidate();
        pictureBox.MouseWheel  = onm ouseWheelPictureBox;
        // Constrain main form to square.
        SizeChanged  = (sender, e) => Size = new Size(Height, Height);
    }

    const int WHEEL_DELTA = 120;
    int notches = 0;
    private void onm ouseWheelPictureBox(object? sender, MouseEventArgs e)
    {
        notches  = e.Delta / WHEEL_DELTA;
        pictureBox.Invalidate();
    }

    private void onPaintPictureBox(object? sender, PaintEventArgs e)
    {
        var scale = 1.0 - (0.2 * notches);
        var x = (int)(pictureBox.Padding.Left * scale);
        var y = (int)(pictureBox.Padding.Top * scale);
        using (var pen = new Pen(Color.Red, 2f))
        {
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            e.Graphics.DrawEllipse(
                pen,
                x, 
                y,
                width: e.ClipRectangle.Width - (x * 2),
                height: e.ClipRectangle.Height - (y * 2));
        }
        using (var pen = new Pen(Color.Red, 2f))
        {
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            e.Graphics.DrawLine(
                pen,
                x1: (float)pictureBox.Padding.Left,
                y1: pictureBox.Padding.Top,
                x2: e.ClipRectangle.Width - pictureBox.Padding.Left,
                y2: e.ClipRectangle.Height - pictureBox.Padding.Bottom);
        }
    }
  • Related