Ejemplo n.º 1
0
    /// <summary>
    /// Fija un angulo dado a las divisiones de una circunferencia.
    /// </summary>
    /// <returns>The to.</returns>
    /// <param name="v3">V3.</param>
    /// <param name="snapAngle">Snap angle.</param>
    /// <param name="url">http://answers.unity3d.com/questions/493006/snap-a-direction-vector.html</param>
    Vector3 SnapToAngle(Vector3 newPinPos, Vector3 collidedPinPos)
    {
        Vector3 axisDirection;

        if (me.GetPosition() == collidedPinPos)
        {
            axisDirection = Vector3.down;
        }
        else
        {
            axisDirection = (collidedPinPos - Vector3.zero).normalized;
        }

        float deltaAngle = Vector3.Angle(Vector3.down, axisDirection);

        Vector3 dir   = (collidedPinPos - newPinPos).normalized;
        float   angle = Vector3.Angle(axisDirection, dir);

        float badAngle = angle;

        //angle = angle.RoundToNearest(circleDivisions); // Deja esto calculado de antes si puedes

        //angulo entre rotor y bola puesta respecto de V3.down
        //angulo entre bola lanzada y bola puesta respecto del angulo anterior
        // Calculamos el angulo al que se debería pegar la bola lanzada a la bola puesta
        // devolvemos la posición correcta de la bola lanzada

        /*
         * float angle = Vector3.Angle(Vector3.down, dir);
         * float badAngle = angle;
         *
         * angle = angle.RoundToNearest(circleDivisions); // Deja esto calculado de antes si puedes
         */
        float finalAng = (angle + deltaAngle).RoundToNearest(circleDivisions);

        //Debug.LogFormat ("Angulo {0} -> snappedTo {1}  ==> angulo final ({1} + {2}) = {3} -> snappedTo {4}", badAngle.ToString(), angle.ToString (),  deltaAngle.ToString(), (angle + deltaAngle).ToString(), finalAng.ToString());

        return(new Vector3(Mathf.Sin(finalAng * Mathf.Deg2Rad) * Mathf.Sign(dir.x), -Mathf.Cos(finalAng * Mathf.Deg2Rad) * Mathf.Sign(dir.y), 0));
    }
Ejemplo n.º 2
0
    float DistanceBetweenCircumferences(Circumference A, Circumference B)
    {
        float d = DistanceBetweenPoints(A.GetPosition(), B.GetPosition()) - ((A.GetRadius() + B.GetRadius()) * (A.GetRadius() + B.GetRadius()));

        return(d);
    }
Ejemplo n.º 3
0
    void Reposition(Circumference newPin)
    {
        //foreach (Circumference c in circumferencesCollided)
        //	Debug.LogFormat ("<color=blue>Colision con {0} ({1}): distancia: {2}</color>", c.name, c.tag, DistanceBetweenCircumferences (newPin, c));

        if (circumferencesCollided.Count > 1)
        {
            circumferencesCollided.Sort((A, B) => DistanceBetweenCircumferences(newPin, A).CompareTo(DistanceBetweenCircumferences(newPin, B)));
        }

        // Si mas de dos, nos quedamos sólo con los dos mas cercanos
        if (circumferencesCollided.Count > 2)
        {
            circumferencesCollided = circumferencesCollided.GetRange(0, 2);
        }

        //foreach (Circumference c in circumferencesCollided)
        //	Debug.LogFormat ("<color=yellow>Colision aceptada: {0} ({1}) ( distancia: {2})</color>", c.name, c.tag, DistanceBetweenCircumferences (newPin, c));
        switch (circumferencesCollided.Count)
        {
        case 1:
            /*
             * //debug posicion pin colisionado
             * DrawTheGizmo (new GizmoToDraw( GizmoType.sphere, pinsCollided[0].GetPosition(), pinsCollided[0].GetRadius(), Color.gray ) );
             * //debug posicion new pin en el momento de la collision
             * DrawTheGizmo( new GizmoToDraw( GizmoType.sphere, newPin.GetPosition(), newPin.GetRadius(), Color.yellow ) );
             */

            // Reposición
            //newPin.transform.position = circumferencesCollided[0].GetPosition() + ( ( newPin.GetPosition() - circumferencesCollided[0].GetPosition() ).normalized * ( newPin.GetRadius() + circumferencesCollided[0].GetRadius() ) );
            newPin.transform.position = circumferencesCollided[0].GetPosition() + SnapNormalizedVector(newPin.GetPosition(), circumferencesCollided[0].GetPosition()) * (newPin.GetRadius() + circumferencesCollided[0].GetRadius());

            //debug posicion new pin despues de la colocación
            //DrawTheGizmo ( new GizmoToDraw( GizmoType.sphere, newPin.GetPosition(), newPin.GetRadius(), Color.green ) );
            if (circumferencesCollided[0].tag == "Rotator")
            {
                newPin.GetComponent <Pin>().DrawSpear();
            }
            break;

        case 2:
            Circumference A = circumferencesCollided [0];
            Circumference B = circumferencesCollided [1];
            if (A == B)
            {
                //Debug.Log ("Error WTF 0002: Hemos colisionador dos veces con el mismo Pin");
                AnalyticsSender.SendCustomAnalitycs("wtfError", new Dictionary <string, object>()
                {
                    { "type", "0002" },
                    { "message", "Hemos colisionador dos veces con el mismo Pin" }
                });
            }

            //Solución de Fernando Rojas basada en: https://es.wikipedia.org/wiki/Teorema_del_coseno
            float Lc = (B.GetPosition() - A.GetPosition()).magnitude;                       //A.GetRadius() + B.GetRadius();
            float La = B.GetRadius() + newPin.GetRadius();
            float Lb = newPin.GetRadius() + A.GetRadius();

            float a = Mathf.Rad2Deg * Mathf.Acos((Lb * Lb + Lc * Lc - La * La) / (2 * Lb * Lc));

            Vector3 ab = (B.GetPosition() - A.GetPosition()).normalized;

            Quaternion rot       = Quaternion.AngleAxis(a, Vector3.forward);
            Vector3    Solution1 = A.GetPosition() + rot * ab * Lb;

            rot = Quaternion.AngleAxis(a, -Vector3.forward);
            Vector3 Solution2 = A.GetPosition() + rot * ab * Lb;

            #region "Otra solución - Solo funciona con circulos con igual radio"

            /*
             * //Solución para el ajuste de posición. http://stackoverflow.com/questions/18558487/tangent-circles-for-two-other-circles
             * // 1 Calculate distance from A to B -> |AB|:
             * float AB = Vector3.Distance(A.GetPosition(), B.GetPosition());
             * // 2 Checks whether a solution exist, it exist only if:
             * Debug.Assert(AB <= 4 * newPin.GetComponent<Circumference>().GetRadius());
             * // 3 If it exist, calculate half-point between points A and B:
             * Vector2 H = new Vector2( A.GetPosition().x + ( (B.GetPosition().x - A.GetPosition().x) / 2 ), A.GetPosition().y + ( (B.GetPosition().y - A.GetPosition().y) / 2 ) );
             * // 4 Create normalized perpendicular vector to line segment AB:
             * Vector2 HC_perp_norm = new Vector2( (B.GetPosition().y - A.GetPosition().y) / AB, -(B.GetPosition().x - A.GetPosition().x) / AB );
             * // 5 Calculate distance from this H point to C point -> |HC|:
             * float HCpos = Mathf.Abs( 0.5f * Mathf.Sqrt( 16 * ( newPin.GetRadius() * newPin.GetRadius() ) - (AB*AB) ) );
             * float HCneg = -( 0.5f * Mathf.Sqrt( 16 * ( newPin.GetRadius() * newPin.GetRadius() ) - (AB*AB) ) );
             * // Posibles soluciones
             * Vector3 Solution1 = new Vector3 (H.x + (HCpos * HC_perp_norm.x), H.y + (HCpos * HC_perp_norm.y), 0);
             * Vector3 Solution2 = new Vector3 (H.x + (HCneg * HC_perp_norm.x), H.y + (HCneg * HC_perp_norm.y), 0);
             */
            #endregion
            // nos quedamos con la mas cercana al spawner
            Vector3 sol = DistanceBetweenPoints(Solution1, GameManager.instance.spawner.transform.position) <
                          DistanceBetweenPoints(Solution2, GameManager.instance.spawner.transform.position) ? Solution1 : Solution2;

            if (float.IsNaN(sol.x))
            {
                //Debug.Log ("<color=red>Error WTF 0003: Naaaaaaan</color>");
                AnalyticsSender.SendCustomAnalitycs("wtfError", new Dictionary <string, object>()
                {
                    { "type", "0003" },
                    { "message", "La reposición contiene numero inválidos: (" + sol.ToString() + "). Cambio NaN -> cero" }
                });
                sol = new Vector3(float.IsNaN(sol.x) ? 0 : sol.x, float.IsNaN(sol.y) ? 0 : sol.y, float.IsNaN(sol.y) ? 0 : sol.y);
                // TODO: Enviar como estadística de errores
            }
            else
            {
                // Posición final
                newPin.transform.position = sol;
            }

            /*
             * /// DEBUG ///
             * //debug posicion new pin en el momento de la collision
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.sphere, newCircumference.GetPosition(), newCircumference.GetRadius(), Color.white ) );
             * //debug posicion pins colisionados
             * //A
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.sphere, A.GetPosition(), A.GetRadius(), Color.green ) );
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, A.GetPosition(), A.GetPosition() + (B.GetPosition () - A.GetPosition()).normalized * A.GetRadius(), Color.green ) ); // Ra to Rb
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, A.GetPosition(), A.GetPosition() + (Solution1 - A.GetPosition()).normalized * A.GetRadius(), Color.green ) );// Linea A-Solution1
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, A.GetPosition(), A.GetPosition() + (Solution2 - A.GetPosition()).normalized * A.GetRadius(), Color.green ) );//Linea  B-Solution2
             * //B
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.sphere, B.GetPosition(), B.GetRadius(), Color.green ) );
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, B.GetPosition(), B.GetPosition() + (A.GetPosition () - B.GetPosition()).normalized * B.GetRadius(), Color.green ) ); // Rb to Ra
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, B.GetPosition(), B.GetPosition() + (Solution1 - B.GetPosition()).normalized * B.GetRadius(), Color.green ) ); // Linea A-Solution1
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, B.GetPosition(), B.GetPosition() + (Solution2 - B.GetPosition()).normalized * B.GetRadius(), Color.green ) ); // Linea B-Solution2
             * //Solution 1
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.sphere, Solution1, newCircumference.GetRadius(), Color.yellow ) );
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, Solution1, Solution1 + (A.GetPosition () - Solution1).normalized * newCircumference.GetRadius(), Color.yellow ) ); // Linea Solution1-A
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, Solution1, Solution1 + (B.GetPosition () - Solution1).normalized * newCircumference.GetRadius(), Color.yellow ) ); // Linea Solution1-B
             * //Solution 2
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.sphere, Solution2, newCircumference.GetRadius(), Color.yellow ) );
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, Solution2, Solution2 + (A.GetPosition () - Solution2).normalized * newCircumference.GetRadius(), Color.yellow ) ); // Linea Solution2-A
             * DrawTheGizmo ( new GizmoToDraw( GizmoType.line, Solution2, Solution2 + (B.GetPosition () - Solution2).normalized * newCircumference.GetRadius(), Color.yellow ) ); // Linea Solution2-B
             * //Posicion fianl decidida...
             * //DrawTheGizmo ( new GizmoToDraw( GizmoType.sphere, newPin.transform.position, newCircumference.GetRadius(), Color.black ) );
             */
            break;

        default:
            //Debug.Log(string.Format("<color=red> ERROR WTF 0004: número de colisiones incorrectas: {0}</color>", circumferencesCollided.Count.ToString()));

            AnalyticsSender.SendCustomAnalitycs("wtfError", new Dictionary <string, object>()
            {
                { "type", "0004" },
                { "message", "número de colisiones incorrectas: (" + circumferencesCollided.Count.ToString() + ")" }
            });
            break;
        }
    }