Click here to Skip to main content
15,891,431 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have this code:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;

namespace mws
{
    public partial class PaddingPoints : Form
    {
        private Point point;
        private Rectangle _mrect;
        private List<PointF> points = new List<PointF>();
        private Point RectStartPoint;
        private Image img;
        private Image imgClone;
        private Pen myPen;
        private int n = 37; //number of points
        private Bitmap _bmpBU = null;

        public PaddingPoints()
        {
            InitializeComponent();

            this.DoubleBuffered = true;
            _bmpBU = new Bitmap(@"D:\MyWeatherStation-Images-And-Icons\radar090.PNG");

            myPen = new Pen(Brushes.Red, 2);
            //Bitmap to hold the picturebox image
            img = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            Graphics g;
            using (g = Graphics.FromImage(img))
            {
                g.DrawImage(_bmpBU, 0, 0, pictureBox1.Width, pictureBox1.Height);
            }

            //image to hold the original picturebox. We need it to clear img to the original 
            //picturebox image
            imgClone = (Bitmap)img.Clone();

            //We draw always on img and then we invalidate
            pictureBox1.Image = img;
        }

        private void PaddingPoints_Load(object sender, EventArgs e)
        {

        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            RectStartPoint = e.Location;
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            label12.Text = string.Format("X = {0} Y = {1}", e.Location.X, e.Location.Y);
            if (e.Button == MouseButtons.Left && e.Location != RectStartPoint)
            {
                label2.Text = points.Count.ToString();
                label6.Text = points.Count.ToString();
                label7.Text = points.Count.ToString();
                label8.Text = points.Count.ToString();
                DrawRectangle(e.Location);
            }
        }

        private void DrawRectangle(Point pnt)
        {
            PointF pointf = new PointF(0, 0);
            points = new List<PointF>();
            Graphics g = Graphics.FromImage(img);
            int width, height, i, x, y;

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            //Clear img from the rectangle we drawn previously
            g.DrawImage(imgClone, 0, 0);


            if (pnt.X == RectStartPoint.X || pnt.Y == RectStartPoint.Y)
            {
                g.DrawLine(myPen, RectStartPoint.X, RectStartPoint.Y, pnt.X, pnt.Y);
            }
            else
            {
                g.DrawRectangle(myPen, Math.Min(RectStartPoint.X, pnt.X), Math.Min(RectStartPoint.Y, pnt.Y),
                                Math.Abs(RectStartPoint.X - pnt.X), Math.Abs(RectStartPoint.Y - pnt.Y));
                //width of spaces between points
                width = (int)((Math.Abs(RectStartPoint.X - pnt.X)) / (n - 1));
                //height of spaces between points
                height = (int)((Math.Abs(RectStartPoint.Y - pnt.Y)) / (n - 1));
                //we always want the upper left x, y coordinates as a reference drawing clockwise
                x = Math.Min(RectStartPoint.X, pnt.X);
                y = Math.Min(RectStartPoint.Y, pnt.Y);

                //Drawing the points. change the 3, 6 values for larger ones
                for (i = 0; i < n - 1; i++)
                {
                    //Up side
                    g.FillEllipse(Brushes.Green, new Rectangle(x - 3, Math.Min(RectStartPoint.Y, pnt.Y) - 3, 6, 6));
                    //Right side
                    g.FillEllipse(Brushes.Green, new Rectangle(Math.Min(RectStartPoint.X, pnt.X) + Math.Abs(RectStartPoint.X - pnt.X) - 3, y - 3, 6, 6));
                    //Bottom side
                    g.FillEllipse(Brushes.Green, new Rectangle(x - 3, Math.Min(RectStartPoint.Y, pnt.Y) + Math.Abs(RectStartPoint.Y - pnt.Y) - 3, 6, 6));
                    //Left side
                    g.FillEllipse(Brushes.Green, new Rectangle(Math.Min(RectStartPoint.X, pnt.X) - 3, y - 3, 6, 6));
                    pointf = new PointF(Math.Min(RectStartPoint.X, pnt.X) - 3, y - 3);
                    points.Add(pointf);
                    x += width;
                    y += height;
                }
                g.FillEllipse(Brushes.Green, new Rectangle(Math.Min(RectStartPoint.X, pnt.X) + Math.Abs(RectStartPoint.X - pnt.X) - 3,
                              Math.Min(RectStartPoint.Y, pnt.Y) - 3, 6, 6));
                g.FillEllipse(Brushes.Green, new Rectangle(Math.Min(RectStartPoint.X, pnt.X) + Math.Abs(RectStartPoint.X - pnt.X) - 3,
                             Math.Min(RectStartPoint.Y, pnt.Y) + Math.Abs(RectStartPoint.Y - pnt.Y) - 3, 6, 6));
            }

            g.Dispose();

            //draw img to picturebox
            pictureBox1.Invalidate();
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            label10.Text = ((n - 1) * 4).ToString();            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image != null)
            {
                ScanBmpFast((Bitmap)this.pictureBox1.Image, true, _mrect);
                this.pictureBox1.Refresh();
            }
        }

        private unsafe void ScanBmpFast(Bitmap bmp, bool setToOpaqueYellow, Rectangle rect)
        {
            BitmapData b1 = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            int stride = b1.Stride;
            int nWidth = bmp.Width;
            int nHeight = bmp.Height;

            System.IntPtr Scan0 = b1.Scan0;

            byte* p = (byte*)(void*)Scan0;

            int sX = Math.Min(Math.Max(rect.X, 0), bmp.Width);
            int sY = Math.Min(Math.Max(rect.Y, 0), bmp.Height);
            int w = Math.Min(rect.Width, bmp.Width - sX);
            int h = Math.Min(rect.Height, bmp.Height - sY);

            for (int y = sY; y < sY + h; y++)
            {
                p = (byte*)(void*)Scan0;
                p += (y * stride + sX * 4);

                for (int x = sX; x < sX + w; x++)
                {
                    if (p[0] != 0 || p[1] != 0 || p[2] != 0)
                    {
                        p[1] = p[2] = (byte)255;

                        if (setToOpaqueYellow)
                        {
                            p[0] = (byte)0;
                            p[3] = (byte)255;
                        }
                    }

                    p += 4;
                }
            }

            bmp.UnlockBits(b1);
        }
    }
}



Inside the method DrawRectangle i'm drawing a rectangle in red in real time when i'm moving the mouse.
Now i want to add a code to the DrawRectangle method that while it's drawing the rectangle it will also draw/add a line from the left edge middle to the right edge middle. And another line from the top edge middle to the bottom edge middle.

Tried some ways but it didn't work.

I couldn't find how to calculate the distance between the edges left and right, up and down and how to draw a line between each two edges.

I don't mind to make that it will draw this lines in the mouse up event or only if i click on a button. And also how to make it in the DrawRectangle method in real time.

Can someone show me please what should i change/add to this code ?
The DrawRectangle method i didn't do it but i'm using it for other things so i need to keep it but to add to it what i need in the question.
Posted
Updated 24-Sep-14 10:53am
v2
Comments
BillWoodruff 25-Sep-14 4:24am    
I think you are doing a lot of unnecessary work to achieve a simple rectangle divided, by lines, into quadrants of equal area. Are you interested in another approach ?
chocolade 26-Sep-14 0:13am    
BillWoodruff if you could show me another way to do it yes. Thank you very much.
BillWoodruff 28-Sep-14 2:02am    
I am curious if you found the strategy I used in my answer useful. If it wasn't useful ... assuming you tried the code ... I'd be interested to know in what way it did not meet the requirements ... look/feel ... you are trying to achieve. thanks, Bill

What is your problem? Elementary middle-school geometry? How do you define the distance? Shortest distance between two opposite sides is Width or Height, and between non-opposite side it's zero, because they intersect. :-)
If by "distance" you mean anything else, please clarify.

—SA
 
Share this answer
 
Comments
chocolade 24-Sep-14 18:19pm    
My problem is first to define in the DrawRectangle method the rectangle it self. I know Width is the distance between the two edges. But how do i draw the line in the code ? When i make g.DrawLine i need to give two Points. How do i find the rectangle width two points ? I know the propert Width is the distance but i don't have any Rectangle variable that i can get the Width property from yet.
Sergey Alexandrovich Kryukov 24-Sep-14 18:47pm    
There is the infinite number of lines between two sides. What's the problem? If there is a preference in picking one, you need to indicate it. DrawRectangle method is already defined.
What do I want to say here? I want to say: and so on...
—SA
Assuming I wanted to draw the "cross-hairs" graphic in a Panel, I would approach this by creating a GraphicsPath composed of four rectangles, defined in a 1-unit-square:
C#
private GraphicsPath quadPath = new GraphicsPath();

private GraphicsPath copyQuadPath;

private Matrix quadMatrix;

private Pen quadPen;

private int mdX, mdY;

private bool isMouseUp = true;

private void Form1_Load(object sender, EventArgs e)
{
    quadPen = new Pen(Color.Red,1.0F);

    quadMatrix = new Matrix();

    quadPath.AddRectangle(new RectangleF(0.0F, 0.0F, 0.5F, 0.5F));
    quadPath.AddRectangle(new RectangleF(0.5F, 0.0F, 0.5F, 0.5F));
    quadPath.AddRectangle(new RectangleF(0.5F, 0.5F, 0.5F, 0.5F));
    quadPath.AddRectangle(new RectangleF(0.0F, 0.5F, 0.5F, 0.5F));
}

private void panel1_MouseDown(object sender, MouseEventArgs e)
{
    mdX = e.X;
    mdY = e.Y;
    isMouseUp = false;
}

private void panel1_MouseUp(object sender, MouseEventArgs e)
{
    isMouseUp = true;
}

private void panel1_MouseMove(object sender, MouseEventArgs e)
{
    // test to exit if mouse is not down (user not click-dragging)
    if (isMouseUp) return;
    
    // scale factors
    int dx = e.X - mdX;
    int dy = e.Y - mdY;
    
    // transform the matrix to scale and translate 'quadPath

    // reset the quadMatrix to the identity Matrix
    quadMatrix.Reset();

    // translate to where the mouse went down
    quadMatrix.Translate(mdX, mdY);

    // scale
    quadMatrix.Scale(dx,dy);

    // copy quadPath
    copyQuadPath = (GraphicsPath) quadPath.Clone();

    // transform it
    copyQuadPath.Transform(quadMatrix);
    
    // force a redraw of panel1
    panel1.Invalidate();
}

// Then, in the Paint Event of the Panel:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    if (! isMouseUp) e.Graphics.DrawPath(quadPen, copyQuadPath);   
}
I've tested this, and (to my surprise) it worked well :) It's up to you to compare the performance and visual quality of this approach to other approaches you've tried. If it doesn't work as well, please let me know.
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900