//public static void GetHMoveAlongTwoPoints(float x1, float y1, float x2, float y2, float d, out float X, out float Y)
 public static HypPoint GetHMoveAlongTwoPoints(HypPoint P1, HypPoint P2, float d)
 {
     if (!P1.InWorld() || !P2.InWorld())
     {
         return(P1);
     }
     if (P1 != HypPoint.Zero())
     {
         //X1をOへ移す直線L1
         HypLine L1 = GetHBisectorOfTwoPoints(P1, HypPoint.Zero());
         //点X2をL1で線対称移動
         HypPoint XY2 = GetInversionAlongHLine(L1, P2);
         if (XY2.Z == 0f)
         {
             P1.Println("---P1");
             P2.Println("---P2");
             L1.Println("---L1");
             XY2.Println("--XY2");
         }
         float magXY2 = Mathf.Sqrt(XY2.GetX() * XY2.GetX() + XY2.GetY() * XY2.GetY());
         float ed     = H2EFromOrigin(d);
         //原点からX2へ向かう線分で、双曲長がdであるような点
         XY2.X *= ed;
         XY2.Y *= ed;
         XY2.Z *= magXY2;
         //点X2をL1で線対称移動
         HypPoint P3 = GetInversionAlongHLine(L1, XY2);
         if (P3.InWorld())
         {
             return(P3);
         }
         else
         {
             Debug.Log("error occurs at GetHMoveAlongTwoPoints");
             P1.Println("P1");
             P2.Println("P2");
             Debug.Log("magXY2=" + magXY2);
             Debug.Log("ed=" + ed);
             XY2.Println("XY2");
             P3.Println("P3");
             return(P1);
         }
     }
     else
     {
         HypPoint XY2    = P2;
         float    magXY2 = Mathf.Sqrt(XY2.GetX() * XY2.GetX() + XY2.GetY() * XY2.GetY());
         float    ed     = H2EFromOrigin(d);
         //原点からX2へ向かう線分で、双曲長がdであるような点
         XY2.X *= ed;
         XY2.Y *= ed;
         XY2.Z *= magXY2;
         HypPoint P3 = XY2;
         return(P3);
     }
 }
    /// <summary>
    /// P1 = crossing point if exists.
    /// returns between -PI to PI
    /// </summary>
    public static float GetAngleOfTwoLines(HypPoint P11, HypPoint P12, HypPoint P21, HypPoint P22, HypPoint C)
    {
        HypLine  L1        = GetHBisectorOfTwoPoints(C, HypPoint.Zero());
        HypPoint Q11       = GetInversionAlongHLine(L1, P11);
        HypPoint Q12       = GetInversionAlongHLine(L1, P12);
        HypPoint Q21       = GetInversionAlongHLine(L1, P21);
        HypPoint Q22       = GetInversionAlongHLine(L1, P22);
        float    V1x       = Q12.GetX() - Q11.GetX();
        float    V1y       = Q12.GetY() - Q11.GetY();
        float    V2x       = Q22.GetX() - Q21.GetX();
        float    V2y       = Q22.GetY() - Q21.GetY();
        float    InnerProd = V1x * V2x + V1y * V2y;
        float    NormV1    = Mathf.Sqrt(V1x * V1x + V1y * V1y);
        float    NormV2    = Mathf.Sqrt(V2x * V2x + V2y * V2y);
        float    Area      = V1x * V2y - V1y * V2x;
        float    Theta     = Mathf.Acos(InnerProd / NormV1 / NormV2);

        if (Area < 0)
        {
            Theta *= -1;
        }
        return(Theta);
    }
 public static HypPoint GetRotationOfPoint(HypPoint C, float theta, HypPoint P1)
 {
     if (C.GetX() != 0f || C.GetY() != 0f)
     {
         HypLine  L1 = GetHBisectorOfTwoPoints(C, HypPoint.Zero());
         HypPoint P2 = GetInversionAlongHLine(L1, P1);
         HypPoint P3 = new HypPoint(
             Mathf.Cos(theta) * P2.X - Mathf.Sin(theta) * P2.Y,
             Mathf.Sin(theta) * P2.X + Mathf.Cos(theta) * P2.Y,
             P2.Z
             );
         return(GetInversionAlongHLine(L1, P3));
     }
     else
     {
         HypPoint P3 = new HypPoint(
             Mathf.Cos(theta) * P1.X - Mathf.Sin(theta) * P1.Y,
             Mathf.Sin(theta) * P1.X + Mathf.Cos(theta) * P1.Y,
             P1.Z
             );
         return(P3);
     }
 }