Ejemplo n.º 1
0
        public Bitmap DrawTimeDiagram(uint[,] InputDelays, uint TimeLimit)
        {
#if DEBUG
            Log.Method(
                new MethodInfo {
                Name = "Scheme::DrawTimeDiagram", Type = typeof(Bitmap)
            },
                new ArgumentInfo {
                Name = nameof(InputDelays), Type = InputDelays.GetType(), Data = InputDelays
            },
                new ArgumentInfo {
                Name = nameof(TimeLimit), Type = InputDelays.GetType(), Data = TimeLimit
            }
                );
#endif

            var rows = _inputs.Select(x => x.Name).Concat(_outputs.Select(x => x.Name)).ToArray();

            int ImgRows        = _inputs.Count + _outputs.Count;
            int ImgStepColumns = (int)(TimeLimit);
            int ImgWidth       = fieldFirstWidth + ImgStepColumns * fieldStepWidth;
            int ImgHeight      = fieldHeight * ImgRows;

            var bt = new Bitmap(ImgWidth, ImgHeight);
            var gr = Graphics.FromImage(bt);

            gr.FillRectangle(Brushes.White, 0, 0, ImgWidth, ImgHeight);

            Pen gridPen = new Pen(Color.Black);
            gridPen.DashStyle = DashStyle.Solid;

            for (int gor = 1; gor <= ImgRows; gor++)
            {
                gr.DrawLine(gridPen, 0, gor * fieldHeight, ImgWidth, gor * fieldHeight);
                gr.DrawString(rows[gor - 1], new Font("Arial", 10), Brushes.Black,
                              new RectangleF(5, gor * fieldHeight - 20, fieldFirstWidth, 20));
            }

            gridPen.Width = 2;
            gr.DrawLine(gridPen, fieldFirstWidth, 0, fieldFirstWidth, ImgHeight);
            gridPen.Width = 1;

            gridPen.Color     = Color.Gray;
            gridPen.DashStyle = DashStyle.Dot;
            for (int ver = 0; ver <= ImgStepColumns; ver++)
            {
                gr.DrawLine(gridPen, fieldFirstWidth + ver * fieldStepWidth, 0,
                            fieldFirstWidth + ver * fieldStepWidth, ImgHeight);
            }

            gridPen.Color     = Color.Red;
            gridPen.Width     = 2;
            gridPen.DashStyle = DashStyle.Solid;


            uint[]         LastInputChangeTick = new uint[_inputs.Count];
            ElementValue[] state = new ElementValue[_inputs.Count];
            for (int i = 0; i < _inputs.Count; i++)
            {
                state[i] = new ElementValue()
                {
                    Delay = 0, Value = false
                }
            }
            ;

            bool[,] inputValues         = new bool[_inputs.Count, TimeLimit];
            ElementValue[,] outputValue = new ElementValue[_outputs.Count, TimeLimit];

            for (uint CurrentTick = 0; CurrentTick < TimeLimit; CurrentTick++)
            {
                for (int i = 0; i < _inputs.Count; i++)
                {
                    if (CurrentTick - LastInputChangeTick[i] >= InputDelays[i, state[i].Value.Value ? 1 : 0])
                    {
                        LastInputChangeTick[i] = CurrentTick;
                        state[i].Value         = !state[i].Value;
                    }

                    inputValues[i, CurrentTick] = state[i].Value.Value;
                }

                SetCurrentState(state);
                CalculateForCurrentState();

                for (int i = 0; i < _outputs.Count; i++)
                {
                    outputValue[i, CurrentTick] = _outputs[i].Value;
                }
            }

            for (int rw = 0; rw < ImgRows; rw++)
            {
                List <Point> sigLv = new List <Point>();
                if (rw < _inputs.Count)
                {
                    sigLv.Add(new Point(fieldFirstWidth,
                                        (int)((rw + (inputValues[rw, 0] ? .3f : 1f)) * fieldHeight)));
                    sigLv.Add(new Point(fieldFirstWidth + fieldStepWidth,
                                        (int)((rw + (inputValues[rw, 0] ? .3f : 1f)) * fieldHeight)));
                }
                else
                {
                    sigLv.Add(new Point(fieldFirstWidth,
                                        (int)((rw + (outputValue[rw - _inputs.Count, 0].Value.Value ? .3f : 1f)) * fieldHeight)));
                    sigLv.Add(new Point(fieldFirstWidth + fieldStepWidth,
                                        (int)((rw + (outputValue[rw - _inputs.Count, 0].Value.Value ? .3f : 1f)) * fieldHeight)));
                }

                for (int tick = 1; tick < TimeLimit; tick++)
                {
                    if (rw < _inputs.Count)
                    {
                        sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth,
                                            (int)((rw + (inputValues[rw, tick] ? .3f : 1f)) * fieldHeight)));
                        sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth,
                                            (int)((rw + (inputValues[rw, tick] ? .3f : 1f)) * fieldHeight)));
                    }
                    else
                    {
                        if (outputValue[rw - _inputs.Count, tick - 1].Value.Value ^ outputValue[rw - _inputs.Count, tick].Value.Value)
                        {
                            int dx = (int)(fieldStepWidth * outputValue[rw - _inputs.Count, tick].Delay.Value / (_componentLayers.Count + 1));
                            sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth + dx,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick - 1].Value.Value ? .3f : 1f)) * fieldHeight)));                 // last

                            sigLv.Add(new Point(dx + fieldFirstWidth + tick * fieldStepWidth,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight)));
                            sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight)));
                        }
                        else
                        {
                            sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight)));
                            sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight)));
                        }
                    }
                }

                gr.DrawLines(gridPen, sigLv.ToArray());
            }

            gr.Dispose();
            return(bt);
        }