// LLL
    private bool ResolveBottomLLL(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 3 &&
            bottomConditions[0] is BottomLengthCondition && bottomConditions[1] is BottomLengthCondition && bottomConditions[2] is BottomLengthCondition)
        {
            BottomLengthCondition condition1 = (BottomLengthCondition)bottomConditions[0];
            BottomLengthCondition condition2 = (BottomLengthCondition)bottomConditions[1];
            BottomLengthCondition condition3 = (BottomLengthCondition)bottomConditions[2];

            float a, b, c;

            converter.aER = new EdgeRefer(condition1.edge.id1, condition1.edge.id2);
            converter.bER = new EdgeRefer(condition2.edge.id1, condition2.edge.id2);
            converter.cER = new EdgeRefer(condition3.edge.id1, condition3.edge.id2);

            a = condition1.length;
            b = condition2.length;
            c = condition3.length;

            judge = BottomLLL(a, b, c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }

        return(false);
    }
    // L  ->  LAL
    private bool ResolveBottomL(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 1 &&
            bottomConditions[0] is BottomLengthCondition)
        {
            BottomLengthCondition condition = (BottomLengthCondition)bottomConditions[0];

            float a, b, c, alpha;

            int id3 = EdgeOppositeIndex(condition.edge);

            converter.aER = new EdgeRefer(condition.edge.id1, condition.edge.id2);
            converter.bER = new EdgeRefer(condition.edge.id1, id3);
            converter.cER = new EdgeRefer(condition.edge.id2, id3);

            a     = condition.length;
            b     = EdgeIndexLength(condition.edge.id1, id3);
            c     = EdgeReferLength(converter.cER);
            alpha = CornerIndexAngle(condition.edge.id2, condition.edge.id1, id3);

            judge = BottomLAL(a, b, alpha, ref c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }
        return(false);
    }
    // A  ->  LAL
    private bool ResolveBottomA(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 1 &&
            bottomConditions[0] is BottomAngleCondition)
        {
            BottomAngleCondition condition = (BottomAngleCondition)bottomConditions[0];

            float a, b, c, alpha;

            converter.aER = new EdgeRefer(condition.corner.id1, condition.corner.id2);
            converter.bER = new EdgeRefer(condition.corner.id3, condition.corner.id2);
            converter.cER = new EdgeRefer(condition.corner.id1, condition.corner.id3);

            a     = EdgeIndexLength(condition.corner.id1, condition.corner.id2);
            b     = EdgeIndexLength(condition.corner.id3, condition.corner.id2);
            c     = EdgeReferLength(converter.cER);
            alpha = condition.angle;

            judge = BottomLAL(a, b, alpha, ref c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }
        return(false);
    }
 private bool SetBottom(BottomConverter converter)
 {
     if (converter == null)
     {
         return(false);
     }
     return(SetBottomVertex(converter.lenAB, converter.lenAC, converter.lenBC));
 }
    // ALA
    private bool ResolveBottomALA(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 3 &&
            bottomConditions[0] is BottomLengthCondition && bottomConditions[1] is BottomAngleCondition && bottomConditions[2] is BottomAngleCondition)
        {
            BottomLengthCondition condition1 = (BottomLengthCondition)bottomConditions[0];
            BottomAngleCondition  condition2 = (BottomAngleCondition)bottomConditions[1];
            BottomAngleCondition  condition3 = (BottomAngleCondition)bottomConditions[2];

            if (IsEdgeOppositeCorner(condition1.edge, condition2.corner) || IsEdgeOppositeCorner(condition1.edge, condition3.corner))
            {
                int   index = EdgeOppositeIndex(new EdgeRefer(condition2.corner.id2, condition3.corner.id2));
                float angle = 180 - condition2.angle - condition3.angle;
                BottomAngleCondition conditionN = new BottomAngleCondition(condition2.corner.id2, index, condition3.corner.id2, angle);
                if (IsEdgeOppositeCorner(condition1.edge, condition2.corner))
                {
                    condition2 = conditionN;
                }
                else if (IsEdgeOppositeCorner(condition1.edge, condition3.corner))
                {
                    condition3 = conditionN;
                }
            }

            float a, b, c, alpha, beta;

            int id3 = EdgeOppositeIndex(condition1.edge);

            converter.aER = new EdgeRefer(condition1.edge.id1, condition1.edge.id2);
            converter.bER = new EdgeRefer(condition2.corner.id2, id3);
            converter.cER = new EdgeRefer(condition3.corner.id2, id3);

            a     = condition1.length;
            b     = EdgeReferLength(converter.bER);
            c     = EdgeReferLength(converter.cER);
            alpha = condition2.angle;
            beta  = condition3.angle;

            judge = BottomALA(a, alpha, beta, ref b, ref c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }

        return(false);
    }
    // LLA
    private bool ResolveBottomLLA(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 3 &&
            bottomConditions[0] is BottomLengthCondition && bottomConditions[1] is BottomLengthCondition && bottomConditions[2] is BottomAngleCondition)
        {
            BottomLengthCondition condition1 = (BottomLengthCondition)bottomConditions[0];
            BottomLengthCondition condition2 = (BottomLengthCondition)bottomConditions[1];
            BottomAngleCondition  condition3 = (BottomAngleCondition)bottomConditions[2];

            bool isLLA = IsEdgeOppositeCorner(condition1.edge, condition3.corner) || IsEdgeOppositeCorner(condition2.edge, condition3.corner);
            if (!isLLA)
            {
                return(false);
            }

            if (IsEdgeOppositeCorner(condition1.edge, condition3.corner))
            {
                SwapCondition <BottomLengthCondition>(ref condition1, ref condition2);
            }

            float a, b, c, alpha;

            int id3 = EdgeOppositeIndex(condition1.edge);

            converter.aER = new EdgeRefer(condition1.edge.id1, condition1.edge.id2);
            converter.bER = new EdgeRefer(condition2.edge.id1, condition2.edge.id2);
            converter.cER = new EdgeRefer(condition3.corner.id2, id3);

            a     = condition1.length;
            b     = condition2.length;
            c     = EdgeReferLength(converter.cER);
            alpha = condition3.angle;

            judge = BottomLLA(a, b, alpha, ref c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }

        return(false);
    }
    // AA -> ALA
    private bool ResolveBottomAA(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 2 &&
            bottomConditions[0] is BottomAngleCondition && bottomConditions[1] is BottomAngleCondition)
        {
            BottomAngleCondition condition1 = (BottomAngleCondition)bottomConditions[0];
            BottomAngleCondition condition2 = (BottomAngleCondition)bottomConditions[1];

            if (condition1.corner.id1 == condition2.corner.id3)
            {
                condition2.corner.SwapIndex();
            }
            if (condition1.corner.id3 == condition2.corner.id1)
            {
                condition1.corner.SwapIndex();
            }
            if (condition1.corner.id3 == condition2.corner.id3)
            {
                condition1.corner.SwapIndex();
                condition2.corner.SwapIndex();
            }

            float a, b, c, alpha, beta;

            converter.aER = new EdgeRefer(condition1.corner.id2, condition2.corner.id2);
            converter.bER = new EdgeRefer(condition1.corner.id1, condition1.corner.id2);
            converter.cER = new EdgeRefer(condition2.corner.id1, condition2.corner.id2);

            a     = EdgeIndexLength(condition1.corner.id2, condition2.corner.id2);
            b     = EdgeReferLength(converter.bER);
            c     = EdgeReferLength(converter.cER);
            alpha = condition1.angle;
            beta  = condition2.angle;

            judge = BottomALA(a, alpha, beta, ref b, ref c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }
        return(false);
    }
    // LL  ->  LAL
    private bool ResolveBottomLL(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 2 &&
            bottomConditions[0] is BottomLengthCondition && bottomConditions[1] is BottomLengthCondition)
        {
            BottomLengthCondition condition1 = (BottomLengthCondition)bottomConditions[0];
            BottomLengthCondition condition2 = (BottomLengthCondition)bottomConditions[1];

            if (condition1.edge.id1 == condition2.edge.id2)
            {
                condition2.edge.SwapIndex();
            }
            if (condition1.edge.id2 == condition2.edge.id1)
            {
                condition1.edge.SwapIndex();
            }
            if (condition1.edge.id2 == condition2.edge.id2)
            {
                condition1.edge.SwapIndex();
                condition2.edge.SwapIndex();
            }

            float a, b, c, alpha;

            converter.aER = new EdgeRefer(condition1.edge.id1, condition1.edge.id2);
            converter.bER = new EdgeRefer(condition2.edge.id1, condition2.edge.id2);
            converter.cER = new EdgeRefer(condition1.edge.id2, condition2.edge.id2);

            a     = condition1.length;
            b     = condition2.length;
            c     = EdgeReferLength(converter.cER);
            alpha = CornerIndexAngle(condition1.edge.id2, condition1.edge.id1, condition2.edge.id2);

            judge = BottomLAL(a, b, alpha, ref c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }
        return(false);
    }
    // AL -> LAL
    private bool ResolveBottomAL(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 2 &&
            bottomConditions[0] is BottomLengthCondition && bottomConditions[1] is BottomAngleCondition)
        {
            BottomLengthCondition condition1 = (BottomLengthCondition)bottomConditions[0];
            BottomAngleCondition  condition2 = (BottomAngleCondition)bottomConditions[1];

            bool isAL = IsEdgeAdjacentCorner(condition1.edge, condition2.corner);
            if (!isAL)
            {
                return(false);
            }

            float a, b, c, alpha;

            int id3 = EdgeOppositeIndex(condition1.edge);

            converter.aER = new EdgeRefer(condition1.edge.id1, condition1.edge.id2);
            converter.bER = new EdgeRefer(condition2.corner.id2, id3);
            converter.cER = new EdgeRefer(condition2.corner.id1, condition2.corner.id3);

            a     = condition1.length;
            b     = EdgeIndexLength(condition2.corner.id2, id3);
            c     = EdgeReferLength(converter.cER);
            alpha = condition2.angle;

            judge = BottomLAL(a, b, alpha, ref c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }

        return(false);
    }
    // LA -> LLA
    private bool ResolveBottomLA(BottomConverter converter, out bool judge)
    {
        judge = false;

        if (bottomConditions.Count == 2 &&
            bottomConditions[0] is BottomLengthCondition && bottomConditions[1] is BottomAngleCondition)
        {
            BottomLengthCondition condition1 = (BottomLengthCondition)bottomConditions[0];
            BottomAngleCondition  condition2 = (BottomAngleCondition)bottomConditions[1];

            bool isLA = IsEdgeOppositeCorner(condition1.edge, condition2.corner);
            if (!isLA)
            {
                return(false);
            }

            float a, b, c, alpha;

            converter.aER = new EdgeRefer(condition2.corner.id2, condition2.corner.id1);
            converter.bER = new EdgeRefer(condition2.corner.id1, condition2.corner.id3);
            converter.cER = new EdgeRefer(condition2.corner.id2, condition2.corner.id3);

            b     = condition1.length;
            alpha = condition2.angle;
            a     = Mathf.Min(b / Mathf.Sin(alpha * Mathf.Deg2Rad), EdgeIndexLength(condition2.corner.id2, condition2.corner.id1));
            c     = EdgeReferLength(converter.cER);

            judge = BottomLLA(a, b, alpha, ref c);

            ConverterSetABC(converter, a, b, c);

            return(true);
        }

        return(false);
    }
    private bool ResolveBottom(out BottomConverter converter)
    {
        converter = new BottomConverter();

        ResolveBottomDelegate[] resolves1 =
        {
            ResolveBottomA,
            ResolveBottomL,
        };

        ResolveBottomDelegate[] resolves2 =
        {
            ResolveBottomAA,
            ResolveBottomLL,
            ResolveBottomLA,
            ResolveBottomAL,
        };

        ResolveBottomDelegate[] resolves3 =
        {
            ResolveBottomLLL,
            ResolveBottomLAL,
            ResolveBottomLLA,
            ResolveBottomALA,
        };

        ResolveBottomDelegate[][] resolvesArray =
        {
            resolves1,
            resolves2,
            resolves3,
        };

        ResolveBottomDelegate[] resolves = null;
        for (int i = 0; i < resolvesArray.Length; i++)
        {
            if (bottomConditions.Count == i + 1)
            {
                resolves = resolvesArray[i];
                break;
            }
        }

        if (resolves == null)
        {
            return(false);
        }

        foreach (ResolveBottomDelegate resolve in resolves)
        {
            bool judge;
            if (resolve(converter, out judge))
            {
                Debug.Log(resolve);
                if (judge)
                {
                    converter.Resolve();
                    return(true);
                }
                else
                {
                    Debug.LogWarning("Error Condition In Resolve");
                    return(false);
                }
            }
        }

        return(false);
    }
 private void ConverterSetABC(BottomConverter converter, float a, float b, float c)
 {
     converter.a = a;
     converter.b = b;
     converter.c = c;
 }