/*- * Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart * * This file is part of CityDoctor2. * * CityDoctor2 is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CityDoctor2 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CityDoctor2. If not, see . */ package de.hft.stuttgart.citydoctor2.math; import java.util.Arrays; /** * A 3x3 Matrix used for rotation of vectors * * @author Matthias Betz * */ public class Matrix3x3d { private double[][] values; /** * Identity matrix */ public static final Matrix3x3d IDENTITY = new Matrix3x3d(1d, 1d, 1d); /** * Creates an empty matrix, set with all 0. */ public Matrix3x3d() { values = new double[3][3]; } private Matrix3x3d(double[][] values, boolean copy) { if (values.length != 3 || values[0].length != 3 || values[1].length != 3 || values[2].length != 3) { throw new IllegalArgumentException("Only 3x3 arrays allowed"); } if (copy) { this.values = new double[3][]; this.values[0] = Arrays.copyOf(values[0], 3); this.values[1] = Arrays.copyOf(values[1], 3); this.values[2] = Arrays.copyOf(values[2], 3); } else { this.values = values; } } /** * creates a new matrix with the given 3 x 3 array. The array will be copied. * * @param values the 3x3 array containing the matrix values */ public Matrix3x3d(double[][] values) { this(values, true); } /** * Adds two matrices. A + B * * @param other the other matrix * @return a new matrix object containing the result. */ public Matrix3x3d plus(Matrix3x3d other) { double[][] newValues = new double[3][3]; for (int row = 0; row < 3; row++) { for (int column = 0; column < 3; column++) { newValues[row][column] = values[row][column] + other.getValue(row, column); } } return new Matrix3x3d(newValues, false); } /** * Matrix multiplication with a scalar A * s. * * @param s the scalar * @return the result in a new matrix object */ public Matrix3x3d mult(double s) { double[][] newValues = new double[3][3]; for (int row = 0; row < 3; row++) { for (int column = 0; column < 3; column++) { newValues[row][column] = values[row][column] * s; } } return new Matrix3x3d(newValues, false); } /** * Matrix multiplication with another matrix A * B. * * @param other the other matrix * @return the result in a new matrix object */ public Matrix3x3d mult(Matrix3x3d other) { double[][] newValues = new double[3][3]; for (int row = 0; row < 3; row++) { for (int column = 0; column < 3; column++) { newValues[row][column] = values[row][0] * other.getValue(0, column); newValues[row][column] += values[row][1] * other.getValue(1, column); newValues[row][column] += values[row][2] * other.getValue(2, column); } } return new Matrix3x3d(newValues, false); } /** * Transposes this matrix * * @return A new matrix with the transposed values, this instance is not * changed. */ public Matrix3x3d transpose() { Matrix3x3d x = new Matrix3x3d(); double[][] copyValues = x.values; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { copyValues[j][i] = values[i][j]; } } return x; } /** * Multiplies this matrix with a 3-dim vector. * * @param the multiplied vector * @return the result stored in a new vector */ public Vector3d mult(Vector3d other) { double x = values[0][0] * other.getX() + values[0][1] * other.getY() + values[0][2] * other.getZ(); double y = values[1][0] * other.getX() + values[1][1] * other.getY() + values[1][2] * other.getZ(); double z = values[2][0] * other.getX() + values[2][1] * other.getY() + values[2][2] * other.getZ(); return new Vector3d(x, y, z); } /** * Returns the value at the requested location * * @param row the row * @param column the column * @return the value */ public double getValue(int row, int column) { return values[row][column]; } private Matrix3x3d(double m00, double m11, double m22) { this(); values[0][0] = m00; values[1][1] = m11; values[2][2] = m22; } @Override public String toString() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 3; i++) { sb.append(Arrays.toString(values[i])); sb.append('\n'); } return sb.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.deepHashCode(values); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Matrix3x3d other = (Matrix3x3d) obj; return Arrays.deepEquals(values, other.values); } }