Пример #1
0
 //标记元器件
 public override void stamp()
 {
     if (isOpen)
     {
         CirSim.stampVoltageSource(nodes[0], nodes[1], voltSource[0], 0);
     }
 }
Пример #2
0
 //标记矩阵
 public override void stamp()
 {
     //标记两个结点矩阵的非线性
     CirSim.stampNonLinear(nodes[0]);
     CirSim.stampNonLinear(nodes[1]);
     //doStep();
 }
Пример #3
0
 //标记矩阵
 public override void stamp()
 {
     CirSim.stampNonLinear(nodes[0]);
     CirSim.stampNonLinear(nodes[1]);
     CirSim.stampNonLinear(nodes[2]);
     doStep();
 }
Пример #4
0
 //标记元器件
 public override void stamp()
 {
     for (int i = 0; i < getPostCount() - 1; i++)
     {
         CirSim.stampResistor(nodes[i], nodes[8], resistance);               //每个端点都与正极之间有一个电阻
     }
 }
Пример #5
0
    //进行下一步
    public override void doStep()
    {
        float vbc = volts[0] - volts[1];      // typically negative
        float vbe = volts[0] - volts[2];      // typically positive

        if (Mathf.Abs(vbc - lastvbc) > .01 || // .01
            Mathf.Abs(vbe - lastvbe) > .01)
        {
            gmin = 0;
        }
        //System.out.print("T " + vbc + " " + vbe + "\n");
        vbc     = pnp * limitStep(pnp * vbc, pnp * lastvbc);
        vbe     = pnp * limitStep(pnp * vbe, pnp * lastvbe);
        lastvbc = vbc;
        lastvbe = vbe;
        float pcoef = vdcoef * pnp;
        float expbc = Mathf.Exp(vbc * pcoef);

        /*if (expbc > 1e13 || Double.isInfinite(expbc))
         *    expbc = 1e13;*/
        double expbe = Mathf.Exp(vbe * pcoef);

        if (expbe < 1)
        {
            expbe = 1;
        }

        /*if (expbe > 1e13 || Double.isInfinite(expbe))
         *    expbe = 1e13;*/
        ie = (float)(pnp * leakage * (-(expbe - 1) + rgain * (expbc - 1)));
        ic = (float)(pnp * leakage * (fgain * (expbe - 1) - (expbc - 1)));
        ib = -(ie + ic);
        //System.out.println("gain " + ic/ib);
        //System.out.print("T " + vbc + " " + vbe + " " + ie + " " + ic + "\n");
        float gee = (float)(-leakage * vdcoef * expbe);
        float gec = rgain * leakage * vdcoef * expbc;
        float gce = -gee * fgain;
        float gcc = -gec * (1 / rgain);

        // stamps from page 302 of Pillage.  Node 0 is the base,
        // node 1 the collector, node 2 the emitter.  Also stamp
        // minimum conductance (gmin) between b,e and b,c
        CirSim.stampMatrix(nodes[0], nodes[0], -gee - gec - gce - gcc + gmin * 2);
        CirSim.stampMatrix(nodes[0], nodes[1], gec + gcc - gmin);
        CirSim.stampMatrix(nodes[0], nodes[2], gee + gce - gmin);
        CirSim.stampMatrix(nodes[1], nodes[0], gce + gcc - gmin);
        CirSim.stampMatrix(nodes[1], nodes[1], -gcc + gmin);
        CirSim.stampMatrix(nodes[1], nodes[2], -gce);
        CirSim.stampMatrix(nodes[2], nodes[0], gee + gec - gmin);
        CirSim.stampMatrix(nodes[2], nodes[1], -gec);
        CirSim.stampMatrix(nodes[2], nodes[2], -gee + gmin);

        // we are solving for v(k+1), not delta v, so we use formula
        // 10.5.13, multiplying J by v(k)
        CirSim.stampRightSide(nodes[0], -ib - (gec + gcc) * vbc - (gee + gce) * vbe);
        CirSim.stampRightSide(nodes[1], -ic + gce * vbe + gcc * vbc);
        CirSim.stampRightSide(nodes[2], -ie + gee * vbe + gec * vbc);
    }
Пример #6
0
    //标记元器件
    public override void stamp()
    {
        if (isRun)
        {
            CirSim.stampVoltageSource(0, nodes[1], voltSource[0], 999);                 //输出电压为999
            isRun = false;                                                              //运行标志位置false
        }
        else
        {
            CirSim.stampVoltageSource(0, nodes[1], voltSource[0], 0);                   //输出电压为0
        }

        CirSim.stampResistor(nodes[0], nodes[3], 10);                           //0 3结点间为10欧姆的电阻
    }
Пример #7
0
    //灯泡损坏协程
    IEnumerator Damage(float delayTime)
    {
        yield return(new WaitForSeconds(delayTime));                             //等待delayTime秒

        Flash.SetActive(true);                                                   //闪光效果
        Utils.audioManager.playAudio(2);                                         //播放烧毁音效
        stop();                                                                  //小灯泡停止工作
        isDamaged = true;                                                        //元器件破损
        CirSim.damageList.Add(transform.GetComponent <CircuitElm>());            //添加进损坏列表
        CirSim.analyzeCircuit();                                                 //重新分析电路
        yield return(new WaitForSeconds(0.5f));                                  //等待音效播放完

        smoke.Play();                                                            //触发粒子系统
        Utils.menuListener.PopTipUI("灯泡烧毁");                                     //弹出提示界面
    }
Пример #8
0
    //进行下一步
    public override void doStep()
    {
        setUp();
        float voltdiff = volts[0] - volts[1];                           //电势

        voltdiff     = limitStep(voltdiff, lastvoltdiff);
        lastvoltdiff = voltdiff;

        if (voltdiff >= 0 || zvoltage == 0)
        {
            // regular diode or forward-biased zener
            float eval = Mathf.Exp(voltdiff * vdcoef);
            // make diode linear with negative voltages; aids convergence
            if (voltdiff < 0)
            {
                eval = 1;
            }
            float geq = vdcoef * leakage * eval;
            float nc  = (eval - 1) * leakage - geq * voltdiff;
            CirSim.stampConductance(nodes[0], nodes[1], geq);
            CirSim.stampCurrentSource(nodes[0], nodes[1], nc);
        }
        else
        {
            // Zener diode

            /*
             * I(Vd) = Is * (exp[Vd*C] - exp[(-Vd-Vz)*C] - 1 )
             *
             * geq is I'(Vd)
             * nc is I(Vd) + I'(Vd)*(-Vd)
             */

            float geq = leakage * vdcoef * (
                Mathf.Exp(voltdiff * vdcoef) + Mathf.Exp((-voltdiff - zoffset) * vdcoef));

            float nc = leakage * (
                Mathf.Exp(voltdiff * vdcoef)
                - Mathf.Exp((-voltdiff - zoffset) * vdcoef)
                - 1
                ) + geq * (-voltdiff);

            CirSim.stampConductance(nodes[0], nodes[1], geq);
            CirSim.stampCurrentSource(nodes[0], nodes[1], nc);
        }
    }
Пример #9
0
 void Update()
 {
     value = transform.GetComponent <Scrollbar> ().value;
     if (value == oldValue)
     {
         return;
     }
     for (int i = 0; i < PhotosensitiveResistorElm.Length; i++)
     {
         Debug.Log(PhotosensitiveResistorElm.Length);
         PhotosensitiveResistorElm[i].GetComponent <PhotosensitiveResistorElm> ().resistance             = 100.0f * (1 - value);
         PhotosensitiveResistorElm[i].transform.FindChild("Spotlight").GetComponent <Light> ().intensity = 8.0f * value;
         if (PhotosensitiveResistorElm[i].GetComponent <PhotosensitiveResistorElm> ().resistance < 5.0f)
         {
             PhotosensitiveResistorElm[i].GetComponent <PhotosensitiveResistorElm> ().resistance = 5.0f;
         }
     }
     CirSim.analyzeCircuit();                        //分析电路
     oldValue = transform.GetComponent <Scrollbar> ().value;
 }
Пример #10
0
    //标记元器件
    public override void stamp()
    {
        if (ICState == -1)                                                         //开始录音,在连接话筒的两个端口施加电压
        {
            CirSim.stampVoltageSource(nodes[3], nodes[5], voltSource[0], 0.0555f); //标记两个连接话筒的端点 0.0555位话筒接收的电压值
            Debug.Log("ICState状态为-1");
        }

        if (ICState == 1)                                                       //播放录音,在输出端口施加电压
        {
            CirSim.stampVoltageSource(0, nodes[4], voltSource[0], 998f);        //输出电压为998
            Debug.Log("ICState状态为1");
        }

        Debug.Log("ICState状态为0");
        //标记电阻
        CirSim.stampResistor(nodes[6], nodes[0], resistance);          //6 0结点间为5欧姆的电阻
        CirSim.stampResistor(nodes[6], nodes[1], resistance);          //6 1结点间为5欧姆的电阻
        CirSim.stampResistor(nodes[6], nodes[2], resistance);          //6 2结点间为5欧姆的电阻
    }
Пример #11
0
 //标记元器件
 public override void stamp()
 {
     CirSim.stampResistor(nodes [0], nodes [1], resistance);
 }
Пример #12
0
    // 移动平台触屏操作
    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);
                        }
                    }
                }
            }
        }
    }
Пример #13
0
 //标记元器件
 public override void stamp()
 {
     CirSim.stampResistor(nodes[0], nodes[2], maxResistance * ratio);
     CirSim.stampResistor(nodes[1], nodes[2], maxResistance * (1 - ratio));
 }
Пример #14
0
 //标记元器件
 public override void stamp()
 {
     CirSim.stampVoltageSource(nodes[0], nodes[1], voltSource[0], 0);        //标记元器件
 }
Пример #15
0
 //标记元器件
 public override void stamp()
 {
     CirSim.stampVoltageSource(nodes[0], nodes[1], voltSource[0], getVoltage());
 }