From 1c6a635497397c25f68b9cb9521ca9f1a57ccc4a Mon Sep 17 00:00:00 2001 From: Lawrence Date: Tue, 24 Dec 2019 15:18:15 -0800 Subject: [PATCH] Add homogeneous coordinate functions Add functions for transformations in 3 dimensional homogeneous space. These include functions that generate transformation matrices and perform matrix multiplication. --- rtengine/homogeneouscoordinates.cc | 174 +++++++++++++++++++++++++++++ rtengine/homogeneouscoordinates.h | 75 +++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 rtengine/homogeneouscoordinates.cc create mode 100644 rtengine/homogeneouscoordinates.h diff --git a/rtengine/homogeneouscoordinates.cc b/rtengine/homogeneouscoordinates.cc new file mode 100644 index 000000000..f134abc53 --- /dev/null +++ b/rtengine/homogeneouscoordinates.cc @@ -0,0 +1,174 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Lawrence Lee + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +#include "homogeneouscoordinates.h" + +namespace rtengine +{ + +template +homogeneous::Vector operator*(const homogeneous::Matrix& a, const homogeneous::Vector& b) +{ + homogeneous::Vector prod; + + prod.fill(0); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + prod[i] += a[i][j] * b[j]; + } + } + + return prod; +} + +template +homogeneous::Matrix operator*(const homogeneous::Matrix& a, const homogeneous::Matrix& b) +{ + homogeneous::Matrix prod; + + for (int i = 0; i < 4; i++) { + prod[i].fill(0); + + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 4; k++) { + prod[i][j] += a[i][k] * b[k][j]; + } + } + } + + return prod; +} + +namespace homogeneous +{ + +template +Matrix projectionMatrix(T location, Axis normal) +{ + Matrix matrix; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + matrix[i][j] = 0; + } + } + + matrix[0][0] = location; + matrix[1][1] = location; + matrix[2][2] = location; + matrix[3][3] = 0; + + switch (normal) { + case X: + matrix[3][0] = 1; + break; + + case Y: + matrix[3][1] = 1; + break; + + case Z: + matrix[3][2] = 1; + break; + } + + return matrix; +} + +template +Matrix rotationMatrix(double radians, Axis axis) +{ + Matrix matrix; + + switch (axis) { + case X: + matrix[0][0] = 1; + matrix[0][1] = 0; + matrix[0][2] = 0; + matrix[1][0] = 0; + matrix[1][1] = cos(radians); + matrix[1][2] = -sin(radians); + matrix[2][0] = 0; + matrix[2][1] = sin(radians); + matrix[2][2] = cos(radians); + break; + + case Y: + matrix[0][0] = cos(radians); + matrix[0][1] = 0; + matrix[0][2] = sin(radians); + matrix[1][0] = 0; + matrix[1][1] = 1; + matrix[1][2] = 0; + matrix[2][0] = -sin(radians); + matrix[2][1] = 0; + matrix[2][2] = cos(radians); + break; + + case Z: + matrix[0][0] = cos(radians); + matrix[0][1] = -sin(radians); + matrix[0][2] = 0; + matrix[1][0] = sin(radians); + matrix[1][1] = cos(radians); + matrix[1][2] = 0; + matrix[2][0] = 0; + matrix[2][1] = 0; + matrix[2][2] = 1; + break; + } + + matrix[0][3] = 0; + matrix[1][3] = 0; + matrix[2][3] = 0; + matrix[3][0] = 0; + matrix[3][1] = 0; + matrix[3][2] = 0; + matrix[3][3] = 1; + + return matrix; +} + +template +Matrix translationMatrix(T x, T y, T z) +{ + Matrix matrix; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + matrix[i][j] = 0; + } + } + + matrix[0][0] = 1; + matrix[1][1] = 1; + matrix[2][2] = 1; + matrix[0][3] = x; + matrix[1][3] = y; + matrix[2][3] = z; + matrix[3][3] = 1; + + return matrix; +} + +} + +} diff --git a/rtengine/homogeneouscoordinates.h b/rtengine/homogeneouscoordinates.h new file mode 100644 index 000000000..c24b73f05 --- /dev/null +++ b/rtengine/homogeneouscoordinates.h @@ -0,0 +1,75 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Lawrence Lee + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#pragma once + +#include + +namespace rtengine +{ + +namespace homogeneous +{ + +enum Axis {X, Y, Z}; + +template +using Matrix = std::array, 4>; + +/** + * 3 dimensional homogeneous vector. + */ +template +using Vector = std::array; + +/** + * Creates a 3 dimensional transformation matrix for projection onto a plane. + * @param location Distance from the origin to the plane. + * @param normal Direction of the plane's normal. + */ +template +Matrix projectionMatrix(T location, Axis normal); + +/** + * Creates a 3 dimensional transformation matrix for rotation. + * @param radians Rotation angle. + * @param axis Axis of rotation. + */ +template +Matrix rotationMatrix(T radians, Axis axis); + +/** + * Creates a 3 dimensional transformation matrix for translation. + * @param x Translation in the the x-direction. + * @param y Translation in the the y-direction. + * @param z Translation in the the z-direction. + */ +template +Matrix translationMatrix(T x, T y, T z); + +} + +template +homogeneous::Vector operator*(const homogeneous::Matrix& a, const homogeneous::Vector& b); + +template +homogeneous::Matrix operator*(const homogeneous::Matrix& a, const homogeneous::Matrix& b); + +} + +#include "homogeneouscoordinates.cc"