////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); }
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); } }
//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; //} } } }
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); } }
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(); } } }
// 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 }); } }
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); } }
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(); } } }
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(); } } }