模拟系列(一)——数字电路

要求

简要模拟数字电路的运行过程,及电位(简化为L和H),用C# WinForm实现。

思路

逻辑部分

  1. 电路是一种图结构,基于C#的特性,设计Node类(结点)和Wire类(连线),且为泛型。
  2. 由于电路元件可以包含多个Node,故设计超类Unit(继承自Node,管理Node)。
  3. 电路器件的状态有L和H,故存在状态的变迁与计算,故设计Status类(状态)和Mutable类(原状态和新状态)。
  4. 每个电路对象(结点,单元,连线)拥有一个唯一编号,故设计Markable类(基于UUID)。
  5. 结点和单元可以处理事件(单击、绘图等),增加交互接口IInteractive和仿真接口ISimuate。
  6. 设计结点和单元的获得焦点和失去焦点事件,由OnStateUpdated和OnValueUpdated触发。
  7. 构造新元器件可通过派生Node并重载。

界面部分

  1. 采用DirectUI思想绘制,API采用Gdi+的Graphics,构造图元方法参考自@vczh的C++ GUI Library/GacLib。
  2. 构造渲染器工厂GraphicsRendererFactory和图元工厂GraphicsElementFactory,渲染器存放绘制句柄(对Gdi+而言不需要存放句柄,且Gdi+对象有缓存机制),图元存放图形的属性。
  3. 每个元器件拥有独立的IGraphicsElement图元绘制接口集合以绘制图像。

核心算法

采用状态更新机制,类似状态机,并行优化。(此算法仍存在缺陷,有循环刷新问题)

public virtual void Update()
        {
            _units.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Activate(ActivateType.FilterUnit));
            _nodes.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Advance(AdvanceType.NodeToWire));
            _wires.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Advance(AdvanceType.NodeToWire));
            _nodes.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Advance(AdvanceType.WireToNode));
            _wires.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Advance(AdvanceType.WireToNode));
        }

测试

image

image

源码

https://github.com/bajdcc/SimuCircult

类库:SimuCircult

界面:WinSC

原文地址:https://www.cnblogs.com/bajdcc/p/4766208.html