SeExpr
asciiGraph.cpp
Go to the documentation of this file.
1/*
2* Copyright Disney Enterprises, Inc. All rights reserved.
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License
6* and the following modification to it: Section 6 Trademarks.
7* deleted and replaced with:
8*
9* 6. Trademarks. This License does not grant permission to use the
10* trade names, trademarks, service marks, or product names of the
11* Licensor and its affiliates, except as required for reproducing
12* the content of the NOTICE file.
13*
14* You may obtain a copy of the License at
15* http://www.apache.org/licenses/LICENSE-2.0
16*/
17#include <SeExpr2/Expression.h>
18#include <cstdlib>
19#include <cstdio>
20#include <cstring>
21
22using namespace SeExpr2;
23
28class GrapherExpr : public Expression {
29 public:
31 GrapherExpr(const std::string& expr) : Expression(expr) {}
32
34 void setX(double x_input) { x.val = x_input; }
35
36 private:
38 struct SimpleVar : public ExprVarRef {
39 SimpleVar() : ExprVarRef(ExprType().FP(1).Varying()), val(0.0) {}
40
41 double val; // independent variable
42 void eval(double* result) { result[0] = val; }
43
44 void eval(const char** result) {}
45 };
46
48 mutable SimpleVar x;
49
51 ExprVarRef* resolveVar(const std::string& name) const {
52 if (name == "x") return &x;
53 return 0;
54 }
55};
56
57int main(int argc, char* argv[]) {
58 std::string exprStr =
59 "\
60 $val=.5*PI*x;\
61 7*sin(val)/val \
62 ";
63 if (argc == 2) {
64 exprStr = argv[1];
65 }
66 GrapherExpr expr(exprStr);
67
68 if (!expr.isValid()) {
69 std::cerr << "expression failed " << expr.parseError() << std::endl;
70 exit(1);
71 } else if (!expr.returnType().isFP(1)) {
72 std::cerr << "Expected expression of type " << ExprType().FP(1).Varying().toString() << " got "
73 << expr.returnType().toString() << std::endl;
74 exit(1);
75 }
76
77 double xmin = -10, xmax = 10, ymin = -10, ymax = 10;
78 int w = 60, h = 30;
79 char* buffer = new char[w * h];
80 memset(buffer, (int)' ', w * h);
81
82 // draw x axis
83 int j_zero = (-ymin) / (ymax - ymin) * h;
84 if (j_zero >= 0 && j_zero < h) {
85 for (int i = 0; i < w; i++) {
86 buffer[i + j_zero * w] = '-';
87 }
88 }
89 // draw y axis
90 int i_zero = (-xmin) / (xmax - xmin) * w;
91 if (i_zero >= 0 && i_zero < w) {
92 for (int j = 0; j < h; j++) {
93 buffer[i_zero + j * w] = '|';
94 }
95 }
96
97 // evaluate the graph
98 const int samplesPerPixel = 10;
99 const double one_over_samples_per_pixel = 1. / samplesPerPixel;
100 for (int i = 0; i < w; i++) {
101 for (int sample = 0; sample < samplesPerPixel; sample++) {
102 // transform from device to logical coordinatex
103 double dx = double(sample) * one_over_samples_per_pixel;
104 double x = double(dx + i) / double(w) * (xmax - xmin) + xmin;
105 // prep the expression engine for evaluation
106 expr.setX(x);
107 const double* val = expr.evalFP();
108 // evaluate and pull scalar value - currently does not work
109 // TODO: fix eval and then use actual call
110 // Vec3d val=0.0;//expr.evaluate();
111 double y = val[0];
112 // transform from logical to device coordinate
113 int j = (y - ymin) / (ymax - ymin) * h;
114 // store to the buffer
115 if (j >= 0 && j < h) buffer[i + j * w] = '#';
116 }
117 }
118
119 // draw the graph from the buffer
120 for (int j = h - 1; j >= 0; j--) {
121 for (int i = 0; i < w; i++) {
122 std::cout << buffer[i + j * w];
123 }
124 std::cout << std::endl;
125 }
126
127 return 0;
128}
int main(int argc, char *argv[])
ExprType & FP(int d)
Mutate this into a floating point type of dimension d.
Definition ExprType.h:90
std::string toString() const
Stringify the type into a printable string.
Definition ExprType.h:191
ExprType & Varying()
Mutate this into a varying lifetime.
Definition ExprType.h:122
abstract class for implementing variable references
Definition Expression.h:45
virtual void eval(double *result)=0
returns this variable's value by setting result
main expression class
Definition Expression.h:76
</pre >< h3 > Binding our variable reference</h3 > If we now tried to use the variable would still not be found by our expressions To make it bindable we need to override the resolveVar() function as follows</pre >< h3 > Variable setting</h3 > Next we need to make a way of setting the variable As the controlling code will use the expression it will repeatedly alternate between setting the independent variables that are used and calling evaluate(). What it has to do depends very much on the application. In this case we only need to set the independent variable x as</pre >< h2 > Evaluating expressions</h2 > Evaluating an expression is pretty easy But before we can do that we need to make an instance< pre > GrapherExpr expr("x+x^2")
const double one_over_samples_per_pixel
Definition tutorial.txt:192
</pre > Once we have this we need an instance to store our variable and provide a reference to that We make it because resolveVar() is const . One does not need to store a variable reference in a given expression. In fact
</pre >< h3 > A simple variable reference</h3 > This is not a very interesting subclass of expression until we add some additional variables Variables on some applications may be very dynamic In this we only need x
Definition tutorial.txt:108
This is the same as the prman cellnoise function< br ></div >< br > float< b > float y< br > float< b > float y
Definition userdoc.txt:218