Base: support of multiplication of a matrix with a scalar, add functions to check whether it's the unit or null matrix
This commit is contained in:
@@ -99,6 +99,24 @@ void Matrix4D::setToUnity ()
|
||||
dMtrx4D[3][0] = 0.0; dMtrx4D[3][1] = 0.0; dMtrx4D[3][2] = 0.0; dMtrx4D[3][3] = 1.0;
|
||||
}
|
||||
|
||||
bool Matrix4D::isUnity() const
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (i == j) {
|
||||
if (dMtrx4D[i][j] != 1.0)
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (dMtrx4D[i][j] != 0.0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Matrix4D::nullify()
|
||||
{
|
||||
dMtrx4D[0][0] = 0.0; dMtrx4D[0][1] = 0.0; dMtrx4D[0][2] = 0.0; dMtrx4D[0][3] = 0.0;
|
||||
@@ -107,6 +125,18 @@ void Matrix4D::nullify()
|
||||
dMtrx4D[3][0] = 0.0; dMtrx4D[3][1] = 0.0; dMtrx4D[3][2] = 0.0; dMtrx4D[3][3] = 0.0;
|
||||
}
|
||||
|
||||
bool Matrix4D::isNull() const
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (dMtrx4D[i][j] != 0.0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double Matrix4D::determinant() const
|
||||
{
|
||||
double fA0 = dMtrx4D[0][0]*dMtrx4D[1][1] - dMtrx4D[0][1]*dMtrx4D[1][0];
|
||||
|
||||
@@ -88,6 +88,8 @@ public:
|
||||
inline Vector3d operator * (const Vector3d& rclVct) const;
|
||||
inline void multVec(const Vector3d & src, Vector3d & dst) const;
|
||||
inline void multVec(const Vector3f & src, Vector3f & dst) const;
|
||||
inline Matrix4D operator * (double) const;
|
||||
inline Matrix4D& operator *= (double);
|
||||
/// Comparison
|
||||
inline bool operator != (const Matrix4D& rclMtrx) const;
|
||||
/// Comparison
|
||||
@@ -133,8 +135,12 @@ public:
|
||||
//@{
|
||||
/// Makes unity matrix
|
||||
void setToUnity();
|
||||
/// Checks if this is the unit matrix
|
||||
bool isUnity() const;
|
||||
/// Makes a null matrix
|
||||
void nullify();
|
||||
/// Checks if this is the null matrix
|
||||
bool isNull() const;
|
||||
/// moves the coordinatesystem for the x,y,z value
|
||||
void move (float x, float y, float z)
|
||||
{ move(Vector3f(x,y,z)); }
|
||||
@@ -346,6 +352,28 @@ inline void Matrix4D::multVec(const Vector3f & src, Vector3f & dst) const
|
||||
static_cast<float>(z));
|
||||
}
|
||||
|
||||
inline Matrix4D Matrix4D::operator * (double scalar) const
|
||||
{
|
||||
Matrix4D matrix;
|
||||
for (unsigned short i = 0; i < 4; i++) {
|
||||
for (unsigned short j = 0; j < 4; j++) {
|
||||
matrix.dMtrx4D[i][j] = dMtrx4D[i][j] * scalar;
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
inline Matrix4D& Matrix4D::operator *= (double scalar)
|
||||
{
|
||||
for (unsigned short i = 0; i < 4; i++) {
|
||||
for (unsigned short j = 0; j < 4; j++) {
|
||||
dMtrx4D[i][j] *= scalar;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool Matrix4D::operator== (const Matrix4D& rclMtrx) const
|
||||
{
|
||||
unsigned short iz, is;
|
||||
|
||||
@@ -34,7 +34,7 @@ Scale the matrix with the vector
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="hasScale">
|
||||
<Methode Name="hasScale" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
hasScale(tol=None)
|
||||
@@ -42,11 +42,26 @@ Return 0 is no scale factor, 1 for uniform scaling, -1 for non-uniform scaling.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="nullify">
|
||||
<Documentation>
|
||||
<UserDocu>nullify() - make this the null matrix</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isNull" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>isNull() - check if this is the null matrix</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="unity">
|
||||
<Documentation>
|
||||
<UserDocu>unity() - make this matrix to unity</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isUnity" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>isUnity() - check if this is the unit matrix</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="transform">
|
||||
<Documentation>
|
||||
<UserDocu>transform(Vector,Matrix) - return the dot product of the two vectors</UserDocu>
|
||||
|
||||
@@ -186,8 +186,7 @@ PyObject* MatrixPy::number_multiply_handler(PyObject *self, PyObject *other)
|
||||
|
||||
if (PyNumber_Check(other)) {
|
||||
double v = PyFloat_AsDouble(other);
|
||||
a.scale(v,v,v);
|
||||
return new MatrixPy(a);
|
||||
return new MatrixPy(a * v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,14 +209,14 @@ PyObject * MatrixPy::number_power_handler (PyObject* self, PyObject* other, PyOb
|
||||
Base::Matrix4D a = static_cast<MatrixPy*>(self)->value();
|
||||
|
||||
long b = Py::Int(other);
|
||||
if (!b)
|
||||
if (b == 0)
|
||||
return new MatrixPy(Matrix4D());
|
||||
|
||||
if (b < 0) {
|
||||
if (fabs(a.determinant()) > DBL_EPSILON)
|
||||
a.inverseGauss();
|
||||
else {
|
||||
PyErr_SetString(Base::BaseExceptionFreeCADError, "Cannot invert singular matrix");
|
||||
PyErr_SetString(PyExc_RuntimeError, "Cannot invert singular matrix");
|
||||
return nullptr;
|
||||
}
|
||||
b = -b;
|
||||
@@ -266,7 +265,7 @@ PyObject* MatrixPy::move(PyObject * args)
|
||||
Base::Vector3d vec;
|
||||
PyObject *pcVecObj;
|
||||
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) { // convert args: Python->C
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) {
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
@@ -302,7 +301,7 @@ PyObject* MatrixPy::scale(PyObject * args)
|
||||
Base::Vector3d vec;
|
||||
PyObject *pcVecObj;
|
||||
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) { // convert args: Python->C
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) {
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
@@ -340,10 +339,32 @@ PyObject* MatrixPy::hasScale(PyObject * args)
|
||||
return Py::new_reference_to(Py::Int(getMatrixPtr()->hasScale(tol)));
|
||||
}
|
||||
|
||||
PyObject* MatrixPy::nullify(PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
PY_TRY {
|
||||
getMatrixPtr()->nullify();
|
||||
Py_Return;
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
PyObject* MatrixPy::isNull(PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
PY_TRY {
|
||||
bool ok = getMatrixPtr()->isNull();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
PyObject* MatrixPy::unity(PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) // convert args: Python->C
|
||||
return nullptr; // NULL triggers exception
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
PY_TRY {
|
||||
getMatrixPtr()->setToUnity();
|
||||
}
|
||||
@@ -352,29 +373,33 @@ PyObject* MatrixPy::unity(PyObject * args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* MatrixPy::isUnity(PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
PY_TRY {
|
||||
bool ok = getMatrixPtr()->isUnity();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
PyObject* MatrixPy::transform(PyObject * args)
|
||||
{
|
||||
Base::Vector3d vec;
|
||||
Matrix4D mat;
|
||||
PyObject *pcVecObj,*pcMatObj;
|
||||
|
||||
if (PyArg_ParseTuple(args, "O!O!: a transform point (Vector) and a transform matrix (Matrix) is needed",
|
||||
&(Base::VectorPy::Type), &pcVecObj, &(MatrixPy::Type), &pcMatObj) ) { // convert args: Python->C
|
||||
Base::VectorPy *pcObject = static_cast<Base::VectorPy*>(pcVecObj);
|
||||
Base::Vector3d* val = pcObject->getVectorPtr();
|
||||
vec.Set(val->x,val->y,val->z);
|
||||
mat = *(static_cast<MatrixPy*>(pcMatObj)->getMatrixPtr());
|
||||
// clears the error from the first PyArg_ParseTuple()6
|
||||
PyErr_Clear();
|
||||
}
|
||||
else
|
||||
return nullptr; // NULL triggers exception
|
||||
if (!PyArg_ParseTuple(args, "O!O!: a transform point (Vector) and a transform matrix (Matrix) is needed",
|
||||
&(Base::VectorPy::Type), &pcVecObj, &(MatrixPy::Type), &pcMatObj))
|
||||
return nullptr;
|
||||
|
||||
PY_TRY {
|
||||
getMatrixPtr()->transform(vec,mat);
|
||||
}
|
||||
PY_CATCH;
|
||||
Base::VectorPy *pcObject = static_cast<Base::VectorPy*>(pcVecObj);
|
||||
Base::Vector3d* val = pcObject->getVectorPtr();
|
||||
vec.Set(val->x,val->y,val->z);
|
||||
mat = *(static_cast<MatrixPy*>(pcMatObj)->getMatrixPtr());
|
||||
|
||||
getMatrixPtr()->transform(vec,mat);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
@@ -388,7 +413,7 @@ PyObject* MatrixPy::col(PyObject * args)
|
||||
return Py::new_reference_to(Py::Vector(v));
|
||||
}
|
||||
|
||||
PyErr_SetString(Base::BaseExceptionFreeCADError, "int expected");
|
||||
PyErr_SetString(PyExc_TypeError, "int expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -404,7 +429,7 @@ PyObject* MatrixPy::setCol(PyObject * args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_SetString(Base::BaseExceptionFreeCADError, "int and Vector expected");
|
||||
PyErr_SetString(PyExc_TypeError, "int and Vector expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -418,7 +443,7 @@ PyObject* MatrixPy::row(PyObject * args)
|
||||
return Py::new_reference_to(Py::Vector(v));
|
||||
}
|
||||
|
||||
PyErr_SetString(Base::BaseExceptionFreeCADError, "int expected");
|
||||
PyErr_SetString(PyExc_TypeError, "int expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -434,7 +459,7 @@ PyObject* MatrixPy::setRow(PyObject * args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_SetString(Base::BaseExceptionFreeCADError, "int and Vector expected");
|
||||
PyErr_SetString(PyExc_TypeError, "int and Vector expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -459,7 +484,7 @@ PyObject* MatrixPy::setTrace(PyObject * args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_SetString(Base::BaseExceptionFreeCADError, "Vector expected");
|
||||
PyErr_SetString(PyExc_TypeError, "Vector expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -963,16 +988,26 @@ PyObject * MatrixPy::number_divmod_handler (PyObject* /*self*/, PyObject* /*othe
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * MatrixPy::number_negative_handler (PyObject* /*self*/)
|
||||
PyObject * MatrixPy::number_negative_handler (PyObject* self)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
if (!PyObject_TypeCheck(self, &(MatrixPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "arg must be Matrix");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::Matrix4D a = static_cast<MatrixPy*>(self)->value();
|
||||
return new MatrixPy(a * -1);
|
||||
}
|
||||
|
||||
PyObject * MatrixPy::number_positive_handler (PyObject* /*self*/)
|
||||
PyObject * MatrixPy::number_positive_handler (PyObject* self)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
if (!PyObject_TypeCheck(self, &(MatrixPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "arg must be Matrix");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::Matrix4D a = static_cast<MatrixPy*>(self)->value();
|
||||
return new MatrixPy(a);
|
||||
}
|
||||
|
||||
PyObject * MatrixPy::number_absolute_handler (PyObject* /*self*/)
|
||||
|
||||
Reference in New Issue
Block a user