mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
.examples
git-svn-id: svn://ultimatepp.org/upp/trunk@9434 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
fd862c24a0
commit
42a76739f2
6 changed files with 191 additions and 4 deletions
|
|
@ -5,7 +5,7 @@
|
|||
#include <vector>
|
||||
|
||||
/**
|
||||
* Java simply memory manager.
|
||||
* Java simple memory manager.
|
||||
*/
|
||||
template <class T>
|
||||
class MemoryManager {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
description "Tray application that reminds user to take care about his eyes";
|
||||
description "Tray application that reminds user to take care about his eyes\377";
|
||||
|
||||
uses
|
||||
CtrlLib;
|
||||
|
|
|
|||
12
examples/FnGraph/FnGraph.upp
Normal file
12
examples/FnGraph/FnGraph.upp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
description "Drawing a graph of text expression\377";
|
||||
|
||||
uses
|
||||
CtrlLib,
|
||||
Painter;
|
||||
|
||||
file
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
5
examples/FnGraph/init
Normal file
5
examples/FnGraph/init
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef _FnGraph_icpp_init_stub
|
||||
#define _FnGraph_icpp_init_stub
|
||||
#include "CtrlLib/init"
|
||||
#include "Painter/init"
|
||||
#endif
|
||||
171
examples/FnGraph/main.cpp
Normal file
171
examples/FnGraph/main.cpp
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
#include <Painter/Painter.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
struct ExpressionEvaluator {
|
||||
CParser p; // this will hold our lexical context
|
||||
double x; // 'variable'
|
||||
|
||||
double Factor();
|
||||
double Exponent();
|
||||
double Term();
|
||||
double Expression();
|
||||
};
|
||||
|
||||
double ExpressionEvaluator::Expression()
|
||||
{ // resolve + -
|
||||
double y = Term(); // at least one term
|
||||
for(;;)
|
||||
if(p.Char('+'))
|
||||
y = y + Term(); // add another term
|
||||
else
|
||||
if(p.Char('-'))
|
||||
y = y - Term(); // subtract another term
|
||||
else
|
||||
return x; // no more + - operators
|
||||
}
|
||||
|
||||
double ExpressionEvaluator::Term()
|
||||
{ // resolve * /
|
||||
double y = Exponent(); // at least one member
|
||||
for(;;)
|
||||
if(p.Char('*'))
|
||||
y = y * Exponent(); // multiply by another member
|
||||
else
|
||||
if(p.Char('/'))
|
||||
y = y / Exponent(); // divide by another member
|
||||
else
|
||||
return y; // no more * / operators
|
||||
}
|
||||
|
||||
double ExpressionEvaluator::Exponent()
|
||||
{ // resolve power ^
|
||||
double y = Factor(); // at least one factor
|
||||
for(;;)
|
||||
if(p.Char('^'))
|
||||
y = pow(y, Factor()); // power by another factor
|
||||
else
|
||||
return y; // no more power ^ operators
|
||||
}
|
||||
|
||||
double ExpressionEvaluator::Factor()
|
||||
{
|
||||
if(p.Char('-')) // unary -
|
||||
return -Factor();
|
||||
if(p.Id("abs")) // some functions...
|
||||
return fabs(Factor());
|
||||
if(p.Id("sqrt"))
|
||||
return sqrt(Factor());
|
||||
if(p.Id("ln"))
|
||||
return log(Factor());
|
||||
if(p.Id("log"))
|
||||
return log10(Factor());
|
||||
if(p.Id("log2"))
|
||||
return log2(Factor());
|
||||
if(p.Id("sin"))
|
||||
return sin(Factor());
|
||||
if(p.Id("cos"))
|
||||
return cos(Factor());
|
||||
if(p.Id("tan"))
|
||||
return tan(Factor());
|
||||
if(p.Id("asin"))
|
||||
return asin(Factor());
|
||||
if(p.Id("acos"))
|
||||
return acos(Factor());
|
||||
if(p.Id("atan"))
|
||||
return atan(Factor());
|
||||
if(p.Id("x")) // our variable
|
||||
return x;
|
||||
if(p.Id("e")) // e constant
|
||||
return M_E;
|
||||
if(p.Id("pi")) // pi constant
|
||||
return M_PI;
|
||||
if(p.Char('(')) { // resolve parenthesis - recurse back to Sum (+ - operators)
|
||||
double y = Expression();
|
||||
p.PassChar(')'); // make sure there is closing parenthesis
|
||||
return y;
|
||||
}
|
||||
return p.ReadDouble(); // last possibility is that we are at number...
|
||||
}
|
||||
|
||||
double Evaluate(const char *s, double x)
|
||||
{ // evaluate expression for given variable, return Null on any failure or out-of-bounds result (NaN)
|
||||
ExpressionEvaluator v;
|
||||
v.x = x;
|
||||
v.p.Set(s);
|
||||
try {
|
||||
double y = v.Expression();
|
||||
return y >= -1e200 && y < 1e200 ? y : Null;
|
||||
}
|
||||
catch(CParser::Error) {}
|
||||
return Null;
|
||||
}
|
||||
|
||||
struct FnGraph : public TopWindow {
|
||||
virtual void Paint(Draw& w);
|
||||
|
||||
EditString expression; // function to display
|
||||
|
||||
FnGraph();
|
||||
};
|
||||
|
||||
FnGraph::FnGraph()
|
||||
{
|
||||
Title("Graph of a function");
|
||||
Add(expression.TopPos(0).HSizePos()); // place widget to the top, horizontally fill the window
|
||||
expression << [&] { Refresh(); }; // when expression changes, repaint the graph
|
||||
Sizeable().Zoomable(); // make the window resizable
|
||||
}
|
||||
|
||||
void FnGraph::Paint(Draw& w_)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
DrawPainter w(w_, sz); // Use Painter for smooth sw rendering
|
||||
w.Clear(White()); // clear the background
|
||||
int ecy = expression.GetSize().cy; // query the height of widget
|
||||
w.Offset(0, ecy); // move coordinates out of widget
|
||||
sz.cy -= ecy; // and reduce the size
|
||||
if(sz.cy < 1) // if too small, do nothing (avoid div by zero)
|
||||
return;
|
||||
sz = sz / 2 * 2 - 1; // this trick will force axes to .5, results in sharper AA rendering
|
||||
double pixels_per_unit = sz.cy / 9; // we want to display y range -4.5 .. 4.5
|
||||
double xaxis = sz.cy / 2.0; // vertical position of x axis
|
||||
double yaxis = sz.cx / 2.0; // horizontal position of y axis
|
||||
w.Move(0, xaxis).Line(sz.cx, xaxis).Stroke(1, Blue()); // draw x axis
|
||||
w.Move(yaxis, 0).Line(yaxis, sz.cy).Stroke(1, Blue()); // draw y axis
|
||||
Font font = Serif(15);
|
||||
if(pixels_per_unit > 20) // if big enough, paint some axis markers and numbers...
|
||||
for(int i = 1; i < 2 * sz.cx / pixels_per_unit; i++)
|
||||
for(int sgn = -1; sgn < 2; sgn += 2) {
|
||||
String n = AsString(sgn * i);
|
||||
Size tsz = GetTextSize(n, font);
|
||||
|
||||
double x = yaxis + sgn * i * pixels_per_unit;
|
||||
w.Move(x, xaxis - 5).Line(x, xaxis + 5).Stroke(1, Blue());
|
||||
w.Text(int(x - tsz.cx / 2.0), int(xaxis + 6), n, font).Fill(Blue());
|
||||
|
||||
double y = xaxis - sgn * i * pixels_per_unit;
|
||||
w.Move(yaxis - 5, y).Line(yaxis + 5, y).Stroke(1, Blue());
|
||||
w.Text(int(yaxis + 6), int(y - tsz.cy / 2.0), n, font).Fill(Blue());
|
||||
}
|
||||
double y0 = Null; // store previous value
|
||||
for(int i = 0; i < sz.cx; i++) { // now iterate through all x pointes and draw the graph
|
||||
double x = (i - sz.cx / 2.0) / pixels_per_unit;
|
||||
double y = Evaluate(~~expression, x);
|
||||
if(!IsNull(y)) {
|
||||
double gy = sz.cy / 2.0 - y * pixels_per_unit;
|
||||
if(IsNull(y0)) // previous value was defined
|
||||
w.Move(i, gy);
|
||||
else
|
||||
w.Line(i, gy);
|
||||
}
|
||||
y0 = y;
|
||||
}
|
||||
w.Stroke(1, Black()); // finally paint the graph line
|
||||
}
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
FnGraph().Run();
|
||||
}
|
||||
|
|
@ -11,6 +11,5 @@ file
|
|||
UWord.iml;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI",
|
||||
"" = "GUI .NOGTK";
|
||||
"" = "GUI";
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue