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); }