Beispiel #1
0
        double pwl(ExprState es, List <Expr> args)
        {
            double x  = args[0].Eval(es);
            double x0 = args[1].Eval(es);
            double y0 = args[2].Eval(es);

            if (x < x0)
            {
                return(y0);
            }
            double x1 = args[3].Eval(es);
            double y1 = args[4].Eval(es);
            int    i  = 5;

            while (true)
            {
                if (x < x1)
                {
                    return(y0 + (x - x0) * (y1 - y0) / (x1 - x0));
                }
                if (i + 1 >= args.Count)
                {
                    break;
                }
                x0 = x1;
                y0 = y1;
                x1 = args[i].Eval(es);
                y1 = args[i + 1].Eval(es);
                i += 2;
            }
            return(y1);
        }
Beispiel #2
0
        public double Eval(ExprState es)
        {
            Expr left  = null;
            Expr right = null;

            if (Children != null && Children.Count > 0)
            {
                left = Children[0];
                if (Children.Count == 2)
                {
                    right = Children[Children.Count - 1];
                }
            }
            switch (type)
            {
            case EXPR_TYPE.E_ADD:
                return(left.Eval(es) + right.Eval(es));

            case EXPR_TYPE.E_SUB:
                return(left.Eval(es) - right.Eval(es));

            case EXPR_TYPE.E_MUL:
                return(left.Eval(es) * right.Eval(es));

            case EXPR_TYPE.E_DIV:
                return(left.Eval(es) / right.Eval(es));

            case EXPR_TYPE.E_POW:
                return(Math.Pow(left.Eval(es), right.Eval(es)));

            case EXPR_TYPE.E_UMINUS:
                return(-left.Eval(es));

            case EXPR_TYPE.E_VAL:
                return(value);

            case EXPR_TYPE.E_T:
                return(es.Time);

            case EXPR_TYPE.E_SIN:
                return(Math.Sin(left.Eval(es)));

            case EXPR_TYPE.E_COS:
                return(Math.Cos(left.Eval(es)));

            case EXPR_TYPE.E_ABS:
                return(Math.Abs(left.Eval(es)));

            case EXPR_TYPE.E_EXP:
                return(Math.Exp(left.Eval(es)));

            case EXPR_TYPE.E_LOG:
                return(Math.Log(left.Eval(es)));

            case EXPR_TYPE.E_SQRT:
                return(Math.Sqrt(left.Eval(es)));

            case EXPR_TYPE.E_TAN:
                return(Math.Tan(left.Eval(es)));

            case EXPR_TYPE.E_MIN: {
                int    i;
                double x = left.Eval(es);
                for (i = 1; i < Children.Count; i++)
                {
                    x = Math.Min(x, Children[i].Eval(es));
                }
                return(x);
            }

            case EXPR_TYPE.E_MAX: {
                int    i;
                double x = left.Eval(es);
                for (i = 1; i < Children.Count; i++)
                {
                    x = Math.Max(x, Children[i].Eval(es));
                }
                return(x);
            }

            case EXPR_TYPE.E_CLAMP:
                return(Math.Min(Math.Max(left.Eval(es), Children[1].Eval(es)), Children[2].Eval(es)));

            case EXPR_TYPE.E_STEP: {
                double x = left.Eval(es);
                if (right == null)
                {
                    return((x < 0) ? 0 : 1);
                }
                return((x > right.Eval(es)) ? 0 : (x < 0) ? 0 : 1);
            }

            case EXPR_TYPE.E_SELECT: {
                double x = left.Eval(es);
                return(Children[x > 0 ? 2 : 1].Eval(es));
            }

            case EXPR_TYPE.E_TRIANGLE: {
                double x = posmod(left.Eval(es), Math.PI * 2) / Math.PI;
                return((x < 1) ? -1 + x * 2 : 3 - x * 2);
            }

            case EXPR_TYPE.E_SAWTOOTH: {
                double x = posmod(left.Eval(es), Math.PI * 2) / Math.PI;
                return(x - 1);
            }

            case EXPR_TYPE.E_MOD:
                return(left.Eval(es) % right.Eval(es));

            case EXPR_TYPE.E_PWL:
                return(pwl(es, Children));

            default:
                if (type >= EXPR_TYPE.E_A)
                {
                    return(es.Values[type - EXPR_TYPE.E_A]);
                }
                Console.WriteLine("unknown\n");
                break;
            }
            return(0);
        }