} // ////////////////////////////////////////////////////////////////////////////////////////// public float dist(d2p other) { float dx = x - other.x; float dz = z - other.z; return(Mathf.Sqrt(dx * dx + dz * dz)); } // //////////////////////////////////////////////////////////////////////////////////////////
} // ///////////////////// EHD MODES /////////////////////////////////////////////////// void setCamera(GameObject gobj) { curTarg = gobj; d2p p = new d2p(gobj); setCamera(p); } // //////////////////////////////////////////////////////////////////////////////////////
} // ////////////////////////////////////////////////////////////////////////////////////////// public float rad(d2p Base) { if (z == Base.z) { return(0); } return(Mathf.Atan2(Base.z - z, x - Base.x)); } // //////////////////////////////////////////////////////////////////////////////////////////
public static d2p rotate(d2p Base, float rad, float len) { d2p p2 = rotate(rad); p2.x *= len; p2.z *= len; return(p2.sum(Base)); } // ////////////////////////////////////////////////////////////////////
} // ///////////////////////////////////////////////////////////////////////////////////////// static public bool Intersection(d2p a1, d2p a2, d2p b1, d2p b2, out d2p Cross) { d2p cross; Utils.Intersections.Info info; bool ret = Utils.Intersections.LineLine(a1, a2, b1, b2, out cross, out info); Cross = cross; return(ret); } // ////////////////////////////////////////////////////////////////////////////////////////
} // //////////////////////////////////////////////////////////////////////////////////// static public d2p rotateRef(d2p Base, d2p p, float rad) { d2p nrm = new d2p(p.x - Base.x, p.z - Base.z); float cos = Mathf.Cos(rad); float sin = Mathf.Sin(rad); float x = +nrm.x * cos + nrm.z * sin; float z = -nrm.x * sin + nrm.z * cos; return(new d2p(Base.x + x, Base.z + z)); } // ////////////////////////////////////////////////////////////////////////////////////
} // ////////////////////////////////////////////////////////////////////////////////////////////////// void getAngle(d2p cam, d2p pnt, float diam, out float min, out float max) { float dist = cam.dist(pnt); float alfa = Mathf.Atan2(diam / 2, dist); float beta = Mathf.PI - cam.rad(pnt); beta = d2p.normrad(beta); min = Mathf.Min(beta - alfa, beta + alfa); max = Mathf.Max(beta - alfa, beta + alfa); } // //////////////////////////////////////////////////////////////////////////////////
} // //////////////////////////////////////////////////////////////////////////////////////// static public d2p rotateRefQQQ(d2p Base, d2p p, float rad) { float len = Base.dist(p); d2p nrm = new d2p(p.x - Base.x, p.z - Base.z); float alfa = -Mathf.Asin(nrm.z / len); float beta = alfa - rad; float x = len * Mathf.Cos(beta); float z = len * Mathf.Sin(beta); return(new d2p(Base.x + x, Base.z + z)); } // ////////////////////////////////////////////////////////////////////////////////////
public bool selected; // is was select public Targ(GameObject game_object) { gobject = game_object; clrSel = gobject.GetComponent <Renderer>().material.color; float lUnSel = 0.7f; clrUnSel = new Color(clrSel.r * lUnSel, clrSel.g * lUnSel, clrSel.b * lUnSel); clrFade = new Color(clrSel.r, clrSel.g, clrSel.b, 0.3f); pnt = new d2p(gobject); selected = false; } // //////////////////////////////////////////////////////////////////////////////
} // /////////////// public static d2p setDist(d2p baza, d2p other, float newsize) { float len = baza.dist(other); if (len == 0) { return(new d2p(baza)); } float k = newsize / len; float dx = k * (other.x - baza.x); float dz = k * (other.z - baza.z); return(new d2p(baza.x + dx, baza.z + dz)); } // ///////////////////////////////////////////////////////////////////////////
} // /////////////////////////////////////////////////////////////////////////// public static d2p addDist(d2p baza, d2p other, float add) { float len = baza.dist(other); if (len == 0) { return(new d2p(other.x - add, other.z + add)); } float k = (len + add) / len; float dx = k * (other.x - baza.x); float dz = k * (other.z - baza.z); return(new d2p(baza.x + dx, baza.z + dz)); } // ///////////////////////////////////////////////////////////////////////////
} // ////////////////////////////////////////////////////////////////////////////////// float getHorSector(d2p cam, d2p cue, d2p aim, d2p luze, float agCueTarget) { float min, max, curmin, curmax; getAngle(cam, cue, Field.BallD, out min, out max); getAngle(cam, aim, Field.BallD, out curmin, out curmax); min = Mathf.Min(min, curmin); max = Mathf.Max(max, curmax); getAngle(cam, luze, 1.2f * Field.BallD, out curmin, out curmax); min = Mathf.Min(min, curmin); max = Mathf.Max(max, curmax); agCueTarget = d2p.normrad(agCueTarget); float maxd = d2p.rad2deg(Mathf.Max(agCueTarget - min, max - agCueTarget)); return(2 * maxd); } // //////////////////////////////////////////////////////////////////////////////////
} // ////////////////////////////////////////////////////////////////////////////// public int Preset(d2p p_targ, float dkcue) // call in waitSetBalls { ptarg = p_targ; foreach (var q in v) { q.reset(); } truepos = Field.rand.Next(-1, 1); sucess = seriesSucess = false; pball = new d2p(goBall); cntSelect = 0; if (dkcue > 0) { float d = -Field.BallD * dkcue; switch (truepos) { case -1: { assign(0); assign(1, d); assign(2, (d + d)); break; } case 0: { assign(0, -d); assign(1); assign(2, d); break; } case 1: { assign(0, -(d + d)); assign(1, -d); assign(2); break; } default: break; } } selectLast = -2; changePos = false; return(truepos); } // //////////////////////////////////////////////////////////////////////////////
public Targs(GameObject ball, GameObject object_left, GameObject object_center, GameObject object_right) { goBall = ball; pball = new d2p(goBall); truepos = selectLast = -2; sucess = seriesSucess = false; clrSucess = new Color(1, 1, 0); clrInvisible = new Color(0, 0, 0, 0); cntSelect = 0; v.Add(new Targ(object_left)); v.Add(new Targ(object_center)); v.Add(new Targ(object_right)); foreach (var q in v) { q.reset(); } } // //////////////////////////////////////////////////////////////////////////////
} // ////////////////////////////////////////////////////////////////////////////////////// void setCamera(d2p ptarget) { if (studyProcess.layout == null) { Debug.Break(); } Layout lay = studyProcess.layout; d2p pcam = getPCameraHoriz(ptarget, lay.pcue); float camdist = pcam.dist(lay.pcue); if (camdist < Field.distCueCam) { pcam = d2p.setDist(lay.pcue, pcam, Field.distCueCam); } d2p pbnd = new d2p(bounds); // far point arc float wfar = pcam.dist(pbnd); float wnear = pcam.dist(lay.pcue); float h = plcamera.transform.position.y; float degcamnear = d2p.rad2deg(Mathf.Atan2(h, wnear)); float degcamfar = d2p.rad2deg(Mathf.Atan2(h - bounds.transform.position.y, wfar)); float degcamavg = (degcamnear + degcamfar) / 2; float aCueTarget = lay.pcue.rad(ptarget); float agCueCam = d2p.rad2deg(aCueTarget - Mathf.PI / 2); Quaternion rotation = Quaternion.Euler(degcamavg, agCueCam, 0); plcamera.transform.SetPositionAndRotation( new Vector3(pcam.x, plcamera.transform.position.y, pcam.z), rotation); float sectorHor = getHorSector(pcam, lay.pcue, lay.paim, lay.pluze, Mathf.PI - aCueTarget); float sectorVert = degcamnear - degcamfar; float sectorMax = Mathf.Max(sectorVert, sectorHor); plcamera.fieldOfView = 1.05f * sectorMax; } // //////////////////////////////////////////////////////////////////////////////////////
} // //////////////////////////////////////////////////////////////////// public static d2p sum(d2p p1, d2p p2) { return(new d2p(p1.x + p2.x, p1.z + p2.z)); }
} // ////////////////////////////////////////////////////////////////////////////////////// d2p getPCameraHoriz(d2p ptarget, d2p pcue) { float alfa = -ptarget.rad(pcue); if (alfa == 0) { return(new d2p(-xmax, pcue.z)); } else if (alfa == -Mathf.PI / 2) { return(new d2p(pcue.x, -zmax)); } else if (alfa > 0 && alfa < Mathf.PI / 2) { // y = ax + b float a = (ptarget.z - pcue.z) / (ptarget.x - pcue.x); // >0 float b = pcue.z - a * pcue.x; float z = b - a * xmax; float x = (-zmax - b) / a; d2p camshort = new d2p(-xmax, z); d2p camlong = new d2p(x, -zmax); if (camshort.dist(pcue) <= camlong.dist(pcue)) { return(camshort); } return(camlong); } else if (alfa < 0 && alfa > -Mathf.PI / 2) { // y = ax + b float a = (ptarget.z - pcue.z) / (ptarget.x - pcue.x); // <0 float b = pcue.z - a * pcue.x; float z = b - a * xmax; float x = (zmax - b) / a; d2p camshort = new d2p(-xmax, z); d2p camlong = new d2p(x, zmax); if (camshort.dist(pcue) <= camlong.dist(pcue)) { return(camshort); } return(camlong); } else if (alfa > Mathf.PI / 2 && alfa < Mathf.PI) { // y = ax + b float a = (pcue.z - ptarget.z) / (pcue.x - ptarget.x); // <0 float b = pcue.z - a * pcue.x; float z = b + a * xmax; float x = (-zmax - b) / a; d2p camshort = new d2p(xmax, z); d2p camlong = new d2p(x, -zmax); if (camshort.dist(pcue) <= camlong.dist(pcue)) { return(camshort); } return(camlong); } else { Debug.Break(); } return(null); } // //////////////////////////////////////////////////////////////////////////////////////////////////
} // ////////////////////////////////////////////////////////////////////////////////////////// // return /_ AOB static public float rad3(d2p A, d2p O, d2p B) { return(B.rad(O) - A.rad(O)); } // //////////////////////////////////////////////////////////////////////////////////////////
} // ////////////////////////////////////////////////////////////////////////////////////////////////////// static public bool LineLine(d2p pABDot1, d2p pABDot2, d2p pCDDot1, d2p pCDDot2, out d2p pCross, out Info info) { info = new Info(); pCross = new d2p(); // Классическое уравнение прямой /* x - x1 y - y1 * ------- = -------- * x2 - x1 y2 - y1 * * запишем уравнение в одну строку * x(y2 - y1) + y(x1 - x2) - x1y2 + y1x2 = 0 * * a = (y2 - y1) * b = (x1 - x2) * c = (-x1y2 + y1x2) * * уравнение прямой с коэффициентами * ax + by + c = 0 * * если а b не равны 0, то * * a1x + b1y + c1 = 0 * a2x + b2y + c2 = 0 * * * решение * x = (b1c2 - c1b2) / (a1b2 - a2b1) * y = (a2c1 - c2a1) / (a1b2 - a2b1) */ /* Частный случай: прямая параллельна оси Х * тогда a = 0 */ /* Частный случай: одна из прямых параллельна оси Y * тогда b = 0 */ /* если и a = 0 и b = 0, то прямая не определена */ float a1 = pABDot2.z - pABDot1.z; float b1 = pABDot1.x - pABDot2.x; float c1 = -pABDot1.x * pABDot2.z + pABDot1.z * pABDot2.x; float a2 = pCDDot2.z - pCDDot1.z; float b2 = pCDDot1.x - pCDDot2.x; float c2 = -pCDDot1.x * pCDDot2.z + pCDDot1.z * pCDDot2.x; // До нахождения точки пересечения, // определим состояние параллельности данных прямых /* Необходимым и достаточным условием параллельности двух прямых является: * a1 b1 * ---- = ----- * a2 b2 * в одну строчку a1*b2 - a2*b1 = 0 */ // Обе прямые неопределенны if (a1 == 0 && b1 == 0 && a2 == 0 && b2 == 0) { info.Id = 10; info.Message = "Обе прямые не определены"; return(false); } // Направление первой прямой неопределенно if (a1 == 0 && b1 == 0) { info.Id = 11; info.Message = "Первая прямая не определена"; return(false); } // Направление второй прямой неопределенно if (a2 == 0 && b2 == 0) { info.Id = 12; info.Message = "Вторая прямая не определена"; return(false); } // Прямые параллельны if ((a1 * b2 - a2 * b1) == 0) { info.Id = 40; info.Message = "Прямые параллельны"; if (a1 == 0) // Прямые паралельны оси Х { info.Id = 41; info.Message = "Прямые паралельны оси Х"; } if (b1 == 0) // Прямые паралелльны оси Y { info.Id = 42; info.Message = "Прямые паралельны оси Y"; } // Прямые совпадают /* Необходимым и достаточным условием совпадения прямых является равенство: * a1/a2 = b1/b2 = c1/c2 */ if (a1 * b2 == b1 * a2 && a1 * c2 == a2 * c1 && b1 * c2 == c1 * b2) { info.Id = 43; info.Message = "Прямые совпадают"; } return(false); } // *** Прямые пересекаются *** pCross = Cross(a1, b1, c1, a2, b2, c2); /* Необходимым и достаточным условием перпендикулярности двух прямых является: * a1a2 + b1b2 = 0 */ // Прямые перпендикулярны if ((a1 * a2 + b1 * b2) == 0) { info.Id = 50; info.Message = "Прямые перпендикулярны"; return(true); } // Первая прямая паралельна оси Х if (a1 == 0) { info.Id = 60; info.Message = "Первая прямая параллельна оси Х"; return(true); } // Вторая прямая паралельна оси Х if (a2 == 0) { info.Id = 61; info.Message = "Вторая прямая параллельна оси Х"; return(true); } // Первая прямая параллельна оси Y if (b1 == 0) { info.Id = 70; info.Message = "Первая прямая параллельна оси Y"; return(true); } // Вторая прямая параллельна оси Y if (b2 == 0) { info.Id = 71; info.Message = "Вторая прямая параллельна оси Y"; return(true); } info.Id = 0; info.Message = "Общий случай"; return(true); } // ////////////////////////////////////////////////////////////////////////////////
public d2p sum(d2p p1) { return(new d2p(p1.x + x, p1.z + z)); } // ///////////////
} // ////////////////////////////////////////////////////////////////////////////////////////// public float deg(d2p Base) { return(rad2deg(rad(Base))); }
} // ///////////////////////////////////////////////////// public d2p(d2p V) { x = V.x; z = V.z; } // ////////////////////////////////////////////////////