////old
    //public static void GetHLineThruTwoPoints(float x1, float y1, float x2, float y2, out float X, out float Y, out float R)
    ////old
    //{
    //    GetInversionImage(x1, y1, out float u1, out float v1);
    //    GetBisectorLine(x1, y1, u1, v1, out float a, out float b, out float p);
    //    GetInversionImage(x2, y2, out float u2, out float v2);
    //    GetBisectorLine(x2, y2, u2, v2, out float c, out float d, out float q);
    //    GetCrossingPointOfTwoLines(a, b, c, d, p, q, out float X0, out float Y0);
    //    X = X0;
    //    Y = Y0;
    //    R = Mathf.Sqrt(X * X + Y * Y - 1);
    //}

    public static HypLine GetHBisectorOfTwoPoints2(HypPoint P1, HypPoint P2)
    {
        HypLine ret = new HypLine();

        if (P1 != P2)
        {
            if (P1.X == 0f && P1.Y == 0f)
            {
                float    x2 = P2.X;
                float    y2 = P2.Y;
                float    z2 = P2.Z;
                HypPoint P  = new HypPoint(x2 * z2, y2 * z2, x2 * x2 + y2 * y2);
                ret = GetHLineFromCenter(P);
            }
            else if (P2.X == 0f && P2.Y == 0f)
            {
                float    x1 = P1.X;
                float    y1 = P1.Y;
                float    z1 = P1.Z;
                HypPoint P  = new HypPoint(x1 * z1, y1 * z1, x1 * x1 + y1 * y1);
                ret = GetHLineFromCenter(P);
            }
            else
            {
                EucLine  L  = GetLineByTwoPoints(P1, P2);
                HypLine  L1 = GetHLineThruTwoPoints(P1, P2);
                EucLine  L2 = new EucLine(L1.X, L1.Y, 1f);
                HypPoint P  = GetCrossingPointOfTwoLines(L, L2);
                ret = GetHLineFromCenter(P);
            }
        }
        return(ret);
    }
 public HypLine(HypLine L)
 {
     X = L.X;
     Y = L.Y;
     Z = L.Z;
     R = L.R;
 }
    public static HypPoint GetMidPointOfTwoPoint(HypPoint P1, HypPoint P2)
    {
        HypLine L1 = GetHLineThruTwoPoints(P1, P2);
        HypLine L2 = GetHBisectorOfTwoPoints(P1, P2);

        return(GetCrossingPointOfTwoHLines(L1, L2));
    }
    /// <summary>
    /// 特定の点を特定の点へ移す双曲変換
    /// </summary>
    /// <param name="start"></param>
    /// <param name="end"></param>
    /// <param name="P"></param>
    /// <returns></returns>
    public static HypPoint ParallelTransform(Vector2 start, Vector2 end, HypPoint P)
    {
        if ((start - end).magnitude < 0.01f)
        {
            return(P);
        }
        HypPoint Pstart = new HypPoint(start);
        HypPoint Pend   = new HypPoint(end);
        HypLine  L1     = GetHLineThruTwoPoints(Pstart, Pend);
        HypLine  L2     = GetHBisectorOfTwoPoints(Pstart, Pend);
        HypLine  L3     = GetHPerpendicularThruAPoint(L1, Pend);
        HypPoint P1     = GetInversionAlongHLine(L2, P);
        HypPoint P2     = GetInversionAlongHLine(L3, P);

        //if (!P2.InWorld())
        //{
        //    L1.Println("L1");
        //    L2.Println("L2");
        //    L3.Println("L3");
        //    P1.Println("P1");
        //    P2.Println("P2");
        //    return P;
        //}
        return(P2);
    }
    /// <summary>
    /// 中心点から双曲直線を得る
    /// </summary>
    /// <param name="P"></param>
    /// <returns></returns>
    public static HypLine GetHLineFromCenter(HypPoint P)
    {
        HypLine ret = new HypLine();

        if (P.Z != 0f)
        {
            //float radius2 = P.X * P.X / P.Z / P.Z + P.Y * P.Y / P.Z / P.Z - 1f;
            float radius2 = P.GetX() * P.GetX() + P.GetY() * P.GetY() - 1f;
            if (radius2 > 0f)
            {
                ret.X = P.GetX();
                ret.Y = P.GetY();
                ret.Z = 1f;
                ret.R = Mathf.Sqrt(radius2);
            }
            else
            {
                ret.X = P.X;
                ret.Y = P.Y;
                ret.Z = 0f;
                ret.R = Mathf.Infinity;
            }
        }
        else
        {
            ret.X = P.X;
            ret.Y = P.Y;
            ret.Z = 0f;
            ret.R = Mathf.Infinity;
        }
        return(ret);
    }
Example #6
0
    void ModuleUpdatePerpendicular()
    {
        HLine    HLN1 = VA.GetComponent <HLine>(); //対象となる直線1
        HLine    HLN2 = VB.GetComponent <HLine>(); //対象となる直線2
        HypLine  HL1  = HLN1.HL;
        HypLine  HL2  = HLN2.HL;
        Vertex   V11  = HLN1.VA.GetComponent <Vertex>();
        Vertex   V12  = HLN1.VB.GetComponent <Vertex>();
        Vertex   V21  = HLN2.VA.GetComponent <Vertex>();
        Vertex   V22  = HLN2.VB.GetComponent <Vertex>();
        HypPoint P11  = new HypPoint(V11.XY);
        HypPoint P12  = new HypPoint(V12.XY);
        HypPoint P21  = new HypPoint(V21.XY);
        HypPoint P22  = new HypPoint(V22.XY);

        HypPoint C = HTransform.GetCrossingPointOfTwoHLines2(HL1, HL2);

        if (C != new HypPoint(1f, 1f, 0f))
        {
            //float angle = HTransform.GetAngleOfTwoLines(HL1, HL2, C);
            float angle = HTransform.GetAngleOfTwoLines(P11, P12, P21, P22, C);
            //Debug.Log("angle="+angle);
            float error = (Mathf.PI / 2f - angle) * 0.25f;
            if (angle < 0f)
            {
                error = (-Mathf.PI / 2f - angle) * 0.25f;
            }
            HypPoint P1m  = HTransform.GetMidPointOfTwoPoint(P11, P12);
            HypPoint P11T = HTransform.GetRotationOfPoint(P1m, -error, P11);
            HypPoint P12T = HTransform.GetRotationOfPoint(P1m, -error, P12);
            //HypLine L1T = HTransform.GetHLineThruTwoPoints(P11T, P12T);
            HypPoint P2m  = HTransform.GetMidPointOfTwoPoint(P21, P22);
            HypPoint P21T = HTransform.GetRotationOfPoint(P2m, error, P21);
            HypPoint P22T = HTransform.GetRotationOfPoint(P2m, error, P22);
            //HypLine L2T = HTransform.GetHLineThruTwoPoints(P21T, P22T);
            if (!V11.Fixed && P11T.InWorld())
            {
                V11.XY.x = P11T.GetX();
                V11.XY.y = P11T.GetY();
            }
            if (!V12.Fixed && P12T.InWorld())
            {
                V12.XY.x = P12T.GetX();
                V12.XY.y = P12T.GetY();
            }
            if (!V21.Fixed && P21T.InWorld())
            {
                V21.XY.x = P21T.GetX();
                V21.XY.y = P21T.GetY();
            }
            if (!V22.Fixed && P22T.InWorld())
            {
                V22.XY.x = P22T.GetX();
                V22.XY.y = P22T.GetY();
            }
        }
    }
 //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);
     }
 }
Example #8
0
    //string MyDebug_Backup="";
    void ModuleUpdatePointToLine2()
    {
        Vertex VTX = VA.GetComponent <Vertex>(); //対象となる点
        HLine  HLN = VB.GetComponent <HLine>();  //対象となる直線

        if (VTX != null && HLN != null)
        {
            HypLine  L1    = HLN.HL;
            HypPoint P1    = new HypPoint(VTX.XY);
            HypLine  L2    = HTransform.GetHPerpendicularThruAPoint(L1, P1);
            HypPoint P2    = HTransform.GetCrossingPointOfTwoHLines(L1, L2);
            float    error = HTransform.GetHDistanceOfTwoPoints(P1, P2) * 0.2f;
            //Debug.Log(error);
            if (0.001f < error || error < -0.001f)
            {
                //string MyDebug = "";
                HypPoint P3 = HTransform.GetHMoveAlongTwoPoints(P2, P1, error);
                HypPoint P4 = HTransform.GetHMoveAlongTwoPoints(P1, P2, error);
                ////点を直線に寄せる
                if (!VTX.Fixed && P4.InWorld())
                {
                    //MyDebug += "P4:" + P4.GetX() + "," + P4.GetY();
                    VTX.XY.x = P4.GetX();
                    VTX.XY.y = P4.GetY();
                }
                //直線を円に寄せる
                Vertex   L1V1   = HLN.VA.GetComponent <Vertex>(); //動かすべき点1
                Vertex   L1V2   = HLN.VB.GetComponent <Vertex>(); //動かすべき点2
                HypPoint PL1    = new HypPoint(L1V1.XY);
                HypPoint PL2    = new HypPoint(L1V2.XY);
                HypPoint NewPL1 = HTransform.ParallelTransform(P2, P3, PL1);
                HypPoint NewPL2 = HTransform.ParallelTransform(P2, P3, PL2);
                //NewPL1.println("NewPL1");
                if (!L1V1.Fixed && NewPL1.InWorld())
                {
                    //MyDebug += "L1:" + NewPL1.GetX() + "," + NewPL1.GetY();
                    L1V1.XY.x = NewPL1.GetX();
                    L1V1.XY.y = NewPL1.GetY();
                }
                if (!L1V2.Fixed && NewPL2.InWorld())
                {
                    //MyDebug += "L2:" + NewPL2.GetX() + "," + NewPL2.GetY();
                    L1V2.XY.x = NewPL2.GetX();
                    L1V2.XY.y = NewPL2.GetY();
                }
                HLN.GetHLineFromTwoVertices();
                //if (MyDebug != MyDebug_Backup)
                //{
                //    Debug.Log(MyDebug);
                //    MyDebug_Backup = MyDebug;
                //}
            }
        }
    }
Example #9
0
 public HypLine GetHL()
 {
     if (HL == null)
     {
         HL = new HypLine();
     }
     if (VA != null && VB != null)
     {
         GetHLineFromTwoVertices();
     }
     return(HL);
 }
    public static HypPoint ParallelTransform(HypPoint Pstart, HypPoint Pend, HypPoint P)
    {
        if (!Pstart.InWorld() || !Pend.InWorld() || !P.InWorld())
        {
            Debug.Log("error occurs at ParallelTransform: A");
            Debug.Log("Pstart:" + Pstart.GetX() + "," + Pstart.GetY() + "(" + Pstart.X + ":" + Pstart.Y + ":" + Pstart.Z + ")");
            Debug.Log("Pend:" + Pend.GetX() + "," + Pend.GetY() + "(" + Pend.X + ":" + Pend.Y + ":" + Pend.Z + ")");
            Debug.Log("error occurs at ParallelTransform ここまで");
            return(P);
        }
        if (GetEDistanceOfTwoPoints(Pstart, Pend) < 0.001f)
        {
            //Debug.Log("error occurs at ParallelTransform: B");
            //Debug.Log("Pstart:" + Pstart.GetX() + "," + Pstart.GetY() + "(" + Pstart.X + ":" + Pstart.Y + ":" + Pstart.Z + ")");
            //Debug.Log("Pend:" + Pend.GetX() + "," + Pend.GetY() + "(" + Pend.X + ":" + Pend.Y + ":" + Pend.Z + ")");
            //Debug.Log("error occurs at ParallelTransform ここまで");
            return(P);
        }
        HypLine L1 = GetHLineThruTwoPoints(Pstart, Pend);
        HypLine L2 = GetHBisectorOfTwoPoints(Pstart, Pend);
        //L2.Println("---L2");
        HypLine L3 = GetHPerpendicularThruAPoint(L1, Pend);
        //L3.Println("---L3");
        HypPoint P1 = GetInversionAlongHLine(L2, P);
        HypPoint P2 = GetInversionAlongHLine(L3, P1);

        if (P2.InWorld())
        {
            return(P2);
        }
        else
        {
            Debug.Log("error occurs at ParallelTransform: C");
            Debug.Log("Pstart:" + Pstart.GetX() + "," + Pstart.GetY() + "(" + Pstart.X + ":" + Pstart.Y + ":" + Pstart.Z + ")");
            Debug.Log("Pend:" + Pend.GetX() + "," + Pend.GetY() + "(" + Pend.X + ":" + Pend.Y + ":" + Pend.Z + ")");
            Debug.Log("L1:" + L1.GetX() + "," + L1.GetY() + "," + L1.R + "(" + L1.X + ":" + L1.Y + ":" + L1.Z + ")");
            Debug.Log("L2:" + L2.GetX() + "," + L2.GetY() + "," + L2.R + "(" + L2.X + ":" + L2.Y + ":" + L2.Z + ")");
            Debug.Log("L3:" + L3.GetX() + "," + L3.GetY() + "," + L3.R + "(" + L3.X + ":" + L3.Y + ":" + L3.Z + ")");
            Debug.Log("P1:" + P1.GetX() + "," + P1.GetY() + "(" + P1.X + ":" + P1.Y + ":" + P1.Z + ")");
            Debug.Log("P2:" + P2.GetX() + "," + P2.GetY() + "(" + P2.X + ":" + P2.Y + ":" + P2.Z + ")");
            P1 = GetInversionAlongHLine(L2, P);
            P2 = GetInversionAlongHLine(L3, P1);
            Debug.Log("P2:" + P2.GetX() + "," + P2.GetY() + "(" + P2.X + ":" + P2.Y + ":" + P2.Z + ")");
            if (P2.InWorld())
            {
                return(P2);
            }
            Debug.Log("error occurs at ParallelTransform ここまで");
            return(P);
        }
    }
Example #11
0
    void ModuleUpdateTangentCircleToLine()
    {
        HCircle hcircle = VA.GetComponent <HCircle>(); //対象となる円
        HLine   hline   = VB.GetComponent <HLine>();   //対象となる直線

        if (hcircle != null && hline != null)
        {
            HypCircle C1 = hcircle.GetHCR();
            HypLine   L1 = hline.GetHL();
            HypPoint  P1 = new HypPoint(hcircle.VA.GetComponent <Vertex>().XY);
            HypLine   L2 = HTransform.GetHPerpendicularThruAPoint(L1, P1);
            HypPoint  P2 = HTransform.GetCrossingPointOfTwoHLines(L1, L2);
            //P2.println("P2");
            float error = (HTransform.GetHDistanceOfTwoPoints(P1, P2) - C1.HR) * 0.1f;
            //Debug.Log(error);
            if (0.001f < error || error < -0.001f)
            {
                HypPoint P3 = HTransform.GetHMoveAlongTwoPoints(P2, P1, error);
                HypPoint P4 = HTransform.GetHMoveAlongTwoPoints(P1, P2, error);
                //円の半径を変える
                C1.HR += error;
                ////円を直線に寄せる
                Vertex C1V = hcircle.VA.GetComponent <Vertex>();
                if (!C1V.Fixed && P4.InWorld())
                {
                    C1V.XY.x = P4.GetX();
                    C1V.XY.y = P4.GetY();
                }
                //直線を円に寄せる
                Vertex   L1V1   = hline.VA.GetComponent <Vertex>(); //動かすべき点1
                Vertex   L1V2   = hline.VB.GetComponent <Vertex>(); //動かすべき点2
                HypPoint PL1    = new HypPoint(L1V1.XY);
                HypPoint PL2    = new HypPoint(L1V2.XY);
                HypPoint NewPL1 = HTransform.ParallelTransform(P2, P3, PL1);
                HypPoint NewPL2 = HTransform.ParallelTransform(P2, P3, PL2);
                //NewPL1.println("NewPL1");
                if (!L1V1.Fixed && NewPL1.InWorld())
                {
                    L1V1.XY.x = NewPL1.GetX();
                    L1V1.XY.y = NewPL1.GetY();
                }
                if (!L1V2.Fixed && NewPL2.InWorld())
                {
                    L1V2.XY.x = NewPL2.GetX();
                    L1V2.XY.y = NewPL2.GetY();
                }
                hline.GetHLineFromTwoVertices();
            }
        }
    }
Example #12
0
 // Start is called before the first frame update
 void Start()
 {
     LR = GetComponent <LineRenderer>();
     LR.positionCount = PosLength;
     HL   = new HypLine();
     Pos  = new Vector3[PosLength];
     ks   = new Keyframe[PosLength];
     anim = new AnimationCurve(ks);
     for (int i = 0; i < PosLength; i++)
     {
         Pos[i] = new Vector3(0f, 0f, -1f);                     //線の位置を決めるためのベクトルの列
         ks[i]  = new Keyframe(1f * i / (PosLength - 1), .05f); //線の太さのためのキーフレーム
     }
     LineRendererSetPosition();
     Clipped = false;
 }
    public static HypPoint GetCrossingPointOfTwoHLines2(HypLine L1, HypLine L2)
    {
        // Center (L1.X : L1.Y : L1.Z ) Radius L1.R
        // RadicalLine
        float a = -L1.X * L2.Z + L1.Z * L2.X;
        float b = -L1.Y * L2.Z + L1.Z * L2.Y;

        //Debug.Log(a + "," + b);
        if (a == 0f && b == 0f)
        {
            return(new HypPoint(0f, 0f));
        }
        float X, Y, Z;

        if (L1.Z != 0f)
        {
            X = L1.X;
            Y = L1.Y;
            Z = L1.Z;
        }
        else
        {
            X = L2.X;
            Y = L2.Y;
            Z = L2.Z;
        }
        float d = (b * X - a * Y) * (b * X - a * Y) - (a * a + b * b) * Z * Z;

        if (d <= 0f)
        {
            return(new HypPoint(1f, 1f, 0f));;
        }
        float x1 = b * (b * X - a * Y + Mathf.Sqrt(d)) / (a * a + b * b) / Z;
        float x2 = b * (b * X - a * Y - Mathf.Sqrt(d)) / (a * a + b * b) / Z;
        float y1 = -a * (b * X - a * Y + Mathf.Sqrt(d)) / (a * a + b * b) / Z;
        float y2 = -a * (b * X - a * Y - Mathf.Sqrt(d)) / (a * a + b * b) / Z;

        if (x1 * x1 + y1 * y1 < 1f)
        {
            return(new HypPoint(x1, y1));
        }
        else
        {
            return(new HypPoint(x2, y2));
        }
    }
    /// <summary>
    /// 二つの双曲直線の交点を求める。
    /// </summary>
    /// <param name="L1"></param>
    /// <param name="L2"></param>
    /// <returns></returns>
    public static HypPoint GetCrossingPointOfTwoHLines(HypLine L1, HypLine L2)
    {
        bool  debug = false;
        float X1 = L1.X, Y1 = L1.Y, Z1 = L1.Z;
        float X2 = L2.X, Y2 = L2.Y, Z2 = L2.Z;
        float WX = Y1 * Z2 - Y2 * Z1, WY = X1 * Z2 - X2 * Z1, WZ = X1 * Y2 - X2 * Y1;
        float s1 = -WZ - Mathf.Sqrt(WZ * WZ - WX * WX - WY * WY);
        float s2 = -WZ + Mathf.Sqrt(WZ * WZ - WX * WX - WY * WY);

        if (debug)
        {
            Debug.Log(X1 + "," + Y1 + "," + Z1 + "," + X2 + "," + Y2 + "," + Z2);
            Debug.Log(WX + "," + WY + "," + WZ);
            Debug.Log("s=" + s1 + "," + s2);
        }
        float s = 0;

        if (Mathf.Abs(s1) < Mathf.Abs(s2))
        {
            s = s2;
        }
        else
        {
            s = s1;
        }
        if (Z1 != 0f || Z2 != 0f)
        {
            return(new HypPoint
            {
                X = WX,
                Y = -WY,
                Z = s
            });
        }
        else
        {
            return(new HypPoint
            {
                X = 0,
                Y = 0,
                Z = -2 * WZ
            });
        }
    }
Example #15
0
    public void GetHLineFromTwoVertices()
    {
        Vertex   PVA = VA.GetComponent <Vertex>();
        HypPoint P1  = new HypPoint(PVA.XY);
        Vertex   PVB = VB.GetComponent <Vertex>();
        HypPoint P2  = new HypPoint(PVB.XY);

        HL = HTransform.GetHLineThruTwoPoints(P1, P2);
        if (Clipped)
        {
            DrawClippedLine();
        }
        else
        {
            DrawAllLine();
        }
        LineRendererSetPosition();
        //print(HTransform.GetHDistanceOfTwoPoints(x1,y1,x2,y2));
    }
    public static HypLine GetHBisectorOfTwoPoints(HypPoint P1, HypPoint P2)
    {
        HypLine ret = new HypLine
        {
            X = 1f,
            Y = 1f,
            Z = 0f,
            R = 0f
        };

        if (P1 != P2)
        {
            EucLine   L     = GetLineByTwoPoints(P1, P2);
            HypPoint  P3    = new HypPoint(L.a, L.b, Mathf.Sqrt(L.a * L.a + L.b * L.b));
            EucLine   L12   = GetBisectorLine(P1, P2);
            EucLine   L23   = GetBisectorLine(P2, P3);
            HypPoint  P123  = GetCrossingPointOfTwoLines(L12, L23);
            float     C123R = GetEDistanceOfTwoPoints(P123, P1);
            HypCircle C1    = new HypCircle
            {
                EX = P123.GetX(),
                EY = P123.GetY(),
                ER = C123R
            };// P1,P2,P3を通る円。
            EucLine L2 = new EucLine
            {
                a = -2 * C1.EX,
                b = -2 * C1.EY,
                p = C1.ER * C1.ER - C1.EX * C1.EX - C1.EY * C1.EY - 1f
            };                                              //単位円とC1の共通弦(接するならば共通接線)
            HypPoint P = GetCrossingPointOfTwoLines(L, L2); //L1とL2の交点(無限遠点もありうる)
            ret = GetHLineFromCenter(P);                    //Pを中心とする双曲直線
        }
        else
        {
            Debug.Log("GetHBisectorOfTwoPoints error: P1==P2");
            P1.Println("P1");
            P2.Println("P2");
        }
        return(ret);
    }
 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);
     }
 }
    /// <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 void GetIdealPointsFromTwoPoints(HypPoint P1, HypPoint P2, out HypPoint Out1, out HypPoint Out2)
    {
        HypLine L = GetHLineThruTwoPoints(P1, P2);

        //L.Println("L");
        if (L.R > 300f || L.Z == 0f)
        {
            float X1  = -L.Y;
            float Y1  = L.X;
            float mag = Mathf.Sqrt(X1 * X1 + Y1 * Y1);
            Out1 = new HypPoint(X1, Y1, mag);
            Out2 = new HypPoint(-X1, -Y1, mag);
        }
        else
        {
            float midT = Mathf.Atan2(L.Y, L.X);
            float widT = Mathf.Asin(1f / Mathf.Sqrt(L.GetX() * L.GetX() + L.GetY() * L.GetY()));
            float t1   = midT - widT;
            Out1 = new HypPoint(L.GetX() - L.R * Mathf.Cos(t1), L.GetY() - L.R * Mathf.Sin(t1));
            float t2 = midT + widT;
            Out2 = new HypPoint(L.GetX() - L.R * Mathf.Cos(t2), L.GetY() - L.R * Mathf.Sin(t2));
        }
    }
    /// <summary>
    /// P1 = crossing point if exists.
    /// returns between 0 to PI/2
    /// </summary>
    /// <param name="L1"></param>
    /// <param name="L2"></param>
    /// <param name="P1"></param>
    /// <returns></returns>
    public static float GetAngleOfTwoLines(HypLine L1, HypLine L2, HypPoint P1)
    { // P1 = crossing point if exists
        if (L1.Z != 0f && L2.Z != 0f)
        {
            float u1 = L1.GetX() - P1.GetX();
            float v1 = L1.GetY() - P1.GetY();
            float u2 = L2.GetX() - P1.GetX();
            float v2 = L2.GetY() - P1.GetY();
            return(Mathf.Acos(Mathf.Abs(u1 * u2 + v1 * v2) / Mathf.Sqrt((u1 * u1 + v1 * v1) * (u2 * u2 + v2 * v2))));
        }
        else if (L1.Z == 0f && L2.Z != 0f)
        {
            float u1 = L2.GetX() - P1.GetX();
            float v1 = L2.GetY() - P1.GetY();
            float u2 = L1.X;
            float v2 = L1.Y;
            return(Mathf.Acos(Mathf.Abs(u1 * u2 + v1 * v2) / Mathf.Sqrt((u1 * u1 + v1 * v1) * (u2 * u2 + v2 * v2))));
        }
        else if (L1.Z != 0f && L2.Z == 0f)
        {
            float u1 = L1.GetX() - P1.GetX();
            float v1 = L1.GetY() - P1.GetY();
            float u2 = L2.X;
            float v2 = L2.Y;
            return(Mathf.Acos(Mathf.Abs(u1 * u2 + v1 * v2) / Mathf.Sqrt((u1 * u1 + v1 * v1) * (u2 * u2 + v2 * v2))));
        }
        else if (L1.Z == 0f && L2.Z == 0f)
        {
            float u1 = L1.X;
            float v1 = L1.Y;
            float u2 = L2.X;
            float v2 = L2.Y;
            return(Mathf.Acos(Mathf.Abs(u1 * u2 + v1 * v2) / Mathf.Sqrt((u1 * u1 + v1 * v1) * (u2 * u2 + v2 * v2))));
        }

        return(0f);
    }
 public static HypPoint GetInversionAlongHLine(HypLine L, HypPoint P)
 {
     if (P.Z == 0f)
     {
         return(new HypPoint(L.X, L.Y, L.Z));
     }
     if (L.Z != 0f && L.R != Mathf.Infinity)
     {
         float X3 = P.X * L.Z - L.X * P.Z;
         float Y3 = P.Y * L.Z - L.Y * P.Z;
         float Z3 = P.Z * L.Z;
         //Debug.Log("XYZ3=" + X3 / Z3 + "," + Y3 / Z3);
         float X4 = X3 * Z3 * L.R * L.R;
         float Y4 = Y3 * Z3 * L.R * L.R;
         float Z4 = X3 * X3 + Y3 * Y3;
         //Debug.Log("P4x=" + X4 / Z4 + "," + Y4 / Z4);
         return(new HypPoint(
                    X4 * L.Z + L.X * Z4,
                    Y4 * L.Z + L.Y * Z4,
                    L.Z * Z4));
     }
     else
     {
         float a  = L.X;
         float b  = L.Y;      //L: aX+by=0;
         float ab = Mathf.Sqrt(a * a + b * b);
         a /= ab;
         b /= ab; // Normalize
         float x    = P.GetX();
         float y    = P.GetY();
         float dist = a * x + b * y;
         return(new HypPoint(
                    x - 2 * dist * a,
                    y - 2 * dist * b
                    ));
     }
 }
    ////old
    //public static void GetHBisectorOfTwoPoints(float x1, float y1, float x2, float y2, out float X, out float Y, out float R)
    ////old
    //{
    //    if (x1 == 0f && y1 == 0f)
    //    {
    //        X = x2 / (x2 * x2 + y2 * y2);
    //        Y = y2 / (x2 * x2 + y2 * y2);
    //        R = Mathf.Sqrt(X * X + Y * Y - 1f);
    //    }
    //    else if (x2 == 0f && y2 == 0f)
    //    {
    //        X = x1 / (x1 * x1 + y1 * y1);
    //        Y = y1 / (x1 * x1 + y1 * y1);
    //        R = Mathf.Sqrt(X * X + Y * Y - 1f);
    //    }
    //    else
    //    {
    //        GetLineByTwoPoints(x1, y1, x2, y2, out float A1, out float B1, out float C1);
    //        GetHLineThruTwoPoints(x1, y1, x2, y2, out float X1, out float Y1, out float R1);
    //        float A2 = X1, B2 = Y1, C2 = 1;
    //        GetCrossingPointOfTwoLines(A1, B1, A2, B2, C1, C2, out X, out Y);
    //        R = Mathf.Sqrt(X * X + Y * Y - 1);
    //    }
    //}

    public static HypLine GetHPerpendicularThruAPoint(HypLine L, HypPoint P)
    {
        //L.Println("------L");
        HypPoint P2 = GetInversionImage(P);

        if (P2.Z != 0f)
        {
            EucLine  L1 = new EucLine(L.X, L.Y, L.Z);
            EucLine  L2 = GetBisectorLine(P, P2);
            HypPoint P3 = GetCrossingPointOfTwoLines(L1, L2);
            return(GetHLineFromCenter(P3));
        }
        else
        {
            HypLine HL1 = new HypLine
            {
                X = L.Y,
                Y = -L.X,
                Z = 0f,
                R = 0f
            };
            return(HL1);
        }
    }
Example #23
0
    void ModuleUpdatePointToLine()
    {
        Vector2 vtx   = VA.GetComponent <Vertex>().XY; //対象となる点
        HLine   hline = VB.GetComponent <HLine>();     //対象となる直線

        if (vtx != null && hline != null)
        {
            HypLine ln        = hline.HL;                          //直線の円データ
            Vector2 hlnCenter = new Vector2(ln.GetX(), ln.GetY()); //直線の円データの中心座標
            Vector2 direction = vtx - hlnCenter;                   //円の中心から対象となる点の方向
            float   dist      = direction.magnitude - ln.R;        //誤差
            if (Mathf.Abs(dist) > 0.001f)
            {
                direction.Normalize();
                //Vector2 newVtx = hlnCenter + (ln.R + 0.75f * dist) * direction;//新しい点の座標
                Vector2  newVtx = vtx - (0.1f * dist) * direction;//新しい点の座標
                HypPoint newPt  = new HypPoint(newVtx);
                if (!VA.GetComponent <Vertex>().Fixed&& newPt.InWorld())
                {
                    VA.GetComponent <Vertex>().XY = newVtx;
                }
                Vector2 startPos    = vtx - dist * direction;           //平行移動スタート点
                Vector2 endPos      = vtx - (0.8f * dist) * direction;  //平行移動ゴール点
                Vertex  lineVertex1 = hline.VA.GetComponent <Vertex>(); //動かすべき点1
                Vertex  lineVertex2 = hline.VB.GetComponent <Vertex>(); //動かすべき点2
                //new HypPoint(lineVertex1.XY).Println("LV1");
                //new HypPoint(lineVertex2.XY).Println("LV2");
                Vector2 XY1 = lineVertex1.XY;
                Vector2 XY2 = lineVertex2.XY;
                if (!lineVertex1.Fixed)
                {
                    HypPoint HP1    = new HypPoint(XY1);
                    HypPoint HPnew1 = HTransform.ParallelTransform(startPos, endPos, HP1);//点1を平行移動する
                    if (HPnew1.InWorld())
                    {
                        lineVertex1.XY.x = HPnew1.GetX();
                        lineVertex1.XY.y = HPnew1.GetY();
                    }
                    else
                    {
                        Debug.Log("error occurs at module P2L - 1A:" + HPnew1.X + "," + HPnew1.Y + "," + HPnew1.Z);
                        HP1.Println("HP1");
                        HPnew1.Println("HPnew1");
                        Debug.Log("dist " + dist);
                        Debug.Log("ln.R " + ln.R);
                        Debug.Log("direction " + direction.x + "," + direction.y);
                        Debug.Log("hlnCenter " + hlnCenter.x + "," + hlnCenter.y);
                        Debug.Log("startPos" + startPos.x + "," + startPos.y);
                        Debug.Log("endPos" + endPos.x + "," + endPos.y);
                        Debug.Log(XY1);
                    }
                }
                if (!lineVertex2.Fixed)
                {
                    HypPoint HP2    = new HypPoint(XY2);
                    HypPoint HPnew2 = HTransform.ParallelTransform(startPos, endPos, HP2);//点2を平行移動する
                    if (HPnew2.InWorld())
                    {
                        lineVertex2.XY.x = HPnew2.GetX();
                        lineVertex2.XY.y = HPnew2.GetY();
                    }
                    else
                    {
                        Debug.Log("error occurs at module P2L - 2A:" + HPnew2.X + "," + HPnew2.Y + "," + HPnew2.Z);
                    }
                }
                hline.GetHLineFromTwoVertices();
            }
        }
    }
Example #24
0
    void ModuleUpdateAngle()
    {
        Vertex   VtxA       = VA.GetComponent <Vertex>();         // 対象となる点A
        Vertex   VtxB       = VB.GetComponent <Vertex>();         // 対象となる点B
        Vertex   VtxC       = VC.GetComponent <Vertex>();         // 対象となる点C
        float    FinalAngle = Mathf.Abs(ParaA * Mathf.PI / 180f); // 対象となる角
        HypPoint PA         = new HypPoint(VtxA.XY);
        HypPoint PB         = new HypPoint(VtxB.XY);
        HypPoint PC         = new HypPoint(VtxC.XY);
        HypPoint PO         = new HypPoint(0, 0);
        // Bを原点に移す写像を求める。
        HypLine  LA  = HTransform.GetHBisectorOfTwoPoints(PB, PO);
        HypPoint PAA = HTransform.GetInversionAlongHLine(LA, PA);
        HypPoint PCC = HTransform.GetInversionAlongHLine(LA, PC);
        //角ABCを求める
        float DeclineA = Mathf.Atan2(PAA.GetY(), PAA.GetX());
        float DeclineC = Mathf.Atan2(PCC.GetY(), PCC.GetX());
        float AngleAC  = DeclineC - DeclineA;

        if (AngleAC > Mathf.PI)
        {
            AngleAC -= (Mathf.PI * 2f);
        }
        if (AngleAC < -Mathf.PI)
        {
            AngleAC += (Mathf.PI * 2f);
        }
        // 修正する角度をもとめる。
        float error = (AngleAC - FinalAngle) * 0.1f;

        if (AngleAC < 0)
        {
            error = (AngleAC + FinalAngle) * 0.1f;
        }
        //今一度点の取り直し。
        {//線分ABのとりなおし
            PA = new HypPoint(VtxA.XY);
            PB = new HypPoint(VtxB.XY);
            HypPoint PM = HTransform.GetMidPointOfTwoPoint(PA, PB);
            LA = HTransform.GetHBisectorOfTwoPoints(PM, PO);
            HypPoint PPA    = HTransform.GetInversionAlongHLine(LA, PA);
            HypPoint PPB    = HTransform.GetInversionAlongHLine(LA, PB);
            HypPoint NewPPA = HTransform.GetRotationOfPoint(PO, error, PPA);
            HypPoint NewPPB = HTransform.GetRotationOfPoint(PO, error, PPB);
            HypPoint NewPA  = HTransform.GetInversionAlongHLine(LA, NewPPA);
            HypPoint NewPB  = HTransform.GetInversionAlongHLine(LA, NewPPB);
            if (!VtxA.Fixed && NewPA.InWorld())
            {
                VtxA.XY.x = NewPA.GetX();
                VtxA.XY.y = NewPA.GetY();
            }
            if (!VtxB.Fixed && NewPB.InWorld())
            {
                VtxB.XY.x = NewPB.GetX();
                VtxB.XY.y = NewPB.GetY();
            }
        }
        {//線分BCの取り直し
            PC = new HypPoint(VtxC.XY);
            PB = new HypPoint(VtxB.XY);
            HypPoint PM = HTransform.GetMidPointOfTwoPoint(PC, PB);
            LA = HTransform.GetHBisectorOfTwoPoints(PM, PO);
            HypPoint PPC    = HTransform.GetInversionAlongHLine(LA, PC);
            HypPoint PPB    = HTransform.GetInversionAlongHLine(LA, PB);
            HypPoint NewPPC = HTransform.GetRotationOfPoint(PO, -error, PPC);
            HypPoint NewPPB = HTransform.GetRotationOfPoint(PO, -error, PPB);
            HypPoint NewPC  = HTransform.GetInversionAlongHLine(LA, NewPPC);
            HypPoint NewPB  = HTransform.GetInversionAlongHLine(LA, NewPPB);
            if (!VtxC.Fixed && NewPC.InWorld())
            {
                VtxC.XY.x = NewPC.GetX();
                VtxC.XY.y = NewPC.GetY();
            }
            if (!VtxB.Fixed && NewPB.InWorld())
            {
                VtxB.XY.x = NewPB.GetX();
                VtxB.XY.y = NewPB.GetY();
            }
        }
    }