/* Function: PickOutputString(position)
     *
     * checks the string position and then returns the rule which corresponds to the value chosen
     *
     *
     */
    public string PickOutputString(int rule_position)
    {
        float rule_value = rng.NextFloat();

        for (int i = 0; i < stochastic_values.GetLength(1); ++i)
        {
            if (stochastic_values[rule_position, i] >= rule_value)
            {
                return(rules_out[rule_position, i]);
            }
        }
        return(rules_in[rule_position]);
    }
    // checks the angle relative to the flow and phototaxis
    // relevant variables are light_constant, light_direction, flow, test_flow, and flow_constant
    private void AdjustAngles(ref float angle_a, ref float angle_b)
    {
        Vector3 temp_vector = RotatePoint(new Vector3(0, 1, 0), angle_a, angle_b);

        //float dp = Mathf.Sqrt(Vector3.Dot(test_flow, temp_vector))/(Mathf.Sqrt(Vector3.Dot(test_flow,test_flow))*Mathf.Sqrt(Vector3.Dot(temp_vector, temp_vector)));
        if (debug_AdjustAngles)
        {
            //Debug.Log ("cp value is " + cp);
            //Debug.Log ("dp value is " + dp);
            Debug.Log("angle a value before is " + angle_a);
            Debug.Log("angle b value before is " + angle_b);
        }

        // if dp = 0 we are happy, else we want to make dp = 0 because that means the branch is perpendicular to the flow
        if (flow_on)
        {
            Vector3 cp1  = new Vector3(0, 0, 0);
            Vector3 cp2  = new Vector3(0, 0, 0);
            Vector3 temp = new Vector3(0, 0, 0);
            cp1  = Vector3.Cross(test_flow, temp_vector);
            cp2  = Vector3.Cross(test_flow, cp1);
            temp = Vector3.RotateTowards(temp_vector, cp2, flow_constant_lerp, max_mag);
            float theta = Mathf.PI / 2;
            if (temp.x != 0)
            {
                theta = Mathf.Atan(temp.y / temp.x);
            }
            float phi = Mathf.Acos(temp.z);
            angle_b = (flow_constant * phi) + ((1.0f - flow_constant) * angle_b);
            angle_a = (flow_constant * theta) + ((1.0f - flow_constant) * angle_a);
            if (debug_AdjustAngles)
            {
                Debug.Log("theta and phi are " + theta + " " + phi);
                Debug.Log("cp1 is " + cp1.ToString());
                Debug.Log("cp2 is " + cp2.ToString());
                Debug.Log("temp is " + temp.ToString());
            }
        }
        // we need to look at the continueum propperly, cp produces sin theta and dp produces the dot product
        if (add_phototaxis)
        {
            if (angle_b > Mathf.PI)
            {
                angle_b += light_constant;
            }
            else
            {
                angle_b -= light_constant;
            }
        }
        if (invariant_flow_on)
        {
            if (angle_a > Mathf.PI)
            {
                if (angle_a > ((3 * Mathf.PI) / 2))
                {
                    angle_a += flow_constant;
                }
                else
                {
                    angle_a -= flow_constant;
                }
            }
            else
            {
                if (angle_a < (Mathf.PI / 2))
                {
                    angle_a -= flow_constant;
                }
                else
                {
                    angle_a += flow_constant;
                }
            }
        }
        if (add_wobble)
        {
            angle_a += (wobble_rng.NextFloat() - 0.5f) * wobble_strength;
            angle_b += (wobble_rng.NextFloat() - 0.5f) * wobble_strength;
        }
        if (debug_AdjustAngles)
        {
            Debug.Log("angle a value after is " + angle_a);
            Debug.Log("angle b value after is " + angle_b);
        }
        angle_a = (angle_a + two_pi) % two_pi;
        angle_b = (angle_b + two_pi) % two_pi;
    }