Пример #1
0
    public void OnMouseUp()
    {
        Vector3 MouseUpVec = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        MouseUpVec.z = 0f;
        MouseUpVec  /= thisKnot.GlobalRate;
        if (Display.IsDrawKnotMode())
        {
            if (DraggedNode != null)
            {     //ノードマウスダウンから始めたとき
                if ((MouseUpVec - MouseDownVec).magnitude < 0.05f && DraggedNode.ThisBead.Joint)
                { // ノードをクリック -> クロシングチェンジ
                 //ビーズのデータの変更
                    Bead bd  = DraggedNode.ThisBead;
                    Bead tmp = bd.N1;
                    bd.N1 = bd.U2;
                    bd.U2 = bd.N2;
                    bd.N2 = bd.U1;
                    bd.U1 = tmp;
                    //ノードのデータの変更
                    DraggedNode.Theta -= Mathf.PI / 2f;
                    float rtmp = DraggedNode.R[0];
                    DraggedNode.R[0] = DraggedNode.R[3];
                    DraggedNode.R[3] = DraggedNode.R[2];
                    DraggedNode.R[2] = DraggedNode.R[1];
                    DraggedNode.R[1] = rtmp;
                    //エッジのデータの変更
                    Edge[] AllEdges = FindObjectsOfType <Edge>();
                    for (int e = 0; e < AllEdges.Length; e++)
                    {
                        Edge ed = AllEdges[e];
                        if (ed.ANodeID == DraggedNode.ID)
                        {
                            ed.ANodeRID = (ed.ANodeRID + 1) % 4;
                        }
                        else if (ed.BNodeID == DraggedNode.ID)
                        {
                            ed.BNodeRID = (ed.BNodeRID + 1) % 4;
                        }
                    }
                }
                //ノードをドラッグしたときは後処理なし
                DraggedNode = null;
            }
            // フリーカーブを描いているとき
            else if (StartFreeCurveBead != null)
            {
                // スポットを消去する
                //Spot[] NodeSpots = FindObjectsOfType<Spot>();
                //for(int i= NodeSpots.Length; i>=0; i--)
                //{
                //    Destroy(NodeSpots[i].gameObject);
                //}
                ////終了地点がノードでないことが要件
                bool NoProc = false;
                //終了地点がノードだったら、非処理フラグを立てる
                thisKnot.GetAllThings();
                for (int n = 0; n < thisKnot.AllNodes.Length; n++)
                {
                    if ((thisKnot.AllNodes[n].Position - MouseUpVec).magnitude < 0.2f)
                    {
                        NoProc = true;
                    }
                }
                //終了地点がビーズだったら、処理に入る。
                //終了地点がビーズでなかったら、非処理フラグを立てる
                Bead EndFreeCurveBead = null;
                if (!NoProc)
                {
                    NoProc = true;
                    for (int b = 0; b < thisKnot.AllBeads.Length; b++)
                    {
                        if ((thisKnot.AllBeads[b].Position - MouseUpVec).magnitude < 0.15f)
                        {
                            NoProc = false;
                            // 終了ビーズを記録
                            EndFreeCurveBead = thisKnot.AllBeads[b];
                            break;
                        }
                    }
                }
                //非処理フラグが立っていたらフリーカーブを消去して終わり
                if (NoProc)
                {
                    thisFreeLoop.FreeCurve.Clear();
                }
                else// 処理に入る
                {
                    // 開始ビーズから終了ビーズをたどる方法を探索
                    // 開始ビーズから終了ビーズの間にクロシングがどのように表れるかを調査。
                    // first : 0:何もなし、1:オーバーのみ、2:アンダーのみ
                    // second : ビーズ距離
                    PairInt GotoN1 = thisKnot.FindBeadAlongCurve(StartFreeCurveBead, StartFreeCurveBead.N1, EndFreeCurveBead);
                    PairInt GotoN2 = thisKnot.FindBeadAlongCurve(StartFreeCurveBead, StartFreeCurveBead.N2, EndFreeCurveBead);
                    //Debug.Log(GotoN1.first + "," + GotoN2.first);
                    bool BothOK = (GotoN1.first != -1) && (GotoN2.first != -1);
                    // オーバーのみ、またはアンダーのみの時には処理を開始(どちらともとれる場合には、短いほう)
                    if (GotoN1.first != -1 || (BothOK && GotoN1.second < GotoN2.second))
                    {
                        // 開始ビーズから終了ビーズまでの既存のビーズラインを消去
                        thisKnot.DeleteBeadsFromTo(StartFreeCurveBead, StartFreeCurveBead.N1, EndFreeCurveBead);
                        // フリーループにあたる部分をビーズへと変換
                        thisKnot.FreeCurve2Bead(StartFreeCurveBead, EndFreeCurveBead, GotoN1.first);
                        // 旧フリーループと旧ビーズとの交点を探してジョイントにする。
                    }
                    else if (GotoN2.first != -1 || (BothOK && GotoN1.second > GotoN2.second))
                    {
                        // 開始ビーズから終了ビーズまでの既存のビーズラインを消去
                        thisKnot.DeleteBeadsFromTo(StartFreeCurveBead, StartFreeCurveBead.N2, EndFreeCurveBead);
                        // フリーループにあたる部分をビーズへと変換
                        thisKnot.FreeCurve2Bead(StartFreeCurveBead, EndFreeCurveBead, GotoN2.first);
                        // 旧フリーループと旧ビーズとの交点を探してジョイントにする。
                    }
                    else //書き換える条件を満たしていないとき
                    {//すべてを消去して終了
                        thisFreeLoop.FreeCurve.Clear();
                        Display.SetDrawKnotMode();
                    }
                    // グラフ構造を書き換える
                    // 形を整える
                    //thisKnot.Modify();
                    //thisKnot.UpdateBeads();
                }
            }
            else if (StartFreeLoop)
            {
                StartFreeLoop = false;//必ずフリーループモードは終了
                if (!thisFreeLoop.CircleEffectEnable)
                {
                    thisFreeLoop.FreeCurve.Clear();
                    Display.SetDrawKnotMode();
                    // フリーループモードから抜けたことが直感的にわかりにくい。
                }
                else
                {
                    // まず1列のbeadの列を作る。
                    int BeadCount     = thisKnot.GetMaxIDOfBead();
                    int freeCurveSize = thisFreeLoop.FreeCurve.Count;
                    for (int b = 0; b < freeCurveSize; b++)
                    {
                        //ビーズを追加(ID番号=BeadCount + 1 + b)
                        thisKnot.AddBead(thisFreeLoop.FreeCurve[b], BeadCount + 1 + b);
                    }
                    //FreeCurveをクリアしておく
                    thisFreeLoop.CircleEffect.GetComponent <LineRenderer>().enabled
                        = thisFreeLoop.CircleEffectEnable = false;
                    thisFreeLoop.FreeCurve.Clear();
                    thisKnot.AllBeads = FindObjectsOfType <Bead>();
                    // N1,N2, NumOfNbhdを設定
                    for (int b = 0; b < freeCurveSize; b++)
                    {
                        Bead bd = thisKnot.GetBeadByID(BeadCount + 1 + b);
                        bd.N1        = thisKnot.GetBeadByID(BeadCount + 1 + (b + 1) % freeCurveSize);
                        bd.N2        = thisKnot.GetBeadByID(BeadCount + 1 + (b + freeCurveSize - 1) % freeCurveSize);
                        bd.NumOfNbhd = 2;
                    }
                    //重複も許して交点を検出
                    List <PairInt> meets = new List <PairInt>();
                    for (int b1 = 0; b1 < thisKnot.GetMaxIDOfBead() + 1; b1++)
                    {
                        Bead b1c = thisKnot.GetBeadByID(b1);
                        if (b1c == null)
                        {
                            continue;
                        }
                        Bead b1n = b1c.N1;
                        Bead b1p = b1c.N2;
                        if (b1n == null || b1p == null)
                        {
                            continue;
                        }
                        for (int b2 = BeadCount + 1; b2 < BeadCount + freeCurveSize; b2++)
                        {
                            if (b1 >= b2)
                            {
                                continue;
                            }
                            Bead b2c = thisKnot.GetBeadByID(b2);
                            if (b2c == null)
                            {
                                continue;
                            }
                            Bead b2n = b2c.N1;
                            Bead b2p = b2c.N2;
                            if (b2n == null || b2p == null)
                            {
                                continue;
                            }
                            if (b1c == b2n || b1c == b2p || b1n == b2c || b1n == b2p)
                            {
                                continue;                                                       // そもそも異なる場所である保証。
                            }
                            if (GetMeetPairOfNewFreeCurve(b1, b1n, b1p, b2, b2n, b2p, meets))
                            {
                                meets.Add(new PairInt(b1, b2));
                            }
                        }
                    }
                    if (meets.Count == 0)
                    {
                        // ある程度の長さがありかつ交点の個数が0ならば、トリビアルな成分を追加する。
                        if (freeCurveSize > 20)
                        {
                            Bead Bd = thisKnot.GetBeadByID(BeadCount + 1 + 1);
                            Bd.MidJoint = true;
                            Bd          = thisKnot.GetBeadByID(BeadCount + 1 + Mathf.FloorToInt(freeCurveSize / 3));
                            Bd.MidJoint = true;
                            Bd          = thisKnot.GetBeadByID(BeadCount + 1 + Mathf.FloorToInt(2 * freeCurveSize / 3));
                            Bd.MidJoint = true;
                            // BeadsからNodeEdgeを更新する
                            thisKnot.CreateNodesEdgesFromBeads();
                            // 形を整える
                            thisKnot.GetAllThings();
                            thisKnot.Modify();
                            thisKnot.UpdateBeads();
                        }
                        else
                        {// 交点の個数が0ならば、新規Beadを全部捨てる。
                            thisKnot.AllBeads = FindObjectsOfType <Bead>();
                            for (int i = 0; i < thisKnot.AllBeads.Length; i++)
                            {
                                Bead bd = thisKnot.AllBeads[i];
                                if (bd.ID > BeadCount)
                                {
                                    bd.N1        = bd.N2 = null;
                                    bd.NumOfNbhd = 0;
                                    bd.Active    = false;
                                }
                            }
                        }
                        //モードを戻しておく
                        Display.SetDrawKnotMode();
                    }
                    else
                    {// さもなくば、交点に当たるところをJointにする
                        for (int i = 0; i < meets.Count; i++)
                        {
                            int  b1  = meets[i].first;
                            int  b2  = meets[i].second;
                            Bead bd1 = thisKnot.GetBeadByID(b1);
                            Bead bd2 = thisKnot.GetBeadByID(b2);
                            if (bd1 == null || bd2 == null)
                            {
                                continue;
                            }
                            if (bd1.N1 == null || bd2.N1 == null || bd2.N2 == null)
                            {
                                continue;
                            }
                            bd1.Joint = true;
                            //Nbhdの繋ぎ替え
                            // これをどちらにどちらをつなぐかは、選ぶ必要がある。
                            float bd1x   = bd1.Position.x;
                            float bd1y   = bd1.Position.y;
                            float n1x    = bd1.N1.Position.x - bd1x;
                            float n1y    = bd1.N1.Position.y - bd1y;
                            float bd2n1x = bd2.N1.Position.x - bd1x;
                            float bd2n1y = bd2.N1.Position.y - bd1y;
                            float bd2n2x = bd2.N2.Position.x - bd1x;
                            float bd2n2y = bd2.N2.Position.y - bd1y;
                            if (n1x * bd2n1y - n1y * bd2n1x > 0 && n1x * bd2n2y - n1y * bd2n2x < 0)
                            {
                                bd1.U1 = bd2.N1;
                                bd1.U2 = bd2.N2;
                            }
                            else
                            {
                                bd1.U1 = bd2.N2;
                                bd1.U2 = bd2.N1;
                            }
                            if (bd2.N1.N1 == bd2)
                            {
                                bd2.N1.N1 = bd1;
                            }
                            else if (bd2.N1.N2 == bd2)
                            {
                                bd2.N1.N2 = bd1;
                            }
                            if (bd2.N2.N1 == bd2)
                            {
                                bd2.N2.N1 = bd1;
                            }
                            else if (bd2.N2.N2 == bd2)
                            {
                                bd2.N2.N2 = bd1;
                            }
                            //消去
                            bd2.Active = false;//
                            // Joint-Jointとなるエッジには間にMidJointを必ず追加する。
                            for (int r1 = 0; r1 < 4; r1++)
                            {
                                PairInt br2     = thisKnot.FindEndOfEdgeOnBead(bd1, r1, true);
                                Bead    endBead = thisKnot.FindBeadByID(br2.first);
                                if (endBead != null && endBead.Joint)
                                {
                                    // ジョイント間のビーズ数を数える。
                                    int count = thisKnot.CountBeadsOnEdge(bd1, r1);
                                    // midJointを作る
                                    Bead midJointBead = thisKnot.GetBeadOnEdge(bd1, r1, Mathf.FloorToInt(count / 2));
                                    if (midJointBead != null)
                                    {
                                        midJointBead.MidJoint = true;
                                    }
                                    //Debug.Log(bd.ID + "," + r1 + "->" + br2.first + "," + br2.second + "(" + count + ")");
                                }
                            }
                        }
                        thisKnot.AllBeads = FindObjectsOfType <Bead>();
                        // BeadsからNodeEdgeを更新する
                        thisKnot.CreateNodesEdgesFromBeads();
                        // 形を整える
                        thisKnot.GetAllThings();
                        thisKnot.Modify();
                        thisKnot.UpdateBeads();
                    }
                }
            }
        }
        else if (Display.IsFreeLoopMode())
        {
            StartFreeLoop = false;//必ずフリーループモードは終了
            //スタート地点に近くない場所で終了した場合には、すべてを消去して終了
            if (!thisFreeLoop.CircleEffectEnable)
            {
                thisFreeLoop.FreeCurve.Clear();
                Display.SetDrawKnotMode();
                // フリーループモードから抜けたことが直感的にわかりにくい。
            }
            else //
            {
                //以下は長い処理なので、メソッド化が望ましい。
                //スタート地点に近い場所で終わった場合は、まずはBeadへと変換する。
                // すべてのビーズを消す(不要)
                thisKnot.ClearAll();
                // まず1列のbeadの列を作る。
                int freeCurveSize = thisFreeLoop.FreeCurve.Count;
                for (int b = 0; b < freeCurveSize; b++)
                {
                    //ビーズを追加(b=ID番号)
                    thisKnot.AddBead(thisFreeLoop.FreeCurve[b], b);
                }
                //FreeCurveをクリアしておく
                thisFreeLoop.CircleEffect.GetComponent <LineRenderer>().enabled
                    = thisFreeLoop.CircleEffectEnable = false;
                thisFreeLoop.FreeCurve.Clear();
                // 新規ビーズのデータを整える
                thisKnot.AllBeads = FindObjectsOfType <Bead>();
                freeCurveSize     = thisKnot.AllBeads.Length;// おそらく無意味
                for (int b = 0; b < freeCurveSize; b++)
                {
                    // N1,N2, NumOfNbhdを設定
                    Bead bd = thisKnot.AllBeads[b];
                    bd.N1        = thisKnot.AllBeads[(b + 1) % freeCurveSize];
                    bd.N2        = thisKnot.AllBeads[(b + freeCurveSize - 1) % freeCurveSize];
                    bd.NumOfNbhd = 2;
                }
                //モードを戻しておく
                Display.SetDrawKnotMode();

                //重複も許して交点を検出
                List <PairInt> meets = new List <PairInt>();
                for (int b1 = 0; b1 < freeCurveSize; b1++)
                {
                    int b1n = (b1 + 1) % freeCurveSize;
                    int b1p = (b1 + freeCurveSize - 1) % freeCurveSize;
                    for (int b2 = b1 + 1; b2 < freeCurveSize; b2++)
                    {
                        int b2n = (b2 + 1) % freeCurveSize;
                        int b2p = (b2 + freeCurveSize - 1) % freeCurveSize;
                        //int difference = (b2 - b1 + freeCurveSize) % freeCurveSize;//なぜ?
                        int difference = b2 - b1;
                        if (2 < difference && difference < freeCurveSize - 2)
                        {// そもそも異なる場所である保証。
                            float x1 = thisKnot.AllBeads[b1p].Position.x;
                            float y1 = thisKnot.AllBeads[b1p].Position.y;
                            float x2 = thisKnot.AllBeads[b1n].Position.x;
                            float y2 = thisKnot.AllBeads[b1n].Position.y;
                            float x3 = thisKnot.AllBeads[b2p].Position.x;
                            float y3 = thisKnot.AllBeads[b2p].Position.y;
                            float x4 = thisKnot.AllBeads[b2n].Position.x;
                            float y4 = thisKnot.AllBeads[b2n].Position.y;
                            // (x2-x1)s+x1 = (x4-x3)t+x3
                            // (y2-y1)s+y1 = (y4-y3)t+y3
                            // (x2-x1)s - (x4-x3)t = +x3-x1
                            // (y2-y1)s - (y4-y3)t = +y3-y1
                            float a  = x2 - x1;
                            float b  = -x4 + x3;
                            float c  = y2 - y1;
                            float d  = -y4 + y3;
                            float p  = x3 - x1;
                            float q  = y3 - y1;
                            float s1 = p * d - b * q; // s = s1/st
                            float t1 = a * q - p * c; // t = t1/st
                            float st = a * d - b * c;
                            if (st < 0)
                            {
                                st *= -1;
                                s1 *= -1;
                                t1 *= -1;
                            }
                            if (0 < s1 && s1 < st && 0 < t1 && t1 < st)
                            { // 線分が交わっている条件
                                //重複を排してListに貯める
                                bool OK = true;
                                for (int mt = 0; mt < meets.Count; mt++)
                                {
                                    int m1 = meets[mt].first;
                                    int m2 = meets[mt].second;
                                    if (Math.Abs(b1 - m1) <= 2 && Math.Abs(b2 - m2) <= 2)
                                    {
                                        //Debug.Log("(" + b1 + "," + b2 + ")=(" + m1 + "," + m2 + ")");
                                        OK = false;
                                        break;
                                    }
                                }
                                if (OK)
                                {
                                    meets.Add(new PairInt(b1, b2));
                                }
                            }
                        }
                    }
                }
                if (meets.Count == 0)
                {// ある程度の長さがありかつ交点の個数が0ならば、トリビアルな成分を追加する。
                    if (freeCurveSize > 20)
                    {
                        Bead Bd = thisKnot.AllBeads[1];
                        Bd.MidJoint = true;
                        Bd          = thisKnot.AllBeads[Mathf.FloorToInt(freeCurveSize / 3)];
                        Bd.MidJoint = true;
                        Bd          = thisKnot.AllBeads[Mathf.FloorToInt(2 * freeCurveSize / 3)];
                        Bd.MidJoint = true;
                        // BeadsからNodeEdgeを更新する
                        thisKnot.CreateNodesEdgesFromBeads();
                        // 形を整える
                        thisKnot.GetAllThings();
                        thisKnot.Modify();
                        thisKnot.UpdateBeads();
                    }
                    else
                    {
                        // 全体が短くてかつ交点の個数が0ならば、Beadを全部捨てる。
                        thisKnot.ClearAllBeads();
                    }
                    //モードを戻しておく
                    Display.SetDrawKnotMode();
                }
                else
                {// さもなくば、交点に当たるところをJointにする
                    for (int i = 0; i < meets.Count; i++)
                    {
                        int  b1  = meets[i].first;
                        int  b2  = meets[i].second;
                        Bead bd1 = thisKnot.AllBeads[b1];
                        Bead bd2 = thisKnot.AllBeads[b2];
                        bd1.Joint = true;
                        //Nbhdの繋ぎ替え
                        // これをどちらにどちらをつなぐかは、選ぶ必要がある。
                        float bd1x   = bd1.Position.x;
                        float bd1y   = bd1.Position.y;
                        float n1x    = bd1.N1.Position.x - bd1x;
                        float n1y    = bd1.N1.Position.y - bd1y;
                        float bd2n1x = bd2.N1.Position.x - bd1x;
                        float bd2n1y = bd2.N1.Position.y - bd1y;
                        float bd2n2x = bd2.N2.Position.x - bd1x;
                        float bd2n2y = bd2.N2.Position.y - bd1y;
                        if (n1x * bd2n1y - n1y * bd2n1x > 0 && n1x * bd2n2y - n1y * bd2n2x < 0)
                        {
                            bd1.U1 = bd2.N1;
                            bd1.U2 = bd2.N2;
                        }
                        else
                        {
                            bd1.U1 = bd2.N2;
                            bd1.U2 = bd2.N1;
                        }
                        thisKnot.AllBeads[b2 - 1].N1 = bd1;
                        thisKnot.AllBeads[b2 + 1].N2 = bd1;
                        //消去
                        bd2.Active = false;//
                    }
                    thisKnot.AllBeads = FindObjectsOfType <Bead>();
                    freeCurveSize     = thisKnot.AllBeads.Length;
                    // Joint-Jointとなるエッジには間にMidJointを必ず追加する。
                    for (int b1 = 0; b1 < freeCurveSize; b1++)
                    {
                        Bead bd = thisKnot.AllBeads[b1];
                        if (bd.Joint)
                        {
                            for (int r1 = 0; r1 < 4; r1++)
                            {
                                PairInt br2     = thisKnot.FindEndOfEdgeOnBead(bd, r1, true);
                                Bead    endBead = thisKnot.FindBeadByID(br2.first);
                                if (endBead != null && endBead.Joint)
                                {
                                    // ジョイント間のビーズ数を数える。
                                    int count = thisKnot.CountBeadsOnEdge(bd, r1);
                                    // midJointを作る
                                    Bead midJointBead = thisKnot.GetBeadOnEdge(bd, r1, Mathf.FloorToInt(count / 2));
                                    if (midJointBead != null)
                                    {
                                        midJointBead.MidJoint = true;
                                    }
                                    //Debug.Log(bd.ID + "," + r1 + "->" + br2.first + "," + br2.second + "(" + count + ")");
                                }
                            }
                        }
                    }

                    // BeadsからNodeEdgeを更新する
                    thisKnot.CreateNodesEdgesFromBeads();
                    // 形を整える
                    thisKnot.GetAllThings();
                    thisKnot.Modify();
                    thisKnot.UpdateBeads();

//                    thisKnot.AdjustEdgeLine();

                    //モードを戻す
                    Display.SetDrawKnotMode();
                }
            }
        }
        else if (Display.IsEditKnotMode())
        {
        }
        else if (Display.IsMenuMode())
        {
        }
    }
Пример #2
0
    void OutputData()
    {
        int nodeNumber = nodes.Count;

        thisKnot.ClearAll();
        for (int n = 0; n < nodeNumber; n++)
        {
            DNode nn = nodes[n];
            if (n % 5 == 0)
            {                                                                                             // ジョイント
                Node nd = thisKnot.AddNode(new Vector3((nn.x - 400f) * 0.01f, (nn.y - 400f) * 0.01f), n); // ID = n
                Bead bd = thisKnot.AddBead(new Vector3((nn.x - 400f) * 0.01f, (nn.y - 400f) * 0.01f), n); // ID = n
                if (nn.ou)
                {
                    nd.Theta = Mathf.Atan2(nodes[n + 1].y - nodes[n].y, nodes[n + 1].x - nodes[n].x);
                }
                else
                {
                    nd.Theta = Mathf.Atan2(nodes[n + 2].y - nodes[n].y, nodes[n + 1].x - nodes[n].x);
                }
                nd.R[0]      = nd.R[1] = nd.R[2] = nd.R[3] = 0.1f;
                nd.ID        = n;
                nd.Joint     = true;
                nd.MidJoint  = false;
                bd.NumOfNbhd = 4;            //あとで設定
                bd.N1        = bd.N2 = null; //あとで設定
                bd.U1        = bd.U2 = null; //あとで設定
                bd.ID        = n;
                bd.Joint     = true;
                bd.MidJoint  = false;
                nd.ThisBead  = bd;
            }
            else
            {                                                                                             //非ジョイント
                Bead bd = thisKnot.AddBead(new Vector3((nn.x - 400f) * 0.01f, (nn.y - 400f) * 0.01f), n); // ID = n
                bd.NumOfNbhd = 2;                                                                         //あとで設定
                bd.N1        = bd.N2 = null;                                                              //あとで設定
                bd.U1        = bd.U2 = null;                                                              //あとで設定
                bd.ID        = n;
                bd.Joint     = false;
                bd.MidJoint  = false;
            }
        }
        int BeadLastID = thisKnot.GetMaxIDOfBead();
        // edges
        int A = -1, AR = -1, B = -1, BR = -1;

        for (int e = 0; e < edges.Count; e++)
        {
            DEdge ee = edges[e];
            if (ee.visible)
            {
                A = AR = B = BR = -1;
                if (ee.s % 5 != 0 && ee.t % 5 != 0)
                {
                    for (int es = 0; es < edges.Count; es++)
                    {
                        DEdge ees = edges[es];
                        // ee.sからたどれるジョイントを見つける
                        if (ees.visible && ees.s % 5 == 0 && ees.t == ee.s)
                        {
                            int   s0          = ees.s;
                            float aX          = nodes[s0 + 2].x - nodes[s0 + 1].x;
                            float aY          = nodes[s0 + 2].y - nodes[s0 + 1].y;
                            float bX          = nodes[s0 + 4].x - nodes[s0 + 1].x;
                            float bY          = nodes[s0 + 4].y - nodes[s0 + 1].y;
                            float orientation = aX * bY - aY * bX;
                            int   t           = ees.t - ees.s;
                            if (orientation > 0)
                            {
                                if (nodes[ees.s].ou)
                                {
                                    t = (t + 7) % 4;
                                }
                                else
                                {
                                    t = (t + 6) % 4;
                                }
                            }
                            else
                            {
                                if (nodes[ees.s].ou)
                                {
                                    t = (5 - t) % 4;
                                }
                                else
                                {
                                    t = (6 - t) % 4;
                                }
                            }
                            A  = ees.s;// ee.sからたどれるジョイント
                            AR = t;
                        }
                        // ee.tからたどれるジョイント
                        if (ees.visible && ees.s % 5 == 0 && ees.t == ee.t)
                        {
                            int   s0          = ees.s;
                            float aX          = nodes[s0 + 2].x - nodes[s0 + 1].x;
                            float aY          = nodes[s0 + 2].y - nodes[s0 + 1].y;
                            float bX          = nodes[s0 + 4].x - nodes[s0 + 1].x;
                            float bY          = nodes[s0 + 4].y - nodes[s0 + 1].y;
                            float orientation = aX * bY - aY * bX;
                            int   t           = ees.t - ees.s;
                            if (orientation > 0)
                            {
                                if (nodes[ees.s].ou)
                                {
                                    t = (t + 7) % 4;
                                }
                                else
                                {
                                    t = (t + 6) % 4;
                                }
                            }
                            else
                            {
                                if (nodes[ees.s].ou)
                                {
                                    t = (5 - t) % 4;
                                }
                                else
                                {
                                    t = (6 - t) % 4;
                                }
                            }
                            B  = ees.s;// ee.tからたどれるジョイント
                            BR = t;
                        }
                    }                                                  ////
                    Edge ed       = thisKnot.AddEdge(A, B, AR, BR, e); // iD = e (連番に限らない。)
                    Bead bdJointA = thisKnot.GetBeadByID(A);
                    Bead bdAR     = thisKnot.GetBeadByID(ee.s);
                    Bead bdBR     = thisKnot.GetBeadByID(ee.t);
                    Bead bdJointB = thisKnot.GetBeadByID(B);
                    if (bdJointA == null || bdAR == null || bdBR == null || bdJointB == null)
                    {
                        continue;
                    }
                    bdJointA.SetNU12(AR, bdAR);
                    bdAR.N1 = bdJointA;
                    bdAR.N2 = bdBR;
                    bdBR.N1 = bdJointB;
                    bdBR.N2 = bdAR;
                    bdJointB.SetNU12(BR, bdBR);
                }
            }
        }
        thisKnot.GetAllThings();

        thisKnot.Modify();
        // NodeEdgeからBeadsを整える
        thisKnot.UpdateBeads();
        //グラフの形を整える。現状ではR[]を整えるだけ。
        thisKnot.Modify();
        Display.SetDrawKnotMode();// drawモードの変更
    }