summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-06-30 18:05:10 (GMT)
committerclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-06-30 18:05:10 (GMT)
commit78244d328918b149b86d9b925010e934244d0137 (patch)
tree54228d6e3480fc309143a4ed3d9deb0d51994f56
parenta70715ab8c31160f1be2a74d208681c2ad422bbb (diff)
Clifford Wolf:
Improved value handling Fixed math functions Improved control statements git-svn-id: http://svn.clifford.at/openscad/trunk@39 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r--control.cc38
-rw-r--r--example.scad19
-rw-r--r--expr.cc67
-rw-r--r--func.cc34
-rw-r--r--mainwin.cc1
-rw-r--r--openscad.h18
-rw-r--r--parser.y86
-rw-r--r--primitives.cc35
-rw-r--r--transform.cc44
-rw-r--r--value.cc176
10 files changed, 273 insertions, 245 deletions
diff --git a/control.cc b/control.cc
index bfada90..8c073da 100644
--- a/control.cc
+++ b/control.cc
@@ -23,6 +23,7 @@
#include "openscad.h"
enum control_type_e {
+ ECHO,
ASSIGN,
FOR,
IF
@@ -43,9 +44,24 @@ void for_eval(AbstractNode *node, int l, const QVector<QString> &call_argnames,
Value it_values = call_argvalues[l];
Context c(arg_context);
if (it_values.type == Value::RANGE) {
- for (double i = it_values.r_begin; i <= it_values.r_end; i += it_values.r_step) {
- fprintf(stderr, "%f\n", i);
- c.set_variable(it_name, Value(i));
+ double range_begin = it_values.range_begin;
+ double range_end = it_values.range_end;
+ double range_step = it_values.range_step;
+ if (range_end < range_begin) {
+ double t = range_begin;
+ range_begin = range_end;
+ range_end = t;
+ }
+ if (range_step > 0 && (range_begin-range_end)/range_step < 10000) {
+ for (double i = range_begin; i <= range_end; i += range_step) {
+ c.set_variable(it_name, Value(i));
+ for_eval(node, l+1, call_argnames, call_argvalues, arg_children, &c);
+ }
+ }
+ }
+ else if (it_values.type == Value::VECTOR) {
+ for (int i = 0; i < it_values.vec.size(); i++) {
+ c.set_variable(it_name, *it_values.vec[i]);
for_eval(node, l+1, call_argnames, call_argvalues, arg_children, &c);
}
}
@@ -65,6 +81,19 @@ AbstractNode *ControlModule::evaluate(const Context*, const QVector<QString> &ca
{
AbstractNode *node = new AbstractNode();
+ if (type == ECHO)
+ {
+ QString msg = QString("ECHO: ");
+ for (int i = 0; i < call_argnames.size(); i++) {
+ if (i > 0)
+ msg += QString(", ");
+ if (!call_argnames[i].isEmpty())
+ msg += call_argnames[i] + QString(" = ");
+ msg += call_argvalues[i].dump();
+ }
+ PRINT(msg);
+ }
+
if (type == ASSIGN)
{
Context c(arg_context);
@@ -99,8 +128,9 @@ AbstractNode *ControlModule::evaluate(const Context*, const QVector<QString> &ca
void register_builtin_control()
{
+ builtin_modules["echo"] = new ControlModule(ECHO);
builtin_modules["assign"] = new ControlModule(ASSIGN);
- // builtin_modules["for"] = new ControlModule(FOR);
+ builtin_modules["for"] = new ControlModule(FOR);
builtin_modules["if"] = new ControlModule(IF);
}
diff --git a/example.scad b/example.scad
index 7df8277..c55798a 100644
--- a/example.scad
+++ b/example.scad
@@ -66,4 +66,23 @@ module test004()
}
}
+module test005()
+{
+ translate([0 0 -120]) {
+ difference() {
+ cylinder(h = 50, r = 100);
+ translate([0 0 10]) cylinder(h = 50, r = 80);
+ translate([100 0 35]) cube(50, center = true);
+ }
+ for (i = [0:5]) {
+ echo(360*i/6, sin(360*i/6)*80, cos(360*i/6)*80);
+ translate([sin(360*i/6)*80, cos(360*i/6)*80, 0 ])
+ cylinder(h = 200, r=10);
+ }
+ translate([0 0 200])
+ cylinder(h = 80, r1 = 120, r2 = 0);
+ }
+}
+
test001();
+
diff --git a/expr.cc b/expr.cc
index 0706d33..cefa3b9 100644
--- a/expr.cc
+++ b/expr.cc
@@ -23,12 +23,15 @@
Expression::Expression()
{
type = 0;
+ const_value = NULL;
}
Expression::~Expression()
{
for (int i=0; i < children.size(); i++)
delete children[i];
+ if (const_value)
+ delete const_value;
}
Value Expression::evaluate(const Context *context) const
@@ -55,7 +58,7 @@ Value Expression::evaluate(const Context *context) const
case 'I':
return children[0]->evaluate(context).inv();
case 'C':
- return const_value;
+ return *const_value;
case 'R':
{
Value v1 = children[0]->evaluate(context);
@@ -64,32 +67,20 @@ Value Expression::evaluate(const Context *context) const
if (v1.type == Value::NUMBER && v2.type == Value::NUMBER && v3.type == Value::NUMBER) {
Value r = Value();
r.type = Value::RANGE;
- r.r_begin = v1.num;
- r.r_step = v2.num;
- r.r_end = v3.num;
+ r.range_begin = v1.num;
+ r.range_step = v2.num;
+ r.range_end = v3.num;
return r;
}
return Value();
}
case 'V':
{
- Value v1 = children[0]->evaluate(context);
- Value v2 = children[1]->evaluate(context);
- Value v3 = children[2]->evaluate(context);
- if (v1.type == Value::NUMBER && v2.type == Value::NUMBER && v3.type == Value::NUMBER)
- return Value(v1.num, v2.num, v3.num);
- return Value();
- }
- case 'M':
- {
- double m[16];
- for (int i=0; i<16; i++) {
- Value v = children[i]->evaluate(context);
- if (v.type != Value::NUMBER)
- return Value();
- m[i == 15 ? 15 : (i*4) % 15] = v.num;
- }
- return Value(m);
+ Value v;
+ v.type = Value::VECTOR;
+ for (int i = 0; i < children.size(); i++)
+ v.vec.append(new Value(children[i]->evaluate(context)));
+ return v;
}
case 'L':
return context->lookup_variable(var_name);
@@ -98,25 +89,18 @@ Value Expression::evaluate(const Context *context) const
Value v = children[0]->evaluate(context);
if (v.type == Value::VECTOR && var_name == QString("x"))
- return Value(v.x);
+ return *v.vec[0];
if (v.type == Value::VECTOR && var_name == QString("y"))
- return Value(v.y);
+ return *v.vec[1];
if (v.type == Value::VECTOR && var_name == QString("z"))
- return Value(v.z);
+ return *v.vec[2];
if (v.type == Value::RANGE && var_name == QString("begin"))
- return Value(v.r_begin);
+ return Value(v.range_begin);
if (v.type == Value::RANGE && var_name == QString("step"))
- return Value(v.r_step);
+ return Value(v.range_step);
if (v.type == Value::RANGE && var_name == QString("end"))
- return Value(v.r_end);
-
- for (int i=0; i<16; i++) {
- QString n;
- n.sprintf("m%d", i+1);
- if (v.type == Value::MATRIX && var_name == n)
- return Value(v.m[i]);
- }
+ return Value(v.range_end);
return Value();
}
@@ -147,24 +131,11 @@ QString Expression::dump() const
case 'I':
return QString("(-%1)").arg(children[0]->dump());
case 'C':
- return const_value.dump();
+ return const_value->dump();
case 'R':
return QString("[%1 : %2 : %3]").arg(children[0]->dump(), children[1]->dump(), children[2]->dump());
case 'V':
return QString("[%1, %2, %3]").arg(children[0]->dump(), children[1]->dump(), children[2]->dump());
- case 'M':
- {
- QString text = "[";
- for (int i = 0; i < 16; i++) {
- if (i % 4 == 0 && i > 0)
- text += ";";
- if (i > 0)
- text += " ";
- text += children[i]->dump();
- }
- text += "]";
- return text;
- }
case 'L':
return var_name;
case 'N':
diff --git a/func.cc b/func.cc
index fff9080..07171b6 100644
--- a/func.cc
+++ b/func.cc
@@ -80,52 +80,72 @@ QString BuiltinFunction::dump(QString indent, QString name) const
return QString("%1builtin function %2();\n").arg(indent, name);
}
+static double deg2rad(double x)
+{
+ while (x < 0.0)
+ x += 360.0;
+ while (x >= 360.0)
+ x -= 360.0;
+ x = x * M_PI * 2.0 / 360.0;
+ return x;
+}
+
+static double rad2deg(double x)
+{
+ x = x * 360.0 / (M_PI * 2.0);
+ while (x < 0.0)
+ x += 360.0;
+ while (x >= 360.0)
+ x -= 360.0;
+ return x;
+}
+
Value builtin_sin(const QVector<Value> &args)
{
if (args[0].type == Value::NUMBER)
- Value(sin(args[0].num));
+ return Value(sin(deg2rad(args[0].num)));
return Value();
}
Value builtin_cos(const QVector<Value> &args)
{
if (args[0].type == Value::NUMBER)
- Value(cos(args[0].num));
+ return Value(cos(deg2rad(args[0].num)));
return Value();
}
Value builtin_asin(const QVector<Value> &args)
{
if (args[0].type == Value::NUMBER)
- Value(asin(args[0].num));
+ return Value(rad2deg(asin(args[0].num)));
return Value();
}
Value builtin_acos(const QVector<Value> &args)
{
if (args[0].type == Value::NUMBER)
- Value(acos(args[0].num));
+ return Value(rad2deg(acos(args[0].num)));
return Value();
}
Value builtin_tan(const QVector<Value> &args)
{
if (args[0].type == Value::NUMBER)
- Value(tan(args[0].num));
+ return Value(tan(deg2rad(args[0].num)));
return Value();
}
Value builtin_atan(const QVector<Value> &args)
{
if (args[0].type == Value::NUMBER)
- Value(atan(args[0].num));
+ return Value(rad2deg(atan(args[0].num)));
return Value();
}
Value builtin_atan2(const QVector<Value> &args)
{
if (args[0].type == Value::NUMBER && args[1].type == Value::NUMBER)
- Value(atan2(args[0].num, args[1].num));
+ return Value(rad2deg(atan2(args[0].num, args[1].num)));
return Value();
}
diff --git a/mainwin.cc b/mainwin.cc
index d180d9f..44c1ebd 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -35,6 +35,7 @@ MainWindow::MainWindow(const char *filename)
{
root_ctx.functions_p = &builtin_functions;
root_ctx.modules_p = &builtin_modules;
+ root_ctx.set_variable("$fn", Value(0.0));
root_ctx.set_variable("$fs", Value(1.0));
root_ctx.set_variable("$fa", Value(12.0));
diff --git a/openscad.h b/openscad.h
index 0a8fa5c..e4330a3 100644
--- a/openscad.h
+++ b/openscad.h
@@ -88,18 +88,17 @@ public:
bool b;
double num;
- double x, y, z;
- double r_begin;
- double r_step;
- double r_end;
- double m[16];
+ QVector<Value*> vec;
+ double range_begin;
+ double range_step;
+ double range_end;
QString text;
Value();
+ ~Value();
+
Value(bool v);
Value(double v);
- Value(double v1, double v2, double v3);
- Value(double m[16]);
Value(const QString &t);
Value(const Value &v);
@@ -112,6 +111,9 @@ public:
Value operator % (const Value &v) const;
Value inv() const;
+ bool getnum(double &v) const;
+ bool getv3(double &x, double &y, double &z) const;
+
QString dump() const;
private:
@@ -123,7 +125,7 @@ class Expression
public:
QVector<Expression*> children;
- Value const_value;
+ Value *const_value;
QString var_name;
QString call_funcname;
diff --git a/parser.y b/parser.y
index 1a65c37..d9fce18 100644
--- a/parser.y
+++ b/parser.y
@@ -48,6 +48,7 @@ public:
%union {
char *text;
double number;
+ class Value *value;
class Expression *expr;
class ModuleInstanciation *inst;
class ArgContainer *arg;
@@ -70,6 +71,8 @@ public:
%left '.'
%type <expr> expr
+%type <value> vector_const
+%type <expr> vector_expr
%type <inst> module_instantciation
%type <inst> module_instantciation_list
@@ -171,17 +174,17 @@ expr:
TOK_TRUE {
$$ = new Expression();
$$->type = 'C';
- $$->const_value = Value(true);
+ $$->const_value = new Value(true);
} |
TOK_FALSE {
$$ = new Expression();
$$->type = 'C';
- $$->const_value = Value(false);
+ $$->const_value = new Value(false);
} |
TOK_UNDEF {
$$ = new Expression();
$$->type = 'C';
- $$->const_value = Value();
+ $$->const_value = new Value();
} |
TOK_ID {
$$ = new Expression();
@@ -199,18 +202,18 @@ expr:
TOK_STRING {
$$ = new Expression();
$$->type = 'C';
- $$->const_value = Value(QString($1));
+ $$->const_value = new Value(QString($1));
free($1);
} |
TOK_NUMBER {
$$ = new Expression();
$$->type = 'C';
- $$->const_value = Value($1);
+ $$->const_value = new Value($1);
} |
'[' expr ':' expr ']' {
Expression *e_one = new Expression();
e_one->type = 'C';
- e_one->const_value = Value(1.0);
+ e_one->const_value = new Value(1.0);
$$ = new Expression();
$$->type = 'R';
$$->children.append($2);
@@ -224,54 +227,19 @@ expr:
$$->children.append($4);
$$->children.append($6);
} |
- '[' TOK_NUMBER TOK_NUMBER TOK_NUMBER ']' {
+ '[' ']' {
$$ = new Expression();
$$->type = 'C';
- $$->const_value = Value($2, $3, $4);
+ $$->const_value = new Value();
+ $$->const_value->type = Value::VECTOR;
} |
- '[' TOK_NUMBER TOK_NUMBER TOK_NUMBER TOK_NUMBER ';'
- TOK_NUMBER TOK_NUMBER TOK_NUMBER TOK_NUMBER ';'
- TOK_NUMBER TOK_NUMBER TOK_NUMBER TOK_NUMBER ';'
- TOK_NUMBER TOK_NUMBER TOK_NUMBER TOK_NUMBER ']' {
+ '[' vector_const ']' {
$$ = new Expression();
$$->type = 'C';
- double m[16] = {
- $2, $3, $4, $5,
- $7, $8, $9, $10,
- $12, $13, $14, $15,
- $17, $18, $19, $20,
- };
- $$->const_value = Value(m);
- } |
- '[' expr ',' expr ',' expr ']' {
- $$ = new Expression();
- $$->type = 'V';
- $$->children.append($2);
- $$->children.append($4);
- $$->children.append($6);
+ $$->const_value = $2;
} |
- '[' expr ',' expr ',' expr ',' expr ';'
- expr ',' expr ',' expr ',' expr ';'
- expr ',' expr ',' expr ',' expr ';'
- expr ',' expr ',' expr ',' expr ']' {
- $$ = new Expression();
- $$->type = 'M';
- $$->children.append($2);
- $$->children.append($4);
- $$->children.append($6);
- $$->children.append($8);
- $$->children.append($10);
- $$->children.append($12);
- $$->children.append($14);
- $$->children.append($16);
- $$->children.append($18);
- $$->children.append($20);
- $$->children.append($22);
- $$->children.append($24);
- $$->children.append($26);
- $$->children.append($28);
- $$->children.append($30);
- $$->children.append($32);
+ '[' vector_expr ']' {
+ $$ = $2;
} |
expr '*' expr {
$$ = new Expression();
@@ -331,6 +299,28 @@ expr:
delete $3;
} ;
+vector_const:
+ TOK_NUMBER {
+ $$ = new Value();
+ $$->type = Value::VECTOR;
+ $$->vec.append(new Value($1));
+ } |
+ vector_const TOK_NUMBER {
+ $$ = $1;
+ $$->vec.append(new Value($2));
+ } ;
+
+vector_expr:
+ expr {
+ $$ = new Expression();
+ $$->type = 'V';
+ $$->children.append($1);
+ } |
+ vector_expr ',' expr {
+ $$ = $1;
+ $$->children.append($3);
+ } ;
+
arguments_decl:
/* empty */ {
$$ = new ArgsContainer();
diff --git a/primitives.cc b/primitives.cc
index 59c5938..ae43a58 100644
--- a/primitives.cc
+++ b/primitives.cc
@@ -41,7 +41,7 @@ class PrimitiveNode : public AbstractPolyNode
public:
bool center;
double x, y, z, h, r1, r2;
- double fs, fa;
+ double fn, fs, fa;
primitive_type_e type;
PrimitiveNode(primitive_type_e type) : type(type) { }
virtual PolySet *render_polyset(render_mode_e mode) const;
@@ -71,22 +71,17 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector<QStrin
Context c(ctx);
c.args(argnames, argexpr, call_argnames, call_argvalues);
+ node->fn = c.lookup_variable("$fn").num;
node->fs = c.lookup_variable("$fs").num;
node->fa = c.lookup_variable("$fa").num;
if (type == CUBE) {
Value size = c.lookup_variable("size");
Value center = c.lookup_variable("center");
- if (size.type == Value::VECTOR) {
- node->x = size.x;
- node->y = size.y;
- node->z = size.z;
- }
- if (size.type == Value::NUMBER) {
- node->x = size.num;
- node->y = size.num;
- node->z = size.num;
- }
+ size.getnum(node->x);
+ size.getnum(node->y);
+ size.getnum(node->z);
+ size.getv3(node->x, node->y, node->z);
if (center.type == Value::BOOL) {
node->center = center.b;
}
@@ -101,9 +96,11 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector<QStrin
if (type == CYLINDER) {
Value h = c.lookup_variable("h");
- Value r = c.lookup_variable("r");
- Value r1 = c.lookup_variable("r1");
- Value r2 = c.lookup_variable("r2");
+ Value r, r1, r2;
+ r1 = c.lookup_variable("r1");
+ r2 = c.lookup_variable("r2");
+ if (r1.type != Value::NUMBER && r1.type != Value::NUMBER)
+ r = c.lookup_variable("r");
Value center = c.lookup_variable("center");
if (h.type == Value::NUMBER) {
node->h = h.num;
@@ -133,8 +130,10 @@ void register_builtin_primitives()
builtin_modules["cylinder"] = new PrimitiveModule(CYLINDER);
}
-int get_fragments_from_r(double r, double fs, double fa)
+int get_fragments_from_r(double r, double fn, double fs, double fa)
{
+ if (fn > 0.0)
+ return fn;
return (int)ceil(fmax(fmin(360.0 / fa, r*M_PI / fs), 5));
}
@@ -208,14 +207,14 @@ PolySet *PrimitiveNode::render_polyset(render_mode_e) const
double r, z;
};
- int rings = get_fragments_from_r(r1, fs, fa);
+ int rings = get_fragments_from_r(r1, fn, fs, fa);
ring_s ring[rings];
for (int i = 0; i < rings; i++) {
double phi = (M_PI * (i + 0.5)) / rings;
ring[i].r = r1 * sin(phi);
ring[i].z = r1 * cos(phi);
- ring[i].fragments = get_fragments_from_r(ring[i].r, fs, fa);
+ ring[i].fragments = get_fragments_from_r(ring[i].r, fn, fs, fa);
ring[i].points = new point2d[ring[i].fragments];
for (int j = 0; j < ring[i].fragments; j++) {
phi = (M_PI*2*j) / ring[i].fragments;
@@ -267,7 +266,7 @@ sphere_next_r2:
if (type == CYLINDER && h > 0 && r1 >=0 && r2 >= 0 && (r1 > 0 || r2 > 0))
{
- int fragments = get_fragments_from_r(fmax(r1, r2), fs, fa);
+ int fragments = get_fragments_from_r(fmax(r1, r2), fn, fs, fa);
double z1, z2;
if (center) {
diff --git a/transform.cc b/transform.cc
index de29aaf..6c73993 100644
--- a/transform.cc
+++ b/transform.cc
@@ -78,16 +78,10 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QStrin
if (type == SCALE)
{
Value v = c.lookup_variable("v");
- if (v.type == Value::NUMBER) {
- node->m[0] = v.num;
- node->m[5] = v.num;
- node->m[10] = v.num;
- }
- if (v.type == Value::VECTOR) {
- node->m[0] = v.x;
- node->m[5] = v.y;
- node->m[10] = v.z;
- }
+ v.getnum(node->m[0]);
+ v.getnum(node->m[5]);
+ v.getnum(node->m[10]);
+ v.getv3(node->m[0], node->m[5], node->m[10]);
}
if (type == ROTATE)
{
@@ -95,15 +89,14 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QStrin
Value val_v = c.lookup_variable("v");
double a = 0, x = 0, y = 0, z = 1;
- if (val_a.type == Value::NUMBER) {
- a = val_a.num;
- }
+ val_a.getnum(a);
- if (val_v.type == Value::VECTOR) {
- if (val_v.x != 0.0 || val_v.y != 0.0 || val_v.z != 0.0) {
- x = val_v.x; y = val_v.y; z = val_v.z;
+ if (val_v.getv3(x, y, z)) {
+ if (x != 0.0 || y != 0.0 || z != 0.0) {
double sn = 1.0 / sqrt(x*x + y*y + z*z);
- x *= sn; y *= sn; z *= sn;
+ x *= sn, y *= sn, z *= sn;
+ } else {
+ x = 0, y = 0, z = 1;
}
}
@@ -125,18 +118,17 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QStrin
if (type == TRANSLATE)
{
Value v = c.lookup_variable("v");
- if (v.type == Value::VECTOR) {
- node->m[12] = v.x;
- node->m[13] = v.y;
- node->m[14] = v.z;
- }
+ v.getv3(node->m[12], node->m[13], node->m[14]);
}
if (type == MULTMATRIX)
{
Value v = c.lookup_variable("m");
- if (v.type == Value::MATRIX) {
- for (int i = 0; i < 16; i++)
- node->m[i] = v.m[i];
+ if (v.type == Value::VECTOR) {
+ for (int i = 0; i < 16; i++) {
+ int x = i / 4, y = i % 4;
+ if (y < v.vec.size() && v.vec[y]->type == Value::VECTOR && x < v.vec[y]->vec.size())
+ v.vec[y]->vec[x]->getnum(node->m[i]);
+ }
}
}
@@ -196,7 +188,7 @@ CSGTerm *TransformNode::render_csg_term(double c[16]) const
QString TransformNode::dump(QString indent) const
{
QString text;
- text.sprintf("n%d: multmatrix([%f %f %f %f; %f %f %f %f; %f %f %f %f; %f %f %f %f])", idx,
+ text.sprintf("n%d: multmatrix([[%f %f %f %f], [%f %f %f %f], [%f %f %f %f], [%f %f %f %f]])", idx,
m[0], m[4], m[ 8], m[12],
m[1], m[5], m[ 9], m[13],
m[2], m[6], m[10], m[14],
diff --git a/value.cc b/value.cc
index 4adff51..0eeec36 100644
--- a/value.cc
+++ b/value.cc
@@ -25,6 +25,13 @@ Value::Value()
reset_undef();
}
+Value::~Value()
+{
+ for (int i = 0; i < vec.size(); i++)
+ delete vec[i];
+ vec.clear();
+}
+
Value::Value(bool v)
{
reset_undef();
@@ -39,23 +46,6 @@ Value::Value(double v)
num = v;
}
-Value::Value(double v1, double v2, double v3)
-{
- reset_undef();
- type = VECTOR;
- x = v1;
- y = v2;
- z = v3;
-}
-
-Value::Value(double m[16])
-{
- reset_undef();
- type = MATRIX;
- for (int i=0; i<16; i++)
- this->m[i] = m[i];
-}
-
Value::Value(const QString &t)
{
reset_undef();
@@ -65,16 +55,7 @@ Value::Value(const QString &t)
Value::Value(const Value &v)
{
- reset_undef();
- type = v.type;
- b = v.b;
- num = v.num;
- x = v.x;
- y = v.y;
- z = v.z;
- for (int i=0; i<16; i++)
- m[i] = v.m[i];
- text = v.text;
+ *this = v;
}
Value& Value::operator = (const Value &v)
@@ -83,11 +64,11 @@ Value& Value::operator = (const Value &v)
type = v.type;
b = v.b;
num = v.num;
- x = v.x;
- y = v.y;
- z = v.z;
- for (int i=0; i<16; i++)
- m[i] = v.m[i];
+ for (int i = 0; i < v.vec.size(); i++)
+ vec.append(new Value(*v.vec[i]));
+ range_begin = v.range_begin;
+ range_step = v.range_step;
+ range_end = v.range_end;
text = v.text;
return *this;
}
@@ -95,13 +76,11 @@ Value& Value::operator = (const Value &v)
Value Value::operator + (const Value &v) const
{
if (type == VECTOR && v.type == VECTOR) {
- return Value(x + v.x, y + v.y, z + v.z);
- }
- if (type == MATRIX && v.type == MATRIX) {
- double m_[16];
- for (int i=0; i<16; i++)
- m_[i] = m[i] + v.m[i];
- return Value(m);
+ Value r;
+ r.type = VECTOR;
+ for (int i = 0; i < vec.size() && i < v.vec.size(); i++)
+ r.vec.append(new Value(*vec[i] + *v.vec[i]));
+ return r;
}
if (type == NUMBER && v.type == NUMBER) {
return Value(num + v.num);
@@ -112,13 +91,11 @@ Value Value::operator + (const Value &v) const
Value Value::operator - (const Value &v) const
{
if (type == VECTOR && v.type == VECTOR) {
- return Value(x + v.x, y + v.y, z + v.z);
- }
- if (type == MATRIX && v.type == MATRIX) {
- double m_[16];
- for (int i=0; i<16; i++)
- m_[i] = m[i] + v.m[i];
- return Value(m);
+ Value r;
+ r.type = VECTOR;
+ for (int i = 0; i < vec.size() && i < v.vec.size(); i++)
+ r.vec.append(new Value(*vec[i] - *v.vec[i]));
+ return r;
}
if (type == NUMBER && v.type == NUMBER) {
return Value(num + v.num);
@@ -128,17 +105,19 @@ Value Value::operator - (const Value &v) const
Value Value::operator * (const Value &v) const
{
- if (type == VECTOR && v.type == VECTOR) {
- double nx = (y-v.y)*(z-v.z) - (z-v.z)*(y-v.y);
- double ny = (z-v.z)*(x-v.x) - (x-v.x)*(z-v.z);
- double nz = (x-v.x)*(y-v.y) - (y-v.y)*(x-v.x);
- return Value(nx, ny, nz);
- }
if (type == VECTOR && v.type == NUMBER) {
- return Value(x * v.num, y * v.num, z * v.num);
+ Value r;
+ r.type = VECTOR;
+ for (int i = 0; i < vec.size(); i++)
+ r.vec.append(new Value(*vec[i] * v));
+ return r;
}
if (type == NUMBER && v.type == VECTOR) {
- return Value(num * v.x, num * v.y, num * v.z);
+ Value r;
+ r.type = VECTOR;
+ for (int i = 0; i < v.vec.size(); i++)
+ r.vec.append(new Value(v * *v.vec[i]));
+ return r;
}
if (type == NUMBER && v.type == NUMBER) {
return Value(num * v.num);
@@ -148,6 +127,20 @@ Value Value::operator * (const Value &v) const
Value Value::operator / (const Value &v) const
{
+ if (type == VECTOR && v.type == NUMBER) {
+ Value r;
+ r.type = VECTOR;
+ for (int i = 0; i < vec.size(); i++)
+ r.vec.append(new Value(*vec[i] / v));
+ return r;
+ }
+ if (type == NUMBER && v.type == VECTOR) {
+ Value r;
+ r.type = VECTOR;
+ for (int i = 0; i < v.vec.size(); i++)
+ r.vec.append(new Value(v / *v.vec[i]));
+ return r;
+ }
if (type == NUMBER && v.type == NUMBER) {
return Value(num / v.num);
}
@@ -164,46 +157,59 @@ Value Value::operator % (const Value &v) const
Value Value::inv() const
{
- if (type == MATRIX) {
- double m_[16];
- for (int i=0; i<16; i++)
- m_[i] = -m[i];
- return Value(m);
+ if (type == VECTOR) {
+ Value r;
+ r.type = VECTOR;
+ for (int i = 0; i < vec.size(); i++)
+ r.vec.append(new Value(vec[i]->inv()));
+ return r;
}
- if (type == VECTOR)
- return Value(-x, -y, -z);
if (type == NUMBER)
- return Value(-x);
+ return Value(-num);
return Value();
}
+bool Value::getnum(double &v) const
+{
+ if (type != NUMBER)
+ return false;
+ v = num;
+ return true;
+}
+
+bool Value::getv3(double &x, double &y, double &z) const
+{
+ if (type != VECTOR || vec.size() != 3)
+ return false;
+ if (vec[0]->type != NUMBER)
+ return false;
+ if (vec[1]->type != NUMBER)
+ return false;
+ if (vec[2]->type != NUMBER)
+ return false;
+ x = vec[0]->num;
+ y = vec[1]->num;
+ z = vec[2]->num;
+ return true;
+}
+
QString Value::dump() const
{
if (type == STRING) {
return QString("\"") + text + QString("\"");
}
- if (type == MATRIX) {
+ if (type == VECTOR) {
QString text = "[";
- for (int i=0; i<16; i++) {
- QString t;
- t.sprintf("%f", m[i == 15 ? 15 : (i*4) % 15]);
- if (i % 4 == 0 && i > 0)
- text += ";";
+ for (int i = 0; i < vec.size(); i++) {
if (i > 0)
- text += " ";
- text += t;
+ text += ", ";
+ text += vec[i]->dump();
}
- text += "]";
- return text;
- }
- if (type == VECTOR) {
- QString text;
- text.sprintf("[%f %f %f]", x, y, z);
- return text;
+ return text + "]";
}
if (type == RANGE) {
QString text;
- text.sprintf("[ %f : %f : %f ]", r_begin, r_step, r_end);
+ text.sprintf("[ %f : %f : %f ]", range_begin, range_step, range_end);
return text;
}
if (type == NUMBER) {
@@ -222,14 +228,12 @@ void Value::reset_undef()
type = UNDEFINED;
b = false;
num = 0;
- r_begin = 0;
- r_step = 0;
- r_end = 0;
- x = 0;
- y = 0;
- z = 0;
- for (int i=0; i<16; i++)
- m[i] = 0;
+ for (int i = 0; i < vec.size(); i++)
+ delete vec[i];
+ vec.clear();
+ range_begin = 0;
+ range_step = 0;
+ range_end = 0;
text = QString();
}
contact: Jan Huwald // Impressum