public bool findPath(int n1, int depth) { if (n1 == dest) { return(true); //找到目的元器件端口 } if (depth-- == 0) { return(false); //超过搜索深度 } if (used[n1]) { return(false); //已经遍历过此结点 } used[n1] = true; //标志位置true for (int i = 0; i < elmList.Count; i++) { CircuitElm ce = getElm(i); //获取元器件 if (ce.Equals(firstElm)) { continue; //若是第一个元器件 pass } if (type == VOLTAGE) //若既不是导线也不是电源则继续 { if (!(ce.isWire() || ce.type == TYPES.VoltageElm)) { continue; } } //若当前元器件没有与此结点相连 int j; for (j = 0; j < ce.getPostCount(); j++) { if (ce.getNode(j) == n1) { break; } } if (j == ce.getPostCount()) { continue; } for (int k = 0; k < ce.getPostCount(); k++) { if (j == k) { continue; } if (ce.getConnection(j, k) && findPath(ce.getNode(k), depth)) { used[n1] = false; return(true); } } } used[n1] = false; return(false); }
public void Stop(string s, CircuitElm ce) { StopMessage = s; Matrix = null; /* causes an exception */ StopElm = ce; mSim.SetSimRunning(false); }
//设置UI摄像机位置 private void setUICamera(CircuitElm temp, GameObject UICamera) { float xx = temp.transform.position.x; float yy = temp.transform.position.y; float zz = temp.transform.position.z; float x = xx; float y = yy + 0.5f; float z = zz; if (temp.type == CirSim.TYPES.AmmeterElm) //若是电流表,则UI摄像机向上移动 { AmmeterElm elm = temp.GetComponent <AmmeterElm>(); //获取电流表脚本 x = elm.camPos.position.x; y = elm.camPos.position.y + 0.9f; z = elm.camPos.position.z; } UICamera.transform.position = new Vector3(x, y, z); Magnifier.SetActive(true); //打开放大镜 Magnifier.GetComponent <Magnifier>().reset(); //初始化 Magnifier.transform.FindChild("MagnifierChild").gameObject.SetActive(true); Magnifier.transform.FindChild("MagnifierChild").gameObject.GetComponent <Magnifier>().reset(); setMagnifier(Magnifier); }
int type; //类型 //构造器进行初始化 public FindPathInfo(int t, CircuitElm e, int d) { dest = d; type = t; firstElm = e; used = new bool[nodeList.Count]; }
public void OnTriggerExit(Collider collider) { //若本元器件正在被触摸,并且碰到了元器件 if (Utils.holdingName.Equals(transform.name) && collider.tag == "unit" && state != 1) { unitColliders.Remove(collider.transform.GetComponent <CircuitElm> ()); //将本元器件脚本在元器件列表中移除 Utils.adjustHeight(transform, unitColliders); //调整高度 } //若本元器件碰到了地板 else if (Utils.holdingName.Equals(transform.name) && (collider.tag == "plate")) { floor = 0; //调整层数 transform.position = new Vector3(transform.position.x, 0f, transform.position.z); //调整高度 } //若本元器触碰到其他元器件的纽扣 else if (collider.tag == "button" && collider.transform.parent.tag == "unit" && (state != 0) && (state != 1)) { CircuitElm temp = collider.transform.parent.GetComponent <CircuitElm> (); //获取正在触摸的元器件引用 //若不是正常离开纽扣 if (temp.interfaceList [int.Parse(collider.name)] != null && !temp.interfaceList [int.Parse(collider.name)].Equals(transform.GetComponent <CircuitElm> ())) { return; } temp.interfaceList [int.Parse(collider.name)] = null; buttonColliders.Remove(collider.gameObject); //删除纽扣 } //若本元器触碰到底板上的纽扣 else if (collider.tag == "point" && (state == 2 || state == 1)) { buttonColliders.Remove(collider.gameObject); //删除纽扣 } }
public Adjustable(CircuitElm ce, int item) { MinValue = 1; MaxValue = 1000; Elm = ce; EditItem = item; }
public void OnTriggerEnter(Collider collider) { //若本元器件正在被触摸,并且碰到了元器件 if (Utils.holdingName.Equals(transform.name) && (collider.tag == "unit") && state != 1) { unitColliders.Add(collider.transform.GetComponent <CircuitElm> ()); //将本元器件脚本添加到元器件列表 Utils.adjustHeight(transform, unitColliders); //调整高度 } //若本元器件碰到了地板 else if (Utils.holdingName.Equals(transform.name) && (collider.tag == "plate")) { floor = 1; //调整层数 transform.position = new Vector3(transform.position.x, 0.064f, transform.position.z); //调整高度 } //若本元器触碰到其他元器件的纽扣 else if (collider.tag == "button" && collider.transform.parent.tag == "unit" && (state != 0) && (state != 1)) { CircuitElm temp = collider.transform.parent.GetComponent <CircuitElm> (); //获取正在触摸的元器件引用 if (temp.interfaceList [int.Parse(collider.name)] != null && collider.transform.parent.parent != null) //已经连上的就不能再连了 { return; } temp.interfaceList [int.Parse(collider.name)] = transform.GetComponent <CircuitElm> (); //接口连接 buttonColliders.Add(collider.gameObject); //添加触碰到的纽扣 } //若本元器触碰到底板上的纽扣 else if (collider.tag == "point" && (state == 2 || state == 1)) { buttonColliders.Add(collider.gameObject); //添加触碰到的纽扣 } }
/* State object to help find loops in circuit subject to various conditions (depending on type) * elm = source and destination element. * dest = destination node. */ public PathInfo(PathType type, CircuitElm elm, int dest, List <CircuitElm> elmList, int nodeCount) { mDest = dest; mType = type; mFirstElm = elm; mElmList = elmList; mVisited = new bool[nodeCount]; }
//计算本元器件哪个端口连接下一个元器件 //root--此元器件 next--下一个元器件 public static int calNextPort(CircuitElm root, CircuitElm next) { for (int i = 0; i < root.interfaceList.Count; i++) { if (root.interfaceList[i] != null && root.interfaceList[i].Equals(next)) //若该端口连接为此元器件 { return(i); //返回连接端口号 } } return(-1); //连接错误 }
public ScrollValuePopup(int dy, CircuitElm e, CirSim s) : base() { mMyElm = e; mDeltaY = 0; mSim = s; mSim.PushUndo(); setupValues(); Text = mName; mPnlV = new Panel(); { mPnlV.Left = 4; mPnlV.Top = 4; int ofsY = 0; /* label */ mLabels = new Label() { Text = "---" }; mLabels.AutoSize = true; mLabels.Left = 4; mLabels.Top = ofsY; mPnlV.Controls.Add(mLabels); ofsY += mLabels.Height; /* trbValue */ mTrbValue = new TrackBar() { Minimum = 0, Maximum = mNValues - 1, SmallChange = 1, LargeChange = 1, TickFrequency = mNValues / 24, TickStyle = TickStyle.TopLeft, Width = 300, Height = 21, Left = 4, Top = ofsY }; ofsY += mTrbValue.Height * 2 / 3; mTrbValue.ValueChanged += new EventHandler((sender, ev) => { setElmValue((TrackBar)sender); }); mPnlV.Width = mTrbValue.Width + 8; mPnlV.Height = ofsY + 4; mPnlV.Controls.Add(mTrbValue); /* */ Controls.Add(mPnlV); } doDeltaY(dy); Width = mPnlV.Width + 24; Height = mPnlV.Height + 48; FormBorderStyle = FormBorderStyle.FixedToolWindow; }
public void SetElm(CircuitElm ce) { mPlots = new List <ScopePlot>(); if (null != ce && (ce is TransistorElm)) { _setValue(VAL.VCE, ce); } else { _setValue(0, ce); } _initialize(); }
//设置端口点 public override void setPosts() { if (floor == 1) { points[0] = ((GameObject)buttonColliders[0]).name; } else { CircuitElm ce = ((GameObject)buttonColliders[0]).transform.parent.GetComponent <CircuitElm>(); //获取元器件 int index = int.Parse(((GameObject)buttonColliders[0]).name); //被碰撞元器件连接纽扣 points[0] = ce.getPostFromIndex(index); //获取结点名称 } }
public SliderDialog(CircuitElm ce, CirSim f) : base() { Text = "Add Sliders"; sim = f; elm = ce; vp = new Panel(); einfos = new ElementInfo[10]; hp = new Panel(); { hp.AutoSize = true; /* Apply */ applyButton = new Button() { Text = "Apply" }; applyButton.Click += new EventHandler((sender, e) => { apply(); }); ctrlInsert(hp, applyButton); /* OK */ okButton = new Button() { Text = "OK" }; okButton.Click += new EventHandler((sender, e) => { apply(); closeDialog(); }); ctrlInsert(hp, okButton); /* Cancel */ cancelButton = new Button() { Text = "Cancel" }; cancelButton.Click += new EventHandler((sender, e) => { closeDialog(); }); ctrlInsert(hp, cancelButton); } /* */ ctrlInsert(vp, hp); /* */ vp.Left = 4; vp.Top = 4; Controls.Add(vp); /* */ buildDialog(); Width = vp.Width + 24; Height = vp.Height + 64; Visible = false; }
public Adjustable(StringTokenizer st, CirSim sim) { int e = st.nextTokenInt(); if (e == -1) { return; } Elm = sim.getElm(e); EditItem = st.nextTokenInt(); MinValue = st.nextTokenDouble(); MaxValue = st.nextTokenDouble(); SliderText = CustomLogicModel.unescape(st.nextToken()); }
bool canSplit(CircuitElm ce) { if (!(ce is WireElm)) { return(false); } var we = (WireElm)ce; if (we.P1.X == we.P2.X || we.P1.Y == we.P2.Y) { return(true); } return(false); }
void _setValue(VAL val, CircuitElm ce) { mPlots = new List <ScopePlot>(); if (val == VAL.INVALID) { mPlots.Add(new ScopePlot(ce, 0)); } else { mPlots.Add(new ScopePlot(ce, val)); ShowV = true; } _calcVisiblePlots(); ResetGraph(); }
public ContextMenuStrip Show(int px, int py, CircuitElm mouseElm) { mScope.Enabled = mouseElm.CanViewInScope; mFloatScope.Enabled = mouseElm.CanViewInScope; mEdit.Enabled = mouseElm.GetElementInfo(0) != null; mFlip.Enabled = 2 == mouseElm.PostCount; mSplit.Enabled = canSplit(mouseElm); mSlider.Enabled = sliderItemEnabled(mouseElm); var popupMenu = new ContextMenuStrip(); popupMenu.Items.AddRange(mMenuItems.ToArray()); popupMenu.Show(); popupMenu.Location = new Point(px, py); return(popupMenu); }
bool sliderItemEnabled(CircuitElm elm) { if (elm is PotElm) { return(false); } for (int i = 0; ; i++) { var ei = elm.GetElementInfo(i); if (ei == null) { return(false); } if (ei.CanCreateAdjustable()) { return(true); } } }
//调整元器件的高度 public static void adjustHeight(Transform unit, ArrayList unitColliders) //unit-元器件引用 unitColliders-元器件碰撞列表 { CircuitElm temp = unit.GetComponent <CircuitElm>(); //元器件脚本 int currentFloor = temp.floor; //元器件当前层数 int maxFloor = 0; //碰撞列表中的最大层数 //获取最大层数 for (int i = 0; i < unitColliders.Count; i++) { CircuitElm tempSon = (CircuitElm)unitColliders[i];//强制转换为原始类型 if (tempSon.floor > maxFloor) { maxFloor = tempSon.floor; } } temp.floor = maxFloor + 1; //提高层数 adjustHeightAchieve(unit, maxFloor + 1); //调整高度 }
//设置端口点-有正负极之分 public override void setPosts() { if (floor == 1) //若该元器件直接插在底板上 { Point point = ((GameObject)buttonColliders[0]).GetComponent <Point>(); //获取纽扣上的脚本 if (point.port == 1) //该纽扣碰撞的是电池的正极 { points[1] = ((GameObject)buttonColliders[0]).name; //获取结点名称 points[0] = ((GameObject)buttonColliders[1]).name; } else { points[0] = ((GameObject)buttonColliders[0]).name; //获取结点名称 points[1] = ((GameObject)buttonColliders[1]).name; } } else //若元器件插在其他元器件上 { int index; CircuitElm thisCE = transform.GetComponent <CircuitElm>(); //此元器件 CircuitElm ce = ((GameObject)buttonColliders[0]).transform.parent.GetComponent <CircuitElm>(); //获取元器件 if (thisCE.interfaceList[1].Equals(ce)) //若是电源的正极连接此端口 { ce = ((GameObject)buttonColliders[0]).transform.parent.GetComponent <CircuitElm>(); index = int.Parse(((GameObject)buttonColliders[0]).name); points[1] = ce.getPostFromIndex(index); //point2端口点代表电源的正极 ce = ((GameObject)buttonColliders[1]).transform.parent.GetComponent <CircuitElm>(); index = int.Parse(((GameObject)buttonColliders[1]).name); points[0] = ce.getPostFromIndex(index); //point1端口点代表电源的负极 } else //若是电源的正极连接此端口 { ce = ((GameObject)buttonColliders[0]).transform.parent.GetComponent <CircuitElm>(); index = int.Parse(((GameObject)buttonColliders[0]).name); points[0] = ce.getPostFromIndex(index); //point1端口点代表电源的负极 ce = ((GameObject)buttonColliders[1]).transform.parent.GetComponent <CircuitElm>(); index = int.Parse(((GameObject)buttonColliders[1]).name); points[1] = ce.getPostFromIndex(index); //point2端口点代表电源的正极 } } }
//设置端口点 0、1纽扣代表端口1(point2) 2、3纽扣代表端口0(point1) public virtual void setPosts() { buttonCollidersIndex.Clear(); //清空纽扣对应端口的列表 if (floor == 1) //若该元器件直接插在底板上 { if (getPostCount() == 2 || type == CirSim.TYPES.WireElm) //若端口数为两个或者是导线 { if (((GameObject)buttonColliders [0]).GetComponent <Point> ().port == 1) //若碰到的时1纽扣(端口1) { points [0] = ((GameObject)buttonColliders [0]).name; //获取结点名称 points [1] = ((GameObject)buttonColliders [1]).name; } else //碰到的是3纽扣(端口0) { points [1] = ((GameObject)buttonColliders [0]).name; points [0] = ((GameObject)buttonColliders [1]).name; } } else //端口数大于2并且不是导线 { for (int i = 0; i < downHole; i++) { int port = ((GameObject)buttonColliders [i]).GetComponent <Point> ().port; //获取连接端点数 buttonCollidersIndex.Add(port / 2); //记录纽扣对应的端口 points [port / 2] = ((GameObject)buttonColliders [i]).name; //设置端点名称 } } } else if (floor > 1) //若元器件插在其他元器件上 { for (int i = 0; i < downHole; i++) { CircuitElm ce = ((GameObject)buttonColliders [i]).transform.parent.GetComponent <CircuitElm> (); //获取元器件 int port = calNextPort(transform.GetComponent <CircuitElm> (), ce); //获取本元器件的连接纽扣 int index = int.Parse(((GameObject)buttonColliders [i]).name); //被碰撞元器件连接纽扣 buttonCollidersIndex.Add(port / 2); //记录纽扣对应的端口 points [port / 2] = ce.getPostFromIndex(index); //获取结点名称 } } }
// 移动平台触屏操作 void MobileInput() { if (Utils.isIntroduction) { return; } if (Utils.gestureLayer) //电路连通好后的手势触摸层 { if (Input.touchCount == 1) { Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position); LayerMask unitmask = 1 << LayerMask.NameToLayer("unit"); //规定触摸层数 if (Physics.Raycast(ray, out hit, 100, unitmask.value) && Input.touches[0].phase == TouchPhase.Began) { Utils.audioManager.playAudio(1); //播放音效 temp = hit.collider.transform.GetComponent <CircuitElm>(); //获取元器件脚本 if (temp.type == CirSim.TYPES.SwitchElm) { setUICamera(temp, UICamera); //设置UI摄像机位置 ((SwitchElm)temp).convert(); //转换开关状态 } else if (temp.type == CirSim.TYPES.SlidingResistanceElm || temp.type == CirSim.TYPES.AmmeterElm) { setUICamera(temp, UICamera); //设置UI摄像机位置 } gameObjGesture = hit.collider.gameObject; //获取触摸物体引用 CirSim.analyzeCircuit(); //分析电路 } else if (Input.touches[0].phase == TouchPhase.Moved) { if (gameObjGesture == null) { return; } CircuitElm elm = gameObjGesture.transform.GetComponent <CircuitElm>(); //获取元器件脚本 if (elm.type == CirSim.TYPES.SlidingResistanceElm) //若为滑动变阻器 { ((SlidingResistanceElm)(elm)).slideSwitch(Input.touches[0].deltaPosition); //滑动滑块 CirSim.analyzeCircuit(); //分析电路 } } else if (Input.touches[0].phase == TouchPhase.Ended) { gameObjGesture = null; //手持物体引用置null } } return; } if (gameObj != null) // 如果触控物体不为空 { if (!gameObj.tag.Equals("plate") && Input.touchCount <= 0) // 如果触控物体不为地板并且此时没有手指触控事件 { return; // 直接返回 } else if (gameObj.tag.Equals("plate") && Input.touchCount <= 0) // 如果触控物体为地板并且此时没有手指触控事件 { RotatePlate(gameObj); // 校正旋转地板 } } // 1个手指触摸屏幕 if (Input.touchCount == 1) { Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position); // 定义从摄像机出发的射线 LayerMask uimask = 1 << LayerMask.NameToLayer("UI"); //定义UI层 LayerMask unitmask = 1 << LayerMask.NameToLayer("unit"); // 获取unit层 LayerMask platemask = 1 << LayerMask.NameToLayer("plate"); // 获取plate层 LayerMask originalmask = 1 << LayerMask.NameToLayer("original"); // 获取放置初始元器件层 if (Input.GetMouseButtonDown(0)) { if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)) //触摸在UI上 //Debug.Log("触摸在UI上"); { gameObj = null; return; } } if (Input.touches [0].phase == TouchPhase.Began) // 单指触控 { m_screenpos = Input.touches [0].position; // 记录手指触屏的位置 if (Physics.Raycast(ray, out hit, 100, uimask.value)) //如果触碰到了UI按钮 { gameObj = null; return; } else if (Physics.Raycast(ray, out hit, 100, originalmask.value)) //如果触摸到原始元器件 { isHoldUnit = true; //表示持有元件 GameObject gb = Instantiate(hit.collider.gameObject); gb.GetComponent <CircuitElm> ().originalPos = new Vector3(hit.collider.transform.position.x, 0.0f, hit.collider.transform.position.z); gb.transform.SetParent(hit.collider.gameObject.transform.parent); //初始化一个元器件 gameObj = hit.collider.gameObject; gameObj.tag = "unit"; //unit层 gameObj.layer = 8; //unit层 gameObj.GetComponent <CircuitElm>().convertState(true); //转变为透明 Utils.holdingName = gameObj.name; //获取手持元器件的名字 Vector2 tempPos = Camera.main.WorldToScreenPoint(gameObj.transform.position); // 将元件的世界坐标转换为屏幕坐标 offSet = new Vector2(m_screenpos.x - tempPos.x, m_screenpos.y - tempPos.y); // 触控时考虑偏移 } else if (Physics.Raycast(ray, out hit, 100, unitmask.value)) // 如果触控到元件 { isHoldUnit = true; // 表示持有元件 //若元器件被压在底下,则不能动 CircuitElm tempCE = hit.collider.transform.GetComponent <CircuitElm>(); if (tempCE.interfaceList[0] != null || tempCE.interfaceList[2] != null) { gameObj = null; return; } gameObj = hit.collider.gameObject; // 保存持有元件的对象 gameObj.GetComponent <CircuitElm>().convertState(true); //变为透明显示元器件 CirSim.elmList.Remove(gameObj.GetComponent <CircuitElm>()); //在元器件列表中删除该元器件 Utils.holdingName = gameObj.name; // 获取手持元器件的名字 Vector2 tempPos = Camera.main.WorldToScreenPoint(gameObj.transform.position); // 将元件的世界坐标转换为屏幕坐标 offSet = new Vector2(m_screenpos.x - tempPos.x, m_screenpos.y - tempPos.y); // 触控时考虑偏移 //gameObj.transform.SetParent(null); // 设置父物体为空 } else // 如果没有触控到元件 { Utils.holdingName = "null"; // 手持物体名称 isHoldUnit = false; // 表示未持有元件 gameObj = Utils.plate; // 保存地板对象 } } else if (Input.touches [0].phase == TouchPhase.Moved) // 手指移动 { if (gameObj == null) { return; // 若手持物体为空,则返回 } Touch touch = Input.touches [0]; // 获取touch对象 switch (gameObj.tag) // 区别操作对象的便签 { case "unit": // 元件 gameObj.transform.GetComponent <CircuitElm>().state = 2; //切换元器件的状态 Vector3 unitPosition = gameObj.transform.position; // 获取元件世界坐标 Vector3 screenPosition = Camera.main.WorldToScreenPoint(unitPosition); // 将元件的世界坐标转为屏幕坐标 // 计算时考虑偏移量 Vector3 fingerPosition = new Vector3(touch.position.x - offSet.x, touch.position.y - offSet.y, screenPosition.z); Vector3 worldPosition = Camera.main.ScreenToWorldPoint(fingerPosition); // 获取触屏点世界坐标 gameObj.transform.position = new Vector3(worldPosition.x, gameObj.transform.GetComponent <CircuitElm>().getHeight(), worldPosition.z); // 更新元件世界坐标 break; case "plate": // 底板 Vector2 deltaPos = touch.deltaPosition; // 获取滑屏当前帧改变值 gameObj.transform.Rotate(Vector3.down * deltaPos.x * 0.6f, Space.World); // 根据滑屏距离的水平值旋转底板 break; default: //Debug.Log ("touch error!"); // 打印错误信息 break; } } else if (Input.touches[0].phase == TouchPhase.Ended) { //Utils.holdingName = null;//手持元起价置空 if (gameObj != null && gameObj.tag == "unit") { //恢复为不透明 gameObj.GetComponent <CircuitElm>().convertState(false); gameObj.transform.GetComponent <CircuitElm>().putUnit();//将元器件放到指定位置 } } } else if (Input.touchCount > 1) // 如果是多点触控 // 记录两个手指的位置 { Vector2 finger1 = new Vector2(); Vector2 finger2 = new Vector2(); // 记录两个手指的移动 Vector2 mov1 = new Vector2(); Vector2 mov2 = new Vector2(); for (int i = 0; i < 2; i++) // 遍历触控点 { Touch touch = Input.touches [i]; // 获取touch对象 if (touch.phase == TouchPhase.Ended) // 如果有一只手指松开 { break; // 直接跳出循环 } if (touch.phase == TouchPhase.Moved) // 如果行为是移动 { float mov = 0; // 定义记录移动距离的变量 if (i == 0) // 如果是第一支手指 { finger1 = touch.position; // 记录触屏位置 mov1 = touch.deltaPosition; // 记录移动距离 } else // 如果是第二支手指 { finger2 = touch.position; // 记录触屏位置 mov2 = touch.deltaPosition; // 记录移动距离 // Debug.Log (" asd " + Vector2.Angle (mov1, mov2)); // 双指运动方向相同 if (Vector2.Angle(mov1, mov2) <= 90 && (mov1.magnitude > 0.8f || mov2.magnitude > 0.8f)) { if (Vector2.Angle(mov1, new Vector2(1, 0)) < 10) // 滑动方向向量如果和x正轴向量夹角小于10度 // 水平向右旋转 { transform.RotateAround(Utils.plate.transform.position, new Vector3(0, -1, 0), RotateHSpeed * Time.deltaTime); } else if (Vector2.Angle(mov1, new Vector2(-1, 0)) < 10) // 滑动方向向量如果和x负轴向量夹角小于10度 // 水平向左旋转 { transform.RotateAround(Utils.plate.transform.position, new Vector3(0, 1, 0), RotateHSpeed * Time.deltaTime); } else if (Vector2.Angle(mov1, new Vector2(0, 1)) < 10) // 滑动方向向量如果和y负轴向量夹角小于10度 //垂直向上旋转 { transform.FindChild("Main Camera").Rotate(-RotateVSpeed * Time.deltaTime, 0, 0); } else if (Vector2.Angle(mov1, new Vector2(0, -1)) < 10) // 滑动方向向量如果和y负轴向量夹角小于10度 // 垂直向下旋转 { transform.FindChild("Main Camera").Rotate(RotateVSpeed * Time.deltaTime, 0, 0); } } else // 缩放 { if (finger1.x > finger2.x) // 如果第一根手指的x坐标大于第二根 { mov = mov1.x; // 总的移动距离为第一根手指的x方向移动距离 } else // 如果第二根手指的x坐标大于第一根 { mov = mov2.x; // 总的移动距离为第二根手指的x方向移动距离 } if (finger1.y > finger2.y) // 如果第一根手指的y坐标大于第二根 { mov += mov1.y; // 总的移动距离为第一根手指的y方向移动距离 } else // 如果第二根手指的y坐标大于第一根 { mov += mov2.y; // 总的移动距离为第二根手指的y方向移动距离 } transform.Translate(0, -mov * Time.deltaTime, 0); // 移动摄像机父物体的y坐标 if (transform.position.y <= MaxZoomRatio) // 如果y坐标小于等于最大放大率 { transform.position = new Vector3(transform.position.x, MaxZoomRatio, transform.position.z); } else if (transform.position.y >= MinZoomRatio) // 如果y坐标大于等于最小放大率 { transform.position = new Vector3(transform.position.x, MinZoomRatio, transform.position.z); } //Debug.Log (transform.position + "asd" + transform.FindChild("Main Camera").transform.position); } } } } } }
public void setScopeElm(CircuitElm e) { elmScope.SetElm(e); elmScope.ResetGraph(); }
public ScopePlot(CircuitElm e) { Elm = e; }
public ScopePlot(CircuitElm e, Scope.VAL v) { Elm = e; Value = v; }
//分析电路 public static void analyzeCircuit() { if (elmList.Count == 0) //若元器件列表为空 { return; } nodeList.Clear(); //清空结点列表 int vscount = 0; //电压源数量(将导线看做电压为0的电压源) //步骤一:找到电压源,确定起始元器件 Debug.Log("步骤一"); CircuitElm volt = null; //电源源引用 for (int i = 0; i < elmList.Count; i++) //遍历元器件列表 { CircuitElm ce = getElm(i); //获取元器件 if (ce.isDamaged) { elmList.Remove(ce); //若元器件破损,在元器件列表中删除该元器件 damageList.Add(ce); //将损坏元器件添加进损坏列表 } if (volt == null && ce.type == TYPES.VoltageElm) //若找到了一个电源 { volt = ce; //为电压源赋值 } } if (volt != null) //若找到电压源 { CircuitNode cn = new CircuitNode(); //创建结点 cn.name = volt.getPost(0); //获取电压源负极 nodeList.Add(cn); //添加进结点列表 } else { CircuitNode cn = new CircuitNode(); //创建结点 cn.name = null; //设置结点为空 nodeList.Add(cn); //添加进结点列表 return; } //步骤二:分配所有的结点和电压源 Debug.Log("步骤二"); for (int i = 0; i < elmList.Count; i++) //遍历元器件列表 { CircuitElm ce = getElm(i); //获取元器件 Debug.Log("元器件" + i + " " + getElm(i).getPost(0)); int ivs = ce.getVoltageSourceCount(); //记录电压源数量 int posts = ce.getPostCount(); //记录端点数量 for (int j = 0; j < posts; j++) //遍历元器件上的端口 { string port = ce.getPost(j); //获取元器件的端口 int k; for (k = 0; k < nodeList.Count; k++) //遍历结点列表 { CircuitNode cn = getCircuitNode(k); //获取k结点 if (cn.name.Equals(port)) { break; //从结点列表中找到了该结点 } } if (k == nodeList.Count) //结点列表中无此结点 { CircuitNode cn = new CircuitNode(); //创建结点 cn.name = port; //标记结点名称 cn.links.Add(ce, j); //添加进结点序列 ce.setNode(j, nodeList.Count); //记录元器件的连接结点 nodeList.Add(cn); //将该结点添加到结点列表 } else //结点列表中有此结点 { getCircuitNode(k).links.Add(ce, j); //添加结点链 ce.setNode(j, k); //记录元器件的连接结点 if (k == 0) //若结点为电源的负极 { ce.setNodeVoltage(j, 0); //端口j的电压为0 } } } vscount += ivs; //电压源数量累加 } voltageSources = new CircuitElm[vscount]; //创建电压源数组 vscount = 0; //电压源数量置0 circuitNonLinear = false; //电路是否是非线性的 Debug.Log("----------结点-----------"); for (int i = 0; i < nodeList.Count; i++) { Debug.Log("结点" + i + " : " + getCircuitNode(i).name); } Debug.Log("---------元器件对应的结点----------"); //for(int i = 0; i < elmList.Count; i++) { // Debug.Log("元器件"+i+" : "+getElm(i).type+" "+getElm(i).nodes[0]+"--"+ getElm(i).nodes[1]); //} //步骤三:初始电路矩阵 Debug.Log("步骤三"); for (int i = 0; i < elmList.Count; i++) //遍历元器件 { CircuitElm ce = getElm(i); //获取元器件 int ivs = ce.getVoltageSourceCount(); //获取电压源数量 for (int j = 0; j < ivs; j++) //遍历电压源 { voltageSources [vscount] = ce; //为电压源数组赋值 ce.setVoltageSource(j, vscount++); //设置电压源序号 } } int matrixSize = nodeList.Count - 1 + vscount; //矩阵大小 circuitMatrix = new float[matrixSize, matrixSize]; //初始电路矩阵 circuitRightSide = new float[matrixSize]; //初始电路右边矩阵 origMatrix = new float[matrixSize, matrixSize]; origRightSide = new float[matrixSize]; circuitMatrixSize = circuitMatrixFullSize = matrixSize; //初始电路矩阵大小 circuitRowInfo = new RowInfo[matrixSize]; //初始行信息 circuitPermute = new int[matrixSize]; //初始化电路交换数组 for (int i = 0; i < matrixSize; i++) { circuitRowInfo [i] = new RowInfo(); //创建电路矩阵行信息对象 } circuitNeedsMap = false; for (int i = 0; i < elmList.Count; i++) { CircuitElm ce = getElm(i); //获取元器件 ce.stamp(); //标记元器件,初始化电路矩阵 } for (int i = 0; i < CirSim.circuitMatrixSize; i++) { string s = i + ": "; for (int j = 0; j < CirSim.circuitMatrixSize; j++) { s += CirSim.circuitMatrix [i, j] + " "; } s += " " + CirSim.circuitRightSide [i]; Debug.Log(s); } //步骤四:处理图中未连接的结点 Debug.Log("步骤四"); bool[] closure = new bool[nodeList.Count]; bool[] tempclosure = new bool[nodeList.Count]; bool changed = true; //标志位 closure [0] = true; //从第0个结点开始 while (changed) { changed = false; //标志位置false for (int i = 0; i < elmList.Count; i++) //遍历所有元器件 { CircuitElm ce = getElm(i); //获取元器件 for (int j = 0; j < ce.getPostCount(); j++) //遍历元器件的端口 { if (!closure [ce.getNode(j)]) { if (ce.hasGroundConnection(j)) //若该端口连接到y阴极 { closure [ce.getNode(j)] = changed = true; } continue; } for (int k = 0; k < ce.getPostCount(); k++) //再次遍历元器件端口 { if (j == k) { continue; //若两个端口相等则继续 } int kn = ce.getNode(k); //获取端口对应的结点 if (ce.getConnection(j, k) && !closure [kn]) //若两端点相连并没有标记 { closure [kn] = true; changed = true; } } } } if (changed) { continue; } //连接未连接的结点 for (int i = 0; i < nodeList.Count; i++) { if (!closure [i]) { stampResistor(0, i, 1e8f); closure [i] = true; changed = true; break; } } } //步骤五:短路等无效连接的判断 Debug.Log("步骤五"); for (int i = 0; i < elmList.Count; i++) { CircuitElm ce = getElm(i); //获取元器件 //若为电压源或导线 if ((ce.type == TYPES.VoltageElm && ce.getPostCount() == 2) || (ce.type == TYPES.WireElm && ce.getPostCount() != 1)) { FindPathInfo fpi = new FindPathInfo(FindPathInfo.VOLTAGE, ce, ce.getNode(1)); if (fpi.findPath(ce.getNode(0))) //判断是否短路 //短路 { Utils.menuListener.PopTipUI("短 路"); Debug.Log("短路"); return; } } } //步骤六:简化矩阵 Debug.Log("步骤六"); for (int i = 0; i < matrixSize; i++) //遍历矩阵的每一行 { int qm = -1, qp = -1; float qv = 0; RowInfo re = circuitRowInfo [i]; //获取每一行的信息 if (re.lsChanges || re.dropRow || re.rsChanges) { continue; } float rsadd = 0; //寻找可以删除的行 int j; for (j = 0; j < matrixSize; j++) //遍历矩阵的每一行 { float q = circuitMatrix [i, j]; //获取矩阵值 if (circuitRowInfo [j].type == RowInfo.ROW_CONST) { rsadd -= circuitRowInfo [j].value * q; continue; } if (q == 0) { continue; //若矩阵值为0 } if (qp == -1) //记录第一个不为0的数值 { qp = j; //记录第一个不为0的列 qv = q; //记录该矩阵值 continue; } if (qm == -1 && q == -qv) //记录与qv互为相反数的列 { qm = j; //列数 continue; } break; } if (j == matrixSize) //若遍历完了该行 { if (qp == -1) { //矩阵错误 Debug.Log("矩阵错误"); return; } RowInfo elt = circuitRowInfo [qp]; //获取行信息 if (qm == -1) { //一行只有一个常数 int k; for (k = 0; elt.type == RowInfo.ROW_EQUAL && k < 100; k++) { qp = elt.nodeEq; elt = circuitRowInfo [qp]; } if (elt.type == RowInfo.ROW_EQUAL) { elt.type = RowInfo.ROW_NORMAL; continue; } if (elt.type != RowInfo.ROW_NORMAL) { continue; } elt.type = RowInfo.ROW_CONST; //标记为常数 elt.value = (circuitRightSide [i] + rsadd) / qv; //记录结点电压 circuitRowInfo [i].dropRow = true; //删除该行 i = -1; } else if (circuitRightSide [i] + rsadd == 0) { //若一行中只有两个非0的数值,并且两个数值互为相反数 if (elt.type != RowInfo.ROW_NORMAL) { int qq = qm; qm = qp; qp = qq; elt = circuitRowInfo [qp]; if (elt.type != RowInfo.ROW_NORMAL) { //交换失败 continue; } } elt.type = RowInfo.ROW_EQUAL; //标记行类型 elt.nodeEq = qm; //记录相等结点 circuitRowInfo [i].dropRow = true; //删除标志位置true } } } //步骤七:确定新矩阵的大小 Debug.Log("步骤七"); int nn = 0; for (int i = 0; i != matrixSize; i++) //遍历矩阵的行 { RowInfo elt = circuitRowInfo [i]; //获取电路行信息 if (elt.type == RowInfo.ROW_NORMAL) { elt.mapCol = nn++; continue; } if (elt.type == RowInfo.ROW_EQUAL) { RowInfo e2 = null; for (int j = 0; j != 100; j++) { e2 = circuitRowInfo [elt.nodeEq]; if (e2.type != RowInfo.ROW_EQUAL) { break; } if (i == e2.nodeEq) { break; } elt.nodeEq = e2.nodeEq; } } if (elt.type == RowInfo.ROW_CONST) { elt.mapCol = -1; } } for (int i = 0; i != matrixSize; i++) { RowInfo elt = circuitRowInfo [i]; if (elt.type == RowInfo.ROW_EQUAL) { RowInfo e2 = circuitRowInfo [elt.nodeEq]; if (e2.type == RowInfo.ROW_CONST) { elt.type = e2.type; elt.value = e2.value; elt.mapCol = -1; } else { elt.mapCol = e2.mapCol; } } } //步骤八:创建新的简化矩阵 Debug.Log("步骤八"); Debug.Log("nn-----------------" + nn); int newsize = nn; float[,] newmatx = new float[newsize, newsize]; float[] newrs = new float[newsize]; int ii = 0; for (int i = 0; i != matrixSize; i++) { RowInfo rri = circuitRowInfo [i]; if (rri.dropRow) { rri.mapRow = -1; continue; } newrs [ii] = circuitRightSide [i]; rri.mapRow = ii; //System.out.println("Row " + i + " maps to " + ii); for (int j = 0; j != matrixSize; j++) { RowInfo ri = circuitRowInfo [j]; if (ri.type == RowInfo.ROW_CONST) { newrs [ii] -= ri.value * circuitMatrix [i, j]; } else { newmatx [ii, ri.mapCol] += circuitMatrix [i, j]; } } ii++; } circuitMatrix = newmatx; circuitRightSide = newrs; matrixSize = circuitMatrixSize = newsize; for (int i = 0; i != matrixSize; i++) { origRightSide [i] = circuitRightSide [i]; } for (int i = 0; i != matrixSize; i++) { for (int j = 0; j != matrixSize; j++) { origMatrix [i, j] = circuitMatrix [i, j]; } } circuitNeedsMap = true; Debug.Log("--------新矩阵----------"); for (int i = 0; i < CirSim.circuitMatrixSize; i++) { string s = i + ": "; for (int j = 0; j < CirSim.circuitMatrixSize; j++) { s += CirSim.circuitMatrix [i, j] + " "; } s += " " + CirSim.circuitRightSide [i]; Debug.Log(s); } /*for (int i = 0; i != elmList.Count; i++) { * CircuitElm ce = getElm(i); * ce.doStep(); * }*/ if (!lu_factor(circuitMatrix, circuitMatrixSize, circuitPermute)) { Debug.Log("矩阵计算错误"); for (int i = 0; i < elmList.Count; i++) { getElm(i).stop(); //停止所有元器件 } return; } Debug.Log("--------LU分解后的矩阵----------"); for (int i = 0; i < CirSim.circuitMatrixSize; i++) { string s = i + ": "; for (int j = 0; j < CirSim.circuitMatrixSize; j++) { s += CirSim.circuitMatrix [i, j] + " "; } s += " " + CirSim.circuitRightSide [i]; Debug.Log(s); } //矩阵求解 lu_solve(circuitMatrix, circuitMatrixSize, circuitPermute, circuitRightSide); //为每个结点的电压赋值 for (int i = 0; i < circuitMatrixFullSize; i++) { RowInfo ri = circuitRowInfo [i]; //获取行信息 float res = 0; if (ri.type == RowInfo.ROW_CONST) { res = ri.value; } else { res = circuitRightSide [ri.mapCol]; } if (double.IsNaN(res)) //若是未知数结束循环 { Debug.Log("res is NaN"); break; } if (i < nodeList.Count - 1) { CircuitNode cn = getCircuitNode(i + 1); //获取结点 foreach (KeyValuePair <CircuitElm, int> kv in cn.links) //遍历结点上的所有端点 { kv.Key.setNodeVoltage(kv.Value, res); //为结点赋予电压 Debug.Log(kv.Key.type + "--" + kv.Value + " " + res); } } else { int j = i - (nodeList.Count - 1); voltageSources [j].setCurrent(j, res); } } for (int i = 0; i != elmList.Count; i++) { CircuitElm ce = getElm(i); ce.doStep(); } if (!isNext) { for (int i = 0; i < elmList.Count; i++) { CircuitElm ce = getElm(i); //获取元器件脚本 if (ce.type == TYPES.MusicChipElm || ce.type == TYPES.RecorderChipElm) //包含集成电路 { isNext = true; analyzeCircuit(); //重新分析电路 isNext = false; return; } } } //运行元器件 for (int i = 0; i < elmList.Count; i++) { CircuitElm ce = getElm(i); //获取元器件 ce.work(); //元器件工作 } }
public void AnalyzeCircuit() { bool debug = false; var elmList = mSim.ElmList; if (elmList.Count == 0) { PostDrawList = new List <Point>(); BadConnectionList = new List <Point>(); return; } StopMessage = null; StopElm = null; int vscount = 0; NodeList = new List <CircuitNode>(); mPostCountMap = new Dictionary <Point, int>(); bool gotGround = false; bool gotRail = false; CircuitElm volt = null; calculateWireClosure(); if (debug) { Console.WriteLine("ac1"); } /* look for voltage or ground element */ for (int i = 0; i != elmList.Count; i++) { var ce = mSim.getElm(i); if (ce is GroundElm) { gotGround = true; break; } if (ce is RailElm) { gotRail = true; } if (volt == null && (ce is VoltageElm)) { volt = ce; } } /* if no ground, and no rails, then the voltage elm's first terminal * /* is ground */ if (!gotGround && volt != null && !gotRail) { var cn = new CircuitNode(); var pt = volt.GetPost(0); NodeList.Add(cn); /* update node map */ if (mNodeMap.ContainsKey(pt)) { mNodeMap[pt].Node = 0; } else { mNodeMap.Add(pt, new NodeMapEntry(0)); } } else { /* otherwise allocate extra node for ground */ var cn = new CircuitNode(); NodeList.Add(cn); } if (debug) { Console.WriteLine("ac2"); } /* allocate nodes and voltage sources */ LabeledNodeElm.ResetNodeList(); for (int i = 0; i != elmList.Count; i++) { var ce = mSim.getElm(i); int inodes = ce.InternalNodeCount; int ivs = ce.VoltageSourceCount; int posts = ce.PostCount; /* allocate a node for each post and match posts to nodes */ for (int j = 0; j != posts; j++) { var pt = ce.GetPost(j); if (mPostCountMap.ContainsKey(pt)) { int g = mPostCountMap[pt]; mPostCountMap[pt] = g + 1; } else { mPostCountMap.Add(pt, 1); } NodeMapEntry cln = null; var ccln = mNodeMap.ContainsKey(pt); if (ccln) { cln = mNodeMap[pt]; } /* is this node not in map yet? or is the node number unallocated? * /* (we don't allocate nodes before this because changing the allocation order * /* of nodes changes circuit behavior and breaks backward compatibility; * /* the code below to connect unconnected nodes may connect a different node to ground) */ if (!ccln || cln.Node == -1) { var cn = new CircuitNode(); var cnl = new CircuitNodeLink(); cnl.Num = j; cnl.Elm = ce; cn.Links.Add(cnl); ce.SetNode(j, NodeList.Count); if (ccln) { cln.Node = NodeList.Count; } else { mNodeMap.Add(pt, new NodeMapEntry(NodeList.Count)); } NodeList.Add(cn); } else { int n = cln.Node; var cnl = new CircuitNodeLink(); cnl.Num = j; cnl.Elm = ce; getCircuitNode(n).Links.Add(cnl); ce.SetNode(j, n); /* if it's the ground node, make sure the node voltage is 0, * /* cause it may not get set later */ if (n == 0) { ce.SetNodeVoltage(j, 0); } } } for (int j = 0; j != inodes; j++) { var cn = new CircuitNode(); cn.Internal = true; var cnl = new CircuitNodeLink(); cnl.Num = j + posts; cnl.Elm = ce; cn.Links.Add(cnl); ce.SetNode(cnl.Num, NodeList.Count); NodeList.Add(cn); } vscount += ivs; } makePostDrawList(); if (!calcWireInfo()) { return; } mNodeMap = null; /* done with this */ VoltageSources = new CircuitElm[vscount]; vscount = 0; CircuitNonLinear = false; if (debug) { Console.WriteLine("ac3"); } /* determine if circuit is nonlinear */ for (int i = 0; i != elmList.Count; i++) { var ce = mSim.getElm(i); if (ce.NonLinear) { CircuitNonLinear = true; } int ivs = ce.VoltageSourceCount; for (int j = 0; j != ivs; j++) { VoltageSources[vscount] = ce; ce.SetVoltageSource(j, vscount++); } } VoltageSourceCount = vscount; int matrixSize = NodeList.Count - 1 + vscount; Matrix = new double[matrixSize, matrixSize]; mRightSide = new double[matrixSize]; mOrigMatrix = new double[matrixSize, matrixSize]; mOrigRightSide = new double[matrixSize]; mMatrixSize = mMatrixFullSize = matrixSize; mRowInfo = new RowInfo[matrixSize]; mPermute = new int[matrixSize]; for (int i = 0; i != matrixSize; i++) { mRowInfo[i] = new RowInfo(); } mCircuitNeedsMap = false; /* stamp linear circuit elements */ for (int i = 0; i != elmList.Count; i++) { var ce = mSim.getElm(i); ce.Stamp(); } if (debug) { Console.WriteLine("ac4"); } /* determine nodes that are not connected indirectly to ground */ var closure = new bool[NodeList.Count]; bool changed = true; closure[0] = true; while (changed) { changed = false; for (int i = 0; i != elmList.Count; i++) { var ce = mSim.getElm(i); if (ce is WireElm) { continue; } /* loop through all ce's nodes to see if they are connected * /* to other nodes not in closure */ for (int j = 0; j < ce.ConnectionNodeCount; j++) { if (!closure[ce.GetConnectionNode(j)]) { if (ce.HasGroundConnection(j)) { closure[ce.GetConnectionNode(j)] = changed = true; } continue; } int k; for (k = 0; k != ce.ConnectionNodeCount; k++) { if (j == k) { continue; } int kn = ce.GetConnectionNode(k); if (ce.GetConnection(j, k) && !closure[kn]) { closure[kn] = true; changed = true; } } } } if (changed) { continue; } /* connect one of the unconnected nodes to ground with a big resistor, then try again */ for (int i = 0; i != NodeList.Count; i++) { if (!closure[i] && !getCircuitNode(i).Internal) { /* Console.WriteLine("node " + i + " unconnected"); */ StampResistor(0, i, 1e8); closure[i] = true; changed = true; break; } } } if (debug) { Console.WriteLine("ac5"); } for (int i = 0; i != elmList.Count; i++) { var ce = mSim.getElm(i); /* look for inductors with no current path */ if (ce is InductorElm) { var fpi = new PathInfo(PathType.INDUCTOR, ce, ce.Nodes[1], elmList, NodeList.Count); if (!fpi.FindPath(ce.Nodes[0])) { if (debug) { Console.WriteLine(ce + " no path"); } ce.Reset(); } } /* look for current sources with no current path */ if (ce is CurrentElm) { var cur = (CurrentElm)ce; var fpi = new PathInfo(PathType.INDUCTOR, ce, ce.Nodes[1], elmList, NodeList.Count); if (!fpi.FindPath(ce.Nodes[0])) { cur.stampCurrentSource(true); } else { cur.stampCurrentSource(false); } } if (ce is VCCSElm) { var cur = (VCCSElm)ce; var fpi = new PathInfo(PathType.INDUCTOR, ce, cur.getOutputNode(0), elmList, NodeList.Count); if (cur.hasCurrentOutput() && !fpi.FindPath(cur.getOutputNode(1))) { cur.mBroken = true; } else { cur.mBroken = false; } } /* look for voltage source or wire loops. we do this for voltage sources or wire-like elements (not actual wires * /* because those are optimized out, so the findPath won't work) */ if (2 == ce.PostCount) { if ((ce is VoltageElm) || (ce.IsWire && !(ce is WireElm))) { var fpi = new PathInfo(PathType.VOLTAGE, ce, ce.Nodes[1], elmList, NodeList.Count); if (fpi.FindPath(ce.Nodes[0])) { Stop("Voltage source/wire loop with no resistance!", ce); return; } } } else if (ce is Switch2Elm) { /* for Switch2Elms we need to do extra work to look for wire loops */ var fpi = new PathInfo(PathType.VOLTAGE, ce, ce.Nodes[0], elmList, NodeList.Count); for (int j = 1; j < ce.PostCount; j++) { if (ce.GetConnection(0, j) && fpi.FindPath(ce.Nodes[j])) { Stop("Voltage source/wire loop with no resistance!", ce); return; } } } /* look for path from rail to ground */ if ((ce is RailElm) || (ce is LogicInputElm)) { var fpi = new PathInfo(PathType.VOLTAGE, ce, ce.Nodes[0], elmList, NodeList.Count); if (fpi.FindPath(0)) { Stop("Path to ground with no resistance!", ce); return; } } /* look for shorted caps, or caps w/ voltage but no R */ if (ce is CapacitorElm) { var fpi = new PathInfo(PathType.SHORT, ce, ce.Nodes[1], elmList, NodeList.Count); if (fpi.FindPath(ce.Nodes[0])) { Console.WriteLine(ce + " shorted"); ((CapacitorElm)ce).Shorted(); } else { /* a capacitor loop used to cause a matrix error. but we changed the capacitor model * /* so it works fine now. The only issue is if a capacitor is added in parallel with * /* another capacitor with a nonzero voltage; in that case we will get oscillation unless * /* we reset both capacitors to have the same voltage. Rather than check for that, we just * /* give an error. */ fpi = new PathInfo(PathType.CAPACITOR_V, ce, ce.Nodes[1], elmList, NodeList.Count); if (fpi.FindPath(ce.Nodes[0])) { Stop("Capacitor loop with no resistance!", ce); return; } } } } if (debug) { Console.WriteLine("ac6"); } if (!simplifyMatrix(matrixSize)) { return; } if (debug) { Console.WriteLine("matrixSize = " + matrixSize + " " + CircuitNonLinear); for (int j = 0; j != mMatrixSize; j++) { Console.WriteLine("RightSide[{0}]:{1}", j, mRightSide[j]); for (int i = 0; i != mMatrixSize; i++) { Console.WriteLine(" Matrix[{0},{1}]:{2}", j, i, Matrix[j, i]); } } } /* check if we called stop() */ if (Matrix == null) { return; } /* if a matrix is linear, we can do the lu_factor here instead of * /* needing to do it every frame */ if (!CircuitNonLinear) { if (!luFactor(Matrix, mMatrixSize, mPermute)) { Stop("Singular matrix!", null); return; } } /* show resistance in voltage sources if there's only one */ bool gotVoltageSource = false; ShowResistanceInVoltageSources = true; for (int i = 0; i != elmList.Count; i++) { var ce = mSim.getElm(i); if (ce is VoltageElm) { if (gotVoltageSource) { ShowResistanceInVoltageSources = false; } else { gotVoltageSource = true; } } } }