該軟件用于將數(shù)學表達式以圖形的形式顯示出來.軟件中定義一套簡單易學的腳本語言,用于描述數(shù)學表達式.使用時需要先要將數(shù)學表達式寫成該腳本的形式,解析腳本代碼以生成相應(yīng)的圖形.能夠生成曲線圖形和曲面圖形. 目前只能處理顯示表達式.
軟件介紹
(1)主界面
在文件夾” MathScript”中,提供了500個以上已經(jīng)寫好的數(shù)學表達式腳本文件.將數(shù)學腳本文件拖入到主界面中,即顯示其圖形.亦可以通過菜單項打開腳本文件.
如果圖形是一個3D圖形,那么軟件會自動為你切換到3D顯示模式.使用鼠標右鍵拖動,以旋轉(zhuǎn)視角.鍵盤上的WSAD,QERF,上下左右也對視角進行控制.這個不細講了,用戶自己去體驗吧.如果圖形是一個2D圖形,打開時為二維顯示模式,用戶可以按下鍵盤上的’O’鍵,在3D,2D間進行切換.鼠標滾輪可以對視口進行縮放.
下圖為一個二維的視圖:
按下鍵盤上的’U’鍵,會在左邊顯示一套UI控件:
用于對一些顯示屬性的操作.可惜我的引擎目前不支持中文字體,所以先將就著用吧.
按下鍵盤上的’0’鍵,會在右邊顯示一個紋理選擇控件,用于設(shè)置數(shù)學曲面的紋理:
UI面板上的也可以控制紋理選擇控件.
紋理文件存放在” Texture”文件夾下,用戶可以將自己喜歡的圖像文件放入其中.軟件會自動為你加載.用戶亦可以直接將圖像文件拖入到主界面中.對圖像格式的支持包括: dds,bmp,jpg,png,gif,tga.
當打開一個數(shù)學圖形后,按下鍵盤上的’7’鍵,會顯示一個滑動條控件,用于控制所顯示的圖形范圍. 控件
也可以.滑動條上有兩個滑塊,分別表示其顯示范圍的最小與最大,如下圖:黃線處為顯的區(qū)域,綠線處為未顯示的區(qū)域.
最小滑塊與最大滑塊可以錯開:
下圖為對曲面圖形的操作
下圖為對曲線圖形的操作:
當打開一個數(shù)學曲面圖形后, 按下鍵盤上的’P’鍵或點下會在右下角顯示兩個對曲面上曲線進行操作的控件.
如下圖所展示:
圖中綠色曲線為第一維度的曲線,紅色曲線為第二維度的曲線.
代碼與自定義擴展
MathExpression模塊中為數(shù)學表達式及腳本解析的代碼邏輯.
(1)主要接口
文件”math_expression_parser.h”提供了對表達式的解析函數(shù)
// 設(shè)置參數(shù)值
void SetParameterValue(char c, float value);
// 清空參數(shù)值
void ClearParameterValues();
// 表達式解析
bool ParseExpression(const char* szExpression, float& rst);
// 括號內(nèi)的子表達式解析
bool ParseBracketExpression(const char* szExpression,
unsigned int& pos, float& rst,
unsigned int bracketIndex, bool endComma);
可以針求獨立表達式的結(jié)果,如:
bool sus = ParseExpression(“sin(PI*3) + 10*E*log(100)”, rst);
文件”math_script_parser.h”提供了一個對象MathScriptParser,用于對數(shù)學腳本的解析
class MathScriptParser
{
public:
...
// 加載腳本文件
bool LoadFile(const char* szFile);
// 處理內(nèi)存數(shù)據(jù)
bool ProcessMemory(const char* bufPtr, unsigned int bufSize);
...
};
(2)添加或設(shè)置常量值
開發(fā)者可以通過”const_value.h”文件中的如下函數(shù)對常量進行添加或修改
// 添加或設(shè)置常量值
bool SetConstValue(const char* szName, float value);
(3)添加或設(shè)置函數(shù)運算符
程序中的運算符操作是以函數(shù)指針的方式使用,開發(fā)者可以將自己實現(xiàn)的函數(shù)設(shè)置到系統(tǒng)中.
有6種運算符函數(shù)類型
// 單目運算函數(shù)
typedef float (*SINGLE_OPERATOR_FUNC)(float);
// 雙目運算函數(shù)
typedef float (*TWIN_OPERATOR_FUNC)(float, float);
// 三目運算函數(shù)
typedef float (*THREE_OPERATOR_FUNC)(float, float, float);
// 四目運算函數(shù)
typedef float (*FOUR_OPERATOR_FUNC)(float, float, float, float);
// 對ValueNode的運算函數(shù)(輸入ValueNode,輸出一個浮點數(shù))
typedef float (*VALUENODE_TO_FLOAT_OPERATOR_FUNC)(const ValueNode*);
// 對ValueNode的運算函數(shù)(輸入ValueNode,輸出ValueNode)
typedef void (*VALUENODE_CONVERT_OPERATOR_FUNC)(const ValueNode*, ValueNode*);
開發(fā)者可自定義運算函數(shù)后,使用如下接口,將其添加到系統(tǒng)中.
// 添加或設(shè)置運算函數(shù)
bool SetSingleOperator(const char* szName, SINGLE_OPERATOR_FUNC func);
bool SetTwinOperator(const char* szName, TWIN_OPERATOR_FUNC func);
bool SetThreeOperator(const char* szName, THREE_OPERATOR_FUNC func);
bool SetFourOperator(const char* szName, FOUR_OPERATOR_FUNC func);
bool SetValueNodeToFloatOperator(const char* szName, VALUENODE_TO_FLOAT_OPERATOR_FUNC func);
bool SetValueNodeConvertOperator2(const char* szName, VALUENODE_CONVERT_OPERATOR_FUNC func);
需要注意這兩個宏:
#define OPERATOR_NAME_LENGTH 24 // 操作符名的最大長度
#define MAX_FUNCTIONS_COUNT 256 // 運算函數(shù)的最大數(shù)目
如果不滿足要求,請自己修改這兩個宏值
代碼中的Integraller模塊為額外添加的數(shù)學函數(shù).
在文件MathGraph.cpp中將額外的數(shù)學函數(shù)注冊到系統(tǒng)中:
void CMathGraph::SetupIntergralFunctions()
{
Why::SetTwinOperator("Trapezia", TestTrapezia);
Why::SetTwinOperator("Simpson", TestSimpson);
Why::SetTwinOperator("ATrapezia", TestATrapezia);
Why::SetTwinOperator("Romberg", TestRomberg);
Why::SetTwinOperator("ValuePq", TestValuePq);
Why::SetTwinOperator("LegdGauss", TestLegdGauss);
Why::SetSingleOperator("Gamma", YfGamma);
Why::SetTwinOperator("Gamma2", YfGamma2);
Why::SetSingleOperator("Erf", YfErf);
Why::SetThreeOperator("Beta", YfBeta);
Why::SetThreeOperator("Gass", YfGass);
Why::SetTwinOperator("Student", YfStudent);
Why::SetTwinOperator("Chii", YfChii);
Why::SetThreeOperator("Fdisp", YfFdisp);
Why::SetSingleOperator("Sinn", YfSinn);
Why::SetSingleOperator("Coss", YfCoss);
Why::SetSingleOperator("Expp", YfExpp);
}