/// <summary>
 /// A hopefully faster iterator over the vertices who does not need to create an object each time.
 /// </summary>
 protected bool FindPrevVertex(ref int controlPointIndex, out RectVertexControlPoint vertex)
 {
     bool result = false;
     LineControlPoint lcp = null;
     while (controlPointIndex > 0) {
         --controlPointIndex;
         lcp = GetControlPoint(controlPointIndex);
         if (lcp is RectVertexControlPoint) {
             result = true;
             break;
         }
     }
     vertex = (RectVertexControlPoint)lcp;
     return result;
 }
 /// <summary>
 /// We assume that a valid bending has been assigned to all vertices from the start point up to and
 /// including v2
 /// </summary>
 /// <param name="v1"></param>
 /// <param name="v2"></param>
 /// <param name="v3"></param>
 protected void AssignBending(RectVertexControlPoint v1, RectVertexControlPoint v2, RectVertexControlPoint v3)
 {
     // Rotate the points such that the connection from v2 to v3 is in the first quadrant
     int r = RotateVertices(v1, v2, v3);
     //
     switch (Geometry.CalcRelativeQuadrant(v1.GetPosition(), v2.GetPosition())) {
         case 1: // this is forbidden
             // Debug.Assert(false);
             // If it happens nevertheless...
             switch (v3.bending) {
                 case VertexBending.None:
                     if (v2.IsVertical) v3.bending = VertexBending.Right;
                     else v3.bending = VertexBending.Down;
                     break;
                 default:
                     // We leave it as it is.
                     break;
             }
             break;
         case 2: //
             Debug.Assert(v2.bending == VertexBending.DownU);
             // If v3 is the end point, it could already have a bending
             switch (v3.bending) {
                 case VertexBending.None:
                     v3.bending = VertexBending.Down;
                     break;
                 case VertexBending.Down:
                 case VertexBending.LeftU:
                     // That is alright.
                     break;
                 case VertexBending.UpU:
                 case VertexBending.Right:
                     // This causes a double knee, but ok.
                     break;
                 case VertexBending.Left:
                 case VertexBending.Up:
                     // Conflict, we just override the bending
                     v3.bending = VertexBending.Down;
                     break;
                 default:
                     Debug.Assert(false);
                     break;
             }
             break;
         case 3:
             // bending of v2 cannot be U
             switch (v3.bending) {
                 case VertexBending.None:
                     if (v2.IsVertical) v3.bending = VertexBending.Right;
                     else v3.bending = VertexBending.Down;
                     break;
                 case VertexBending.Right:
                 case VertexBending.Down:
                     // That is alright.
                     break;
                 case VertexBending.LeftU:
                     v2.bending = VertexBending.Right;
                     break;
                 case VertexBending.UpU:
                     v2.bending = VertexBending.Down;
                     break;
                 case VertexBending.Up:
                 case VertexBending.Left:
                     // Conflict, we just override the bending
                     if (v2.IsVertical) v3.bending = VertexBending.Right;
                     else v3.bending = VertexBending.Down;
                     break;
                 default:
                     Debug.Assert(false);
                     break;
             }
             break;
         case 4:
             Debug.Assert(v2.bending == VertexBending.RightU);
             switch (v3.bending) {
                 case VertexBending.None:
                     v3.bending = VertexBending.Right;
                     break;
                 case VertexBending.Right:
                 case VertexBending.Down:
                 case VertexBending.LeftU:
                 case VertexBending.UpU:
                     // That is ok
                     break;
                 case VertexBending.Left:
                 case VertexBending.Up:
                     // Conflict, we just override the bending
                     v3.bending = VertexBending.Right;
                     break;
                 default:
                     Debug.Assert(false);
                     break;
             }
             break;
         default:
             Debug.Assert(false);
             break;
     }
     UnrotateVertices(r, v1, v2, v3);
 }
 /// <summary>
 /// Assignes the bending.
 /// </summary>
 protected void AssignBending(RectVertexControlPoint currentVertex, RectVertexControlPoint nextVertex)
 {
     int r = RotateVertices(null, currentVertex, nextVertex);
     switch (nextVertex.bending) {
         case VertexBending.None:
             if (currentVertex.IsVertical) nextVertex.bending = VertexBending.Right;
             else nextVertex.bending = VertexBending.Down;
             break;
         default:
             // We currently assume that this function is only called for unassigned bendings in nextVertex.
             Debug.Assert(false);
             break;
     }
     UnrotateVertices(r, null, currentVertex, nextVertex);
 }
 /// <summary>
 /// Rotates the vertices counterclockwise for the number of count quarter rotations.
 /// </summary>
 protected void UnrotateVertices(int count, RectVertexControlPoint v1, RectVertexControlPoint v2, RectVertexControlPoint v3)
 {
     // We rotate 4-count times clockwise
     for (int i = 0; i < (4 - count) % 4; ++i) {
         if (v1 != null) RotateVertex(v1, v2, 1);
         RotateVertex(v3, v2, 1);
         v2.bending = RotateBending(v2.bending, 1);
     }
 }
 /// <summary>
 /// Rotates the vertics around v2 until v3 is in the first quadrant.
 /// </summary>
 /// <returns>Returns the number of clockwise rotations by 90 degree necessary.</returns>
 /// <remarks>Note that our coordinate system is mirrored:
 /// III | IV
 /// ----|----
 ///  II | I
 /// </remarks>
 protected int RotateVertices(RectVertexControlPoint v1, RectVertexControlPoint v2, RectVertexControlPoint v3)
 {
     int result = 0;
     while (Geometry.CalcRelativeQuadrant(v3.GetPosition(), v2.GetPosition()) != 1) {
         RotateVertex(v3, v2, 1);
         if (v1 != null) RotateVertex(v1, v2, 1);
         v2.bending = RotateBending(v2.bending, 1);
         ++result;
     }
     return result;
 }
 /// <summary>
 /// Rotates the v1 around origin by 90 degree clockwise.
 /// </summary>
 protected void RotateVertex(RectVertexControlPoint v, RectVertexControlPoint origin, int count)
 {
     Point p = v.GetPosition();
     Point o = origin.GetPosition();
     for (int i = 0; i < count; ++i) {
         int x = p.X;
         p.X = o.X - (p.Y - o.Y);
         p.Y = o.Y + (x - o.X);
         v.bending = RotateBending(v.bending, 1);
     }
     v.SetPosition(p);
 }