SN25 Ответов: 1

Подсчет движения объекта в некоторой зоне (укажите область) на панели приложения C# winform


Всем привет

Я вызвал изображение карты на панели в качестве фонового изображения и указал на нем зону, нарисовав на ней прямоугольную рамку. потому что позже я буду использовать это поле зоны для подсчета движения объекта.

проблема с которой я сталкиваюсь заключается в том что как только объект входит в этот прямоугольник переменная счетчика продолжает увеличивать свое значение

Я хочу реализовать код, в котором после того, как объект вошел в это прямоугольное поле, он увеличивает счетчик только один раз, пока он не останется внутри прямоугольника

Что я уже пробовал:

Я делюсь своим кодом, чтобы лучше понять свою ситуацию

public partial class Form1 : Form
    {
        Pen Z1;
        Rectangle r1, r2;
        Image i1;
        Double t1x, t1y;
        Boolean draw1 = false;
        Graphics g;
        int count = 0; 

        public Form1()
        {
            InitializeComponent();
            Z1 = new Pen(Color.LightCyan, 3);
            r1 = new Rectangle(0, 0, 200, 200); // SIZE OF THE RECTANGLE STARTING FROM (0,0) OF THE IMAGE
            i1 = new Bitmap("Childr.png");
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            Thread Data_Read1 = new Thread(new ThreadStart(data_read1));
            Data_Read1.Start();

            typeof(Panel).InvokeMember("DoubleBuffered",
            BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
            null, panel1, new object[] { true });
        }
        private void panel_paint(object sender, PaintEventArgs e)
        {
            g = e.Graphics;
            g.DrawRectangle(Z1, r1);// DRAW RECTANGLE FOR ZONE 1         
            if (draw1 == true)
            {
                g.DrawImage(i1, Convert.ToInt32(t1y), Convert.ToInt32(t1x), 18, 21);
            }
        }
        public void data_read1()
        {
            UdpClient UdpServer = new UdpClient(1001);
            IPEndPoint Sender = new IPEndPoint(IPAddress.Any, 0);

            while (true)
            {
                Byte[] data1 = UdpServer.Receive(ref Sender);
                String line1 = Encoding.ASCII.GetString(data1);
                var part = line1.Split('\t');
                if (Double.Parse(part[0]) == 1)
                {
                    t1x = Math.Round((Double.Parse(part[1]) / 0.0347) + 75);
                    t1y = Math.Round((Double.Parse(part[2]) / 0.0335) + 133);
                    zone1_t1(); // method calling 
                }
                if (data1 != null)
                {
                    draw1 = true;
                    panel1.Invoke(new Action(() => { panel1.Invalidate(); }));
                }
                else
                {
                    draw1 = false;
                }
            }
        }
        private void zone1_t1()
        {
            if (r1.Contains(Convert.ToInt32(t1x), Convert.ToInt32(t1y))) // r1 is the rectangle box
            {
                count += 1; // counter variable to count the entire of an object
                label1.Invoke(new Action(() => { label1.Text = "COUNT: " + count.ToString(); }));
            }
        }
    }
}

1 Ответов

Рейтинг:
11

User 7429338

В zone1_t1 вы проверяете, находится ли r1 в прямоугольнике, а затем обновляете свой счетчик. Вас интересует, находится ли r1 в прямоугольнике, в то время как раньше его не было.

Вы можете сделать поле previouslyInRectangle, а затем использовать его следующим образом:

bool previouslyInRectangle;

private void zone1_t1()
{
    if (r1.Contains(Convert.ToInt32(t1x), Convert.ToInt32(t1y))) {
        // r1 is in the rectangle now
        if(!previouslyInRectangle) {        // And it wasn't previously.
            count += 1; // counter check
            label1.Invoke(new Action(() => { label1.Text = "COUNT: " + count.ToString(); }));
        }
        previouslyInRectangle = true;
    } else {
        previouslyInRectangle = false;
    }
}


SN25

спасибо тебе Тадеуш