none
Multithreading pro Graphics RRS feed

Všechny reakce

  • Tak určitě!

    Kdysi dávno, nebudu to kuchat: koukni na to ;)

    public Point N1 = new Point(200, 100);
            public Point N2 = new Point(200, 200);
            public Point N3 = new Point(200, 300);
            public Point K1 = new Point(300, 200);
            public Point K2 = new Point(400, 200);
            public Point A = new Point(500, 100);
            public Point B = new Point(500, 200);
            public Point C = new Point(500, 300);
            public Point Aend = new Point(600, 100);
            public Point Bend = new Point(600, 200);
            public Point Cend = new Point(600, 300);

            List<Train> trains = new List<Train>();

            public bool Tower = false;
            public bool InA = false;
            object lck = new object();

            public Form1()
            {
                DoubleBuffered = true;
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                comboBox1.DataSource = Enum.GetValues(typeof(TrainType));
                comboBox2.DataSource = Enum.GetValues(typeof(End));
                comboBox3.DataSource = Enum.GetValues(typeof(Start));
                Invalidate();
                timer1.Interval = 10;
                timer2.Interval = 30;
                timer2.Start();
                timer1.Start();
            }


            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                //N1
                e.Graphics.DrawLine(new Pen(Color.Black, 3), new Point(0, 100), N1);
                //N2
                e.Graphics.DrawLine(new Pen(Color.Black, 3), new Point(0, 200), N2);
                //N3
                e.Graphics.DrawLine(new Pen(Color.Black, 3), new Point(0, 300), N3);


                //N1-K1
                e.Graphics.DrawLine(new Pen(Color.Black, 3), N1, K1);
                //N2-K1
                e.Graphics.DrawLine(new Pen(Color.Black, 3), N2, K1);
                //N3-K1
                e.Graphics.DrawLine(new Pen(Color.Black, 3), N3, K1);
                //K1-K2
                e.Graphics.DrawLine(new Pen(Color.Black, 3), K1, K2);


                //K2-A
                e.Graphics.DrawLine(new Pen(Color.Black, 3), K2, A);
                //K2-B
                e.Graphics.DrawLine(new Pen(Color.Black, 3), K2, B);
                //K2-C
                e.Graphics.DrawLine(new Pen(Color.Black, 3), K2, C);

                //A
                e.Graphics.DrawLine(new Pen(Color.Black, 3), A, Aend);
                //B
                e.Graphics.DrawLine(new Pen(Color.Black, 3), B, Bend);
                //C
                e.Graphics.DrawLine(new Pen(Color.Black, 3), C, Cend);

                
                foreach (var train in trains)
                {
                    using(Matrix m = new Matrix()) {
                        var angle = Math.Atan2(train.B.Y - train.A.Y, train.B.X - train.A.X);
                        angle =(angle > 0 ? angle : (2 * Math.PI + angle)) * 360 / (2 * Math.PI);
                        Console.WriteLine(angle);
                        m.RotateAt((float)(angle), new PointF(train.pos.X,
                                                  train.pos.Y));
                        e.Graphics.Transform = m;
                    }
                    switch (train.trainType)
                    {
                        case TrainType.R:
                            e.Graphics.FillRectangle(Brushes.Red, new Rectangle((int)train.pos.X - 14, (int)train.pos.Y - 3, 14, 7));
                            break;
                        case TrainType.O:
                            e.Graphics.FillRectangle(Brushes.Green, new Rectangle((int)train.pos.X - 14, (int)train.pos.Y - 3, 14, 7));
                            break;
                        case TrainType.N:
                            e.Graphics.FillRectangle(Brushes.Blue, new Rectangle((int)train.pos.X - 14, (int)train.pos.Y - 3, 14, 7));
                            break;
                        default:
                            break;
                    }
                    e.Graphics.ResetTransform();
                }

            }

            private void button1_Click(object sender, EventArgs e)
            {
                List<Point> points = new List<Point>();
                switch ((Start)comboBox3.SelectedValue)
                {
                    case Start.N1:
                        points.Add(N1);
                        break;
                    case Start.N2:
                        points.Add(N2);
                        break;
                    case Start.N3:
                        points.Add(N3);
                        break;
                    default:
                        break;
                }
                points.Add(K1);
                points.Add(K2);
                switch ((End)comboBox2.SelectedValue)
                {
                    case End.A:
                        points.Add(A);
                        points.Add(Aend);
                        break;
                    case End.B:
                        points.Add(B);
                        points.Add(Bend);
                        break;
                    case End.C:
                        points.Add(C);
                        points.Add(Cend);
                        break;
                    default:
                        break;
                }
                trains.Add(new Train((End)comboBox2.SelectedValue, (TrainType)comboBox1.SelectedValue, (Start)comboBox3.SelectedValue, points));
            }

            private void timer1_Tick(object sender, EventArgs e)
            {

                Invalidate();
                int d = -1;
                for (int i = 0; i < trains.Count; i++)
                {
                    
                    if (trains[i].delete)
                        d = i;

                    if (!trains[i].enabled)
                    {
                        if (trains[i].index == 1)
                        {
                            trains[i].ChangeSpeed(0.5);
                        }
                        else if(trains[i].index == 2)
                        {
                            InA = false;
                            trains[i].NoLimit();
                        }
                        if (trains[i].index != 0)
                        {
                            trains[i].index++;
                            trains[i].SetDestPoint();
                            trains[i].StartEngine();
                        }
                        else
                        {
                            if (Tower && !InA)
                            {
                                InA = true;
                                trains[i].index++;
                                trains[i].SetDestPoint();
                                trains[i].StartEngine();
                            }
                        }
                    }

                    if (trains[i].colided) {
                        trains[i].colided = false;
                    }

                        for (int y = 0; y < trains.Count; y++)
                    {
                        if (i != y)
                        {
                            if (trains[y].IsInRange(trains[i].pos)) { 
                                trains[i].colided = true;
                            }
                        }
                    }
                }
                if (d != -1)
                {
                    trains[d].th.Abort();
                    trains.RemoveAt(d);
                }
            }
            


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

            private void checkBox1_CheckedChanged(object sender, EventArgs e)
            {
                Tower = checkBox1.Checked;
            }
        }

        public enum TrainType { R, O, N }
        public enum Start { N1, N2, N3 }
        public enum End { A, B, C }

        public class Train
        {
            public Point A;
            public Point B;
            public PointF pos;
            public double speed;
            public double currentSpeed = 0;
            public TrainType trainType;
            public End destination;
            public Start start;
            public bool enabled = true;
            List<Point> path;
            public int index = 0;
            public bool delete = false;
            public PointF lastPoint;
            public bool colided = false;
            public Thread th;

            public Train(End d, TrainType t, Start s, List<Point> path)
            {
                start = s;
                this.path = path;
                switch (t)
                {
                    case TrainType.R:
                        speed = 6;
                        break;
                    case TrainType.O:
                        speed = 2;
                        break;
                    case TrainType.N:
                        speed = 1;
                        break;
                    default:
                        break;
                }
                trainType = t;
                destination = d;
                Setup();
                currentSpeed = speed;
            }

            public void ChangeSpeed(double x)
            {
                currentSpeed = x;
            }
            public void NoLimit()
            {
                currentSpeed = speed;
            }

            public void Setup()
            {
                switch (start)
                {
                    case Start.N1:
                        A = new Point(0, 100);
                        SetDestPoint();
                        break;
                    case Start.N2:
                        A = new Point(0, 200);
                        SetDestPoint();
                        break;
                    case Start.N3:
                        A = new Point(0, 300);
                        SetDestPoint();
                        break;
                    default:
                        break;
                }
                pos = A;
                th = new Thread(Move);
                th.Start();
            }

            public void Move()
            {
                while (true)
                {
                    var angle = Math.Atan2(B.Y - A.Y, B.X - A.X);
                    if (enabled && !colided)
                    {
                        pos.X += (float)(Math.Sin(angle + Math.PI / 2) * currentSpeed);
                        pos.Y -= (float)(Math.Cos(angle + Math.PI / 2) * currentSpeed);
                    }
                    lastPoint = new PointF(pos.X, pos.Y);
                    lastPoint.X += (float)(Math.Sin(angle + Math.PI / 2) * -15);
                    lastPoint.Y -= (float)(Math.Cos(angle + Math.PI / 2) * -15);
                    switch (trainType)
                    {
                        case TrainType.R:
                            if (Math.Sqrt(Math.Pow(pos.X - B.X, 2) + Math.Pow(pos.Y - B.Y, 2)) < 6)
                            {
                                Console.WriteLine("Train Completed Way");
                                pos = B;
                                A = B;
                                Stop();
                            }
                            break;
                        case TrainType.O:
                            if (Math.Sqrt(Math.Pow(pos.X - B.X, 2) + Math.Pow(pos.Y - B.Y, 2)) < 2)
                            {
                                Console.WriteLine("Train Completed Way");
                                pos = B;
                                A = B;
                                Stop();
                            }
                            break;
                        case TrainType.N:
                            if (Math.Sqrt(Math.Pow(pos.X - B.X, 2) + Math.Pow(pos.Y - B.Y, 2)) < 1)
                            {
                                Console.WriteLine("Train Completed Way");
                                pos = B;
                                A = B;
                                Stop();
                            }
                            break;
                        default:
                            break;
                    }
                    Thread.Sleep(20);
                }
            }

            public bool IsInRange(PointF point) {
                if (Math.Sqrt(Math.Pow(lastPoint.X - point.X, 2) + Math.Pow(lastPoint.Y - point.Y, 2)) < 18)
                {
                    return true;
                }
                return false;
            }

            public void Stop()
            {
                enabled = false;
            }

            public void StartEngine()
            {
                enabled = true;
            }

            public void SetDestPoint()
            {
                if (path.Count > index)
                {
                    B = path[index];
                }
                else
                {
                    Stop();
                    delete = true;
                }
            }

    úterý 8. května 2018 16:36