src/matrix.h

Wed, 22 Jan 2020 22:41:17 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 22 Jan 2020 22:41:17 +0200
changeset 28
c92c1daf735f
parent 26
3a9e761e4faa
permissions
-rw-r--r--

modelview matrix set up

/*
 *  LDForge: LDraw parts authoring CAD
 *  Copyright (C) 2013 - 2020 Teemu Piippo
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once
#include <QGenericMatrix>
#include <type_traits>

template<int Rows, int Columns, typename T = double>
struct MatrixIterator;

template<int Rows, int Columns>
struct MatrixIndex
{
	int row;
	int column;
};

template<int Rows, int Columns, typename T = double>
struct Matrix
{
	using Iterator = MatrixIterator<Rows, Columns, T>;
	T values[Rows][Columns];
	Iterator begin()
	{
		return {*this, {0, 0}};
	}
	Iterator end()
	{
		return {*this, {Rows, 0}};
	}
	T& operator()(int row, int column)
	{
		return this->values[row][column];
	}
	T operator()(int row, int column) const
	{
		return this->values[row][column];
	}
	T& operator[](const MatrixIndex<Rows, Columns>& index)
	{
		return (*this)(index.row, index.column);
	}
	T operator[](const MatrixIndex<Rows, Columns>& index) const
	{
		return (*this)(index.row, index.column);
	}
};

template<int Rows, int Columns, typename T>
struct MatrixIterator
{
	struct Value
	{
		const MatrixIndex<Rows, Columns> index;
		decltype(std::declval<Matrix<Rows, Columns, T>>()(0, 0)) value;
	};
	Matrix<Rows, Columns, T>& matrix;
	MatrixIndex<Rows, Columns> index;
};

template<int Rows, int Columns>
auto& operator++(MatrixIndex<Rows, Columns>& index)
{
	index.column += 1;
	if (index.column >= Columns)
	{
		index.row += 1;
		index.column -= Columns;
	}
	return index;
}

template<int Rows, int Columns>
bool operator==(
	const MatrixIndex<Rows, Columns>& one,
	const MatrixIndex<Rows, Columns>& other)
{
	return one.row == other.row and one.column == other.column;
}
template<int Rows, int Columns, typename T>
auto& operator++(MatrixIterator<Rows, Columns, T>& iterator)
{
	++iterator.index;
	return iterator;
}

template<int Rows, int Columns, typename T>
bool operator==(
	const MatrixIterator<Rows, Columns, T>& one,
	const MatrixIterator<Rows, Columns, T>& other)
{
	return &one.matrix == &other.matrix and one.index == other.index;
}

template<int Rows, int Columns, typename T>
bool operator!=(
	const MatrixIterator<Rows, Columns, T>& one,
	const MatrixIterator<Rows, Columns, T>& other)
{
	return not (one == other);
}

template<int Rows, int Columns, typename T>
auto operator*(MatrixIterator<Rows, Columns, T>& iterator)
	-> typename MatrixIterator<Rows, Columns, T>::Value
{
	return {iterator.index, iterator.matrix[iterator.index]};
}

template<int Rows, int Columns, typename T>
QGenericMatrix<Rows, Columns, T> matrixToQGenericMatrix(const Matrix<Rows, Columns, T>& matrix)
{
	return {matrix.values};
}

template<int Rows, int Columns, typename T>
Matrix<Rows, Columns, T> matrixFromQGenericMatrix(const QGenericMatrix<Rows, Columns, T&> matrix)
{
	Matrix<Rows, Columns, T> result;
	for (auto& cell : result)
	{
		matrix(cell.index.row, cell.index.column) = result[cell.index];
	}
	return result;
}

using Matrix3x3 = Matrix<3, 3>;
Q_DECLARE_METATYPE(Matrix3x3);
using Matrix4x4 = Matrix<4, 4>;
Q_DECLARE_METATYPE(Matrix4x4);

template<int Rows, int Columns, typename T>
QDataStream& operator<<(QDataStream& stream, const Matrix<Rows, Columns, T>& matrix)
{
	for (auto& cell : matrix)
	{
		stream << cell.value;
	}
	return stream;
}

template<int Rows, int Columns, typename T>
QDataStream& operator>>(QDataStream& stream, Matrix<Rows, Columns, T>& matrix)
{
	for (auto& cell : matrix)
	{
		stream >> cell.value;
	}
	return stream;
}

Matrix4x4 combine(const Matrix3x3& topLeft, const struct Point3D& translation);

static constexpr Matrix3x3 identity3x3 {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}};
static constexpr Matrix4x4 identity4x4 {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}};

namespace math
{
	qreal det(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f, qreal g, qreal h, qreal i);
	qreal det(const Matrix<2, 2>& matrix);
	qreal det(const Matrix3x3& matrix);
	qreal det(const Matrix4x4& matrix);
}

mercurial