2013-07-28 22:08:34 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// An expression in our symbolic algebra system, used to write, linearize,
|
|
|
|
// and solve our constraint equations.
|
|
|
|
//
|
|
|
|
// Copyright 2008-2013 Jonathan Westhues.
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-04-08 12:54:53 +00:00
|
|
|
|
|
|
|
#ifndef __EXPR_H
|
|
|
|
#define __EXPR_H
|
|
|
|
|
|
|
|
class Expr;
|
|
|
|
|
|
|
|
class Expr {
|
|
|
|
public:
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t marker;
|
2008-04-21 10:12:04 +00:00
|
|
|
|
2013-09-09 19:50:32 +00:00
|
|
|
enum {
|
|
|
|
// A parameter, by the hParam handle
|
|
|
|
PARAM = 0,
|
|
|
|
// A parameter, by a pointer straight in to the param table (faster,
|
|
|
|
// if we know that the param table won't move around)
|
|
|
|
PARAM_PTR = 1,
|
2008-04-08 12:54:53 +00:00
|
|
|
|
2013-09-09 19:50:32 +00:00
|
|
|
// These are used only for user-entered expressions.
|
|
|
|
POINT = 10,
|
|
|
|
ENTITY = 11,
|
2008-04-12 14:12:26 +00:00
|
|
|
|
2013-09-09 19:50:32 +00:00
|
|
|
CONSTANT = 20,
|
2008-04-12 14:12:26 +00:00
|
|
|
|
2013-09-09 19:50:32 +00:00
|
|
|
PLUS = 100,
|
|
|
|
MINUS = 101,
|
|
|
|
TIMES = 102,
|
|
|
|
DIV = 103,
|
|
|
|
NEGATE = 104,
|
|
|
|
SQRT = 105,
|
|
|
|
SQUARE = 106,
|
|
|
|
SIN = 107,
|
|
|
|
COS = 108,
|
|
|
|
ASIN = 109,
|
|
|
|
ACOS = 110,
|
2008-04-08 12:54:53 +00:00
|
|
|
|
2013-09-09 19:50:32 +00:00
|
|
|
// Special helpers for when we're parsing an expression from text.
|
|
|
|
// Initially, literals (like a constant number) appear in the same
|
|
|
|
// format as they will in the finished expression, but the operators
|
|
|
|
// are different until the parser fixes things up (and builds the
|
|
|
|
// tree from the flat list that the lexer outputs).
|
|
|
|
ALL_RESOLVED = 1000,
|
|
|
|
PAREN = 1001,
|
|
|
|
BINARY_OP = 1002,
|
|
|
|
UNARY_OP = 1003
|
|
|
|
};
|
2008-04-17 06:42:32 +00:00
|
|
|
|
2008-04-08 12:54:53 +00:00
|
|
|
int op;
|
|
|
|
Expr *a;
|
|
|
|
Expr *b;
|
|
|
|
union {
|
2008-04-13 14:28:35 +00:00
|
|
|
double v;
|
2008-04-08 12:54:53 +00:00
|
|
|
hParam parh;
|
2008-04-13 14:28:35 +00:00
|
|
|
Param *parp;
|
2008-04-12 14:12:26 +00:00
|
|
|
hEntity entity;
|
2008-04-17 06:42:32 +00:00
|
|
|
|
|
|
|
// For use while parsing
|
|
|
|
char c;
|
2008-04-08 12:54:53 +00:00
|
|
|
} x;
|
2008-04-13 14:28:35 +00:00
|
|
|
|
2015-10-14 16:26:19 +00:00
|
|
|
Expr() { }
|
|
|
|
Expr(double v) : op(CONSTANT) { x.v = v; }
|
|
|
|
|
2008-04-25 10:11:29 +00:00
|
|
|
static inline Expr *AllocExpr(void)
|
|
|
|
{ return (Expr *)AllocTemporary(sizeof(Expr)); }
|
|
|
|
|
2008-06-01 08:45:11 +00:00
|
|
|
static Expr *From(hParam p);
|
|
|
|
static Expr *From(double v);
|
2008-04-13 14:28:35 +00:00
|
|
|
|
|
|
|
Expr *AnyOp(int op, Expr *b);
|
2013-10-19 05:36:45 +00:00
|
|
|
inline Expr *Plus (Expr *b_) { return AnyOp(PLUS, b_); }
|
|
|
|
inline Expr *Minus(Expr *b_) { return AnyOp(MINUS, b_); }
|
|
|
|
inline Expr *Times(Expr *b_) { return AnyOp(TIMES, b_); }
|
|
|
|
inline Expr *Div (Expr *b_) { return AnyOp(DIV, b_); }
|
2008-04-13 14:28:35 +00:00
|
|
|
|
|
|
|
inline Expr *Negate(void) { return AnyOp(NEGATE, NULL); }
|
|
|
|
inline Expr *Sqrt (void) { return AnyOp(SQRT, NULL); }
|
|
|
|
inline Expr *Square(void) { return AnyOp(SQUARE, NULL); }
|
|
|
|
inline Expr *Sin (void) { return AnyOp(SIN, NULL); }
|
|
|
|
inline Expr *Cos (void) { return AnyOp(COS, NULL); }
|
2009-01-08 17:22:59 +00:00
|
|
|
inline Expr *ASin (void) { return AnyOp(ASIN, NULL); }
|
|
|
|
inline Expr *ACos (void) { return AnyOp(ACOS, NULL); }
|
2008-04-13 14:28:35 +00:00
|
|
|
|
|
|
|
Expr *PartialWrt(hParam p);
|
|
|
|
double Eval(void);
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint64_t ParamsUsed(void);
|
2009-04-19 03:55:46 +00:00
|
|
|
bool DependsOn(hParam p);
|
2008-04-30 04:52:34 +00:00
|
|
|
static bool Tol(double a, double b);
|
|
|
|
Expr *FoldConstants(void);
|
2008-05-07 07:10:20 +00:00
|
|
|
void Substitute(hParam oldh, hParam newh);
|
2008-04-13 14:28:35 +00:00
|
|
|
|
2008-06-26 09:34:26 +00:00
|
|
|
static const hParam NO_PARAMS, MULTIPLE_PARAMS;
|
|
|
|
hParam ReferencedParams(ParamList *pl);
|
|
|
|
|
2008-04-13 14:28:35 +00:00
|
|
|
void ParamsToPointers(void);
|
2008-04-14 10:28:32 +00:00
|
|
|
|
2013-08-26 18:58:35 +00:00
|
|
|
void App(const char *str, ...);
|
|
|
|
const char *Print(void);
|
2008-04-14 10:28:32 +00:00
|
|
|
void PrintW(void); // worker
|
2008-04-17 06:42:32 +00:00
|
|
|
|
2008-04-18 07:06:37 +00:00
|
|
|
// number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+)
|
|
|
|
int Children(void);
|
2008-06-02 03:31:37 +00:00
|
|
|
// total number of nodes in the tree
|
|
|
|
int Nodes(void);
|
2008-04-17 06:42:32 +00:00
|
|
|
|
2008-06-14 08:43:38 +00:00
|
|
|
// Make a simple copy
|
|
|
|
Expr *DeepCopy(void);
|
2008-04-21 08:16:38 +00:00
|
|
|
// Make a copy, with the parameters (usually referenced by hParam)
|
|
|
|
// resolved to pointers to the actual value. This speeds things up
|
|
|
|
// considerably.
|
|
|
|
Expr *DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
|
|
|
|
IdList<Param,hParam> *thenTry);
|
|
|
|
|
2013-09-16 19:51:20 +00:00
|
|
|
static Expr *From(const char *in, bool popUpError);
|
|
|
|
static void Lex(const char *in);
|
2008-04-17 06:42:32 +00:00
|
|
|
static Expr *Next(void);
|
|
|
|
static void Consume(void);
|
|
|
|
|
|
|
|
static void PushOperator(Expr *e);
|
|
|
|
static Expr *PopOperator(void);
|
|
|
|
static Expr *TopOperator(void);
|
|
|
|
static void PushOperand(Expr *e);
|
|
|
|
static Expr *PopOperand(void);
|
|
|
|
|
|
|
|
static void Reduce(void);
|
|
|
|
static void ReduceAndPush(Expr *e);
|
|
|
|
static int Precedence(Expr *e);
|
|
|
|
|
|
|
|
static int Precedence(int op);
|
|
|
|
static void Parse(void);
|
2008-04-08 12:54:53 +00:00
|
|
|
};
|
|
|
|
|
2008-04-22 13:14:15 +00:00
|
|
|
class ExprVector {
|
|
|
|
public:
|
|
|
|
Expr *x, *y, *z;
|
|
|
|
|
2008-06-01 08:45:11 +00:00
|
|
|
static ExprVector From(Expr *x, Expr *y, Expr *z);
|
|
|
|
static ExprVector From(Vector vn);
|
|
|
|
static ExprVector From(hParam x, hParam y, hParam z);
|
2008-06-02 03:31:37 +00:00
|
|
|
static ExprVector From(double x, double y, double z);
|
2008-04-22 13:14:15 +00:00
|
|
|
|
|
|
|
ExprVector Plus(ExprVector b);
|
|
|
|
ExprVector Minus(ExprVector b);
|
|
|
|
Expr *Dot(ExprVector b);
|
2008-04-28 09:40:02 +00:00
|
|
|
ExprVector Cross(ExprVector b);
|
2008-04-22 13:14:15 +00:00
|
|
|
ExprVector ScaledBy(Expr *s);
|
2008-06-06 08:46:55 +00:00
|
|
|
ExprVector WithMagnitude(Expr *s);
|
2008-04-22 13:14:15 +00:00
|
|
|
Expr *Magnitude(void);
|
2008-05-09 05:33:23 +00:00
|
|
|
|
|
|
|
Vector Eval(void);
|
2008-04-22 13:14:15 +00:00
|
|
|
};
|
|
|
|
|
2008-05-05 06:18:01 +00:00
|
|
|
class ExprQuaternion {
|
|
|
|
public:
|
|
|
|
Expr *w, *vx, *vy, *vz;
|
|
|
|
|
2008-06-01 08:45:11 +00:00
|
|
|
static ExprQuaternion From(Expr *w, Expr *vx, Expr *vy, Expr *vz);
|
|
|
|
static ExprQuaternion From(Quaternion qn);
|
2008-06-01 08:57:16 +00:00
|
|
|
static ExprQuaternion From(hParam w, hParam vx, hParam vy, hParam vz);
|
2008-05-05 06:18:01 +00:00
|
|
|
|
|
|
|
ExprVector RotationU(void);
|
|
|
|
ExprVector RotationV(void);
|
2008-05-05 09:47:23 +00:00
|
|
|
ExprVector RotationN(void);
|
2008-05-08 07:30:30 +00:00
|
|
|
|
2008-05-11 06:09:46 +00:00
|
|
|
ExprVector Rotate(ExprVector p);
|
|
|
|
ExprQuaternion Times(ExprQuaternion b);
|
|
|
|
|
2008-05-08 07:30:30 +00:00
|
|
|
Expr *Magnitude(void);
|
2008-05-05 06:18:01 +00:00
|
|
|
};
|
|
|
|
|
2008-04-08 12:54:53 +00:00
|
|
|
#endif
|
2008-05-05 06:18:01 +00:00
|
|
|
|