summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/value.cc59
-rw-r--r--testdata/scad/misc/vector-values.scad40
-rw-r--r--tests/CMakeLists.txt3
-rw-r--r--tests/regression/echotest/vector-values-expected.txt10
4 files changed, 111 insertions, 1 deletions
diff --git a/src/value.cc b/src/value.cc
index 47fac1e..48fea1a 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -30,6 +30,7 @@
#include <sstream>
#include <QDir>
#include <boost/foreach.hpp>
+#include "printutils.h"
Value::Value()
{
@@ -157,6 +158,64 @@ Value Value::operator * (const Value &v) const
if (this->type == NUMBER && v.type == NUMBER) {
return Value(this->num * v.num);
}
+ if (this->type == VECTOR && v.type == VECTOR && this->vec.size() == v.vec.size() ) {
+ if ( this->vec[0]->type == NUMBER && v.vec[0]->type == NUMBER ) {
+ // Vector dot product.
+ double r=0.0;
+ for (size_t i=0; i <this->vec.size(); i++) {
+ if ( this->vec[i]->type != NUMBER || v.vec[i]->type != NUMBER ) return Value();
+ r = r + (this->vec[i]->num * v.vec[i]->num);
+ }
+ return Value(r);
+ } else if ( this->vec[0]->type == VECTOR && v.vec[0]->type == NUMBER ) {
+ // Matrix * Vector
+ Value r;
+ r.type = VECTOR;
+ for ( size_t i=0; i < this->vec.size(); i++) {
+ double r_e=0.0;
+ if ( this->vec[i]->vec.size() != v.vec.size() ) return Value();
+ for ( size_t j=0; j < this->vec[i]->vec.size(); j++) {
+ if ( this->vec[i]->vec[j]->type != NUMBER || v.vec[i]->type != NUMBER ) return Value();
+ r_e = r_e + (this->vec[i]->vec[j]->num * v.vec[j]->num);
+ }
+ r.vec.push_back(new Value(r_e));
+ }
+ return r;
+ } else if (this->vec[0]->type == NUMBER && v.vec[0]->type == VECTOR ) {
+ // Vector * Matrix
+ Value r;
+ r.type = VECTOR;
+ for ( size_t i=0; i < v.vec[0]->vec.size(); i++) {
+ double r_e=0.0;
+ for ( size_t j=0; j < v.vec.size(); j++) {
+ if ( v.vec[j]->vec.size() != v.vec[0]->vec.size() ) return Value();
+ if ( this->vec[j]->type != NUMBER || v.vec[j]->vec[i]->type != NUMBER ) return Value();
+ r_e = r_e + (this->vec[j]->num * v.vec[j]->vec[i]->num);
+ }
+ r.vec.push_back(new Value(r_e));
+ }
+ return r;
+ }
+ }
+ if (this->type == VECTOR && v.type == VECTOR && this->vec[0]->type == VECTOR && v.vec[0]->type == VECTOR && this->vec[0]->vec.size() == v.vec.size() ) {
+ // Matrix * Matrix
+ Value rrow;
+ rrow.type = VECTOR;
+ for ( size_t i=0; i < this->vec.size(); i++ ) {
+ Value * rcol=new Value();
+ rcol->type = VECTOR;
+ for ( size_t j=0; j < this->vec.size(); j++ ) {
+ double r_e=0.0;
+ for ( size_t k=0; k < v.vec.size(); k++ ) {
+ r_e = r_e + (this->vec[i]->vec[k]->num * v.vec[k]->vec[j]->num);
+ }
+ // PRINTB(" r_e = %s",r_e);
+ rcol->vec.push_back(new Value(r_e));
+ }
+ rrow.vec.push_back(rcol);
+ }
+ return rrow;
+ }
return Value();
}
diff --git a/testdata/scad/misc/vector-values.scad b/testdata/scad/misc/vector-values.scad
new file mode 100644
index 0000000..1872b39
--- /dev/null
+++ b/testdata/scad/misc/vector-values.scad
@@ -0,0 +1,40 @@
+// Value vector tests.
+
+a1=[0,1,2];
+b1=[3,4,5];
+c1=a1*b1;
+echo(str("Testing vector dot product: ",c1));
+
+d1=[1,0];
+echo(str(" Bounds check: ",a1*d1));
+
+m2=[[0,1],[1,0]];
+v2=[2,3];
+p2=m2*v2;
+echo(str("Testing matrix * vector: ",p2));
+
+d2=[0,0,1];
+echo(str(" Bounds check: ",m2*d2));
+
+m3=[[1,-1,1],[1,0,-1]];
+v3=[1,1];
+p3=v3*m3;
+echo(str("Testing vector * matrix: ",p3));
+
+echo(str(" Bounds check: ",m3*v3));
+
+ma4=[ [1,0],[0,1] ];
+mb4=[ [1,0],[0,1] ];
+echo(str("Testing id matrix * id matrix: ",ma4*mb4));
+
+ma5=[ [1, 0, 1]
+ ,[0, 1,-1] ];
+mb5=[ [1,0]
+ ,[0,1]
+ ,[1,1] ];
+echo(str("Testing asymmetric matrix * matrix: ",ma5*mb5));
+echo(str("Testing alternate asymmetric matrix * matrix: ",mb5*ma5));
+
+echo(str(" Bounds check: ",ma5*ma4));
+
+cube(1.0);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b81ce8c..4329795 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -608,7 +608,8 @@ list(APPEND ECHO_FILES ${FUNCTION_FILES}
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/builtin-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/dim-all.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/string-test.scad
- ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/string-indexing.scad)
+ ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/string-indexing.scad
+ ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/vector-values.scad)
list(APPEND DUMPTEST_FILES ${MINIMAL_FILES} ${FEATURES_FILES} ${EXAMPLE_FILES})
list(APPEND DUMPTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/escape-test.scad
diff --git a/tests/regression/echotest/vector-values-expected.txt b/tests/regression/echotest/vector-values-expected.txt
new file mode 100644
index 0000000..7654892
--- /dev/null
+++ b/tests/regression/echotest/vector-values-expected.txt
@@ -0,0 +1,10 @@
+ECHO: "Testing vector dot product: 14"
+ECHO: " Bounds check: undef"
+ECHO: "Testing matrix * vector: [3, 2]"
+ECHO: " Bounds check: undef"
+ECHO: "Testing vector * matrix: [2, -1, 0]"
+ECHO: " Bounds check: undef"
+ECHO: "Testing id matrix * id matrix: [[1, 0], [0, 1]]"
+ECHO: "Testing asymmetric matrix * matrix: [[2, 1], [-1, 0]]"
+ECHO: "Testing alternate asymmetric matrix * matrix: [[1, 0, 1], [0, 1, -1], [1, 1, 0]]"
+ECHO: " Bounds check: undef"
contact: Jan Huwald // Impressum