- 3.e switch 文を使った何か面白いプログラムを作る。
- 6 2 次元以上の配列またはポインタ配列を使った自分の面白いと思うプログラムを作る。
ベクトルと行列のコードを作成し、単体テストをしました。 各定義したコードは、レポート巻末に綴じました。 テストとテスト結果は以下のようになりました。
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "Vector.hpp"
#include "Matrix.hpp"
namespace lsr {
TEST(VectorTest, GetAndSet) {
Vector<double> v0 = {0.0, 0.0, 0.0};
Vector<double> v1 { v0 };
v1.setX(1.0).setY(1.0).setZ(1.0);
EXPECT_EQ(0.0, v0.x());
EXPECT_EQ(1.0, v1[1]);
}
TEST(VectorTest, Math) {
lsr::Vector<double> v0 {0.0, 0.0, 0.0};
lsr::Vector<double> v1 {1.0, 1.0, 1.0};;
v0 += v1;
v0 -= v1;
v0 *= v1;
EXPECT_EQ(0, v0.x());
EXPECT_EQ(0, v0.dot(v1));
}
TEST(MatrixTest, GetAndSet) {
Matrix<double> m0 = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
Matrix<double> m1 { m0 };
m1.set(0, 0, 1.0).set(1, 1, 1.0).set(2, 2, 1.0);
EXPECT_EQ(0.0, m0[0][0]);
EXPECT_EQ(1.0, m1[1][1]);
}
TEST(MatrixTest, Math) {
Matrix<double> m0 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
Matrix<double> m1 {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
m0 += m1;
m0 -= m1;
// m0 *= m1; // TODO DEBUG
EXPECT_EQ(0, m0[0][0]);
}
} // namespace
$ cd modules/core/src && cmake -S . -B build && cmake --build build
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19042.
-- Configuring done
-- Generating done
-- Build files have been written to: ~/src/build
Microsoft (R) Build Engine version 16.7.0+b89cb5fde for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
gmock_main.vcxproj -> ~\src\build\lib\Debug\gmock_maind.lib
gtest.vcxproj -> ~\src\build\lib\Debug\gtestd.lib
gtest_main.vcxproj -> ~\src\build\lib\Debug\gtest_maind.lib
Matrix_test.cc
Matrix_test.vcxproj -> ~\src\build\Debug\Matrix_test.exe
Vector_test.vcxproj -> ~\src\build\Debug\Vector_test.exe
gmock.vcxproj -> ~\src\build\lib\Debug\gmockd.lib
$ cd modules/core/src/build && ctest
Test project ~/src/build
Start 1: VectorTest.GetAndSet
1/4 Test #1: VectorTest.GetAndSet ............. Passed 0.02 sec
Start 2: VectorTest.Math
2/4 Test #2: VectorTest.Math .................. Passed 0.01 sec
Start 3: MatrixTest.GetAndSet
3/4 Test #3: MatrixTest.GetAndSet ............. Passed 0.02 sec
Start 4: MatrixTest.Math
4/4 Test #4: MatrixTest.Math .................. Passed 0.02 sec
100% tests passed, 0 tests failed out of 4
Total Test time (real) = 0.11 sec
Done in 5.61s.
ベクトルと行列の基本的な演算やgetやsetなどで値を操作する処理を作りました。 コードの内容はTiny Different1iable Simulatorを参考にしました。 単体テストはGoogleTestおよびGoogleMockを使用しました。 GoogleTestの使い方はsamples.mdを参考にしました。
#ifndef _MATH_VECTOR_H
#define _MATH_VECTOR_H
namespace lsr {
template <typename S=double>
struct Vector {
typedef Vector V;
S _x;
S _y;
S _z;
S x () const { return _x; }
S y () const { return _y; }
S z () const { return _z; }
inline S& operator[](int i) {
switch (i) {
case 0: { return _x; }
case 1: { return _y; }
case 2: { return _z; }
default: { }
}
return _x;
}
explicit Vector(int unused = 0) {}
Vector (const V& _) { set(_.x(), _.y(), _.z()); }
Vector (S x, S y, S z) { set(x, y, z); }
inline V& set (S x, S y, S z) { _x = x; _y = y; _z = z; return *this; }
inline V& setX (S x) { _x = x; return *this; }
inline V& setY (S y) { _y = y; return *this; }
inline V& setZ (S z) { _z = z; return *this; }
inline V& fill (S s) { _x = _y = _z = s; return *this; }
/**
* Math
*/
inline V& operator =(V& _) { _x =_.x(); _y =_.y(); _z =_.z(); return *this; }
inline V& operator+=(V& _) { _x+=_.x(); _y+=_.y(); _z+=_.z(); return *this; }
inline V& operator-=(V& _) { _x-=_.x(); _y-=_.y(); _z-=_.z(); return *this; }
inline V& operator*=(V& _) { return (*this).cross(_); }
inline S dot (V& _) const { return _x*_.x() + _y*_.y() + _z*_.z(); }
inline S length () const { S res = (*this).dot(*this); return res; }// Const::sqrt(res); }
inline S triple(const V& _, const V& __) const {
return _x * (_.y() * __.z() - _.z() * __.y()) +
_y * (_.z() * __.x() - _.x() * __.z()) +
_z * (_.x() * __.y() - _.y() * __.x());
}
inline V& cross(V& _) {
return Vector::clone(
_y * _.z() - _z * _.y(),
_z * _.x() - _x * _.z(),
_x * _.y() - _y * _.x()
);
}
static V clone(const S& x, const S& y, const S& z) {
Vector<S> res;
return res.set(x, y, z);
}
}; // struct Vector
} // namespace lsr
#endif // _MATH_VECTOR_H
#ifndef _MATH_MATRIX_HPP
#define _MATH_MATRIX_HPP
#include <stdio.h>
#include "Vector.hpp"
namespace lsr {
template <typename S=double>
struct Matrix {
typedef Vector<S> V;
typedef Matrix<S> M;
int rows{3};
int cols{3};
V _[3];
inline V& operator[] (int i) { return _[i]; }
inline S& operator() (int j, int i) const { return _[i][j]; }
inline S& get (int j, int i) const { return _[i][j]; }
inline V& get (int j) { return V.clone(_[0][j], _[1][j], _[2][j]); }
inline M& set (int j, int i, const S& _ij) { _[i][j] = _ij; return *this; }
inline M& set (
const S& xx, const S& xy, const S& xz,
const S& yx, const S& yy, const S& yz,
const S& zx, const S& zy, const S& zz) {
_[0].set(xx, yx, zx);
_[1].set(xy, yy, zy);
_[2].set(xz, yz, zz);
return *this;
}
explicit Matrix(int unused = 0) {}
Matrix (
const S& xx, const S& xy, const S& xz,
const S& yx, const S& yy, const S& yz,
const S& zx, const S& zy, const S& zz) {
set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
}
inline Matrix(M& m) {
_[0] = m._[0];
_[1] = m._[1];
_[2] = m._[2];
}
/**
* Math
*/
inline S tdotx (const V& v) const { return get(0).dot(v); }
inline S tdoty (const V& v) const { return get(1).dot(v); }
inline S tdotz (const V& v) const { return get(2).dot(v); }
inline M& fill (const S& v) { return set(v, v, v, v, v, v, v, v, v); }
inline M& operator = (M& m) { _[0] =m[0]; _[1] =m[1]; _[2] =m[2]; return *this; }
inline M& operator+= (M& m) { _[0]+=m[0]; _[1]+=m[1]; _[2]+=m[2]; return *this; }
inline M& operator-= (M& m) { _[0]-=m[0]; _[1]-=m[1]; _[2]-=m[2]; return *this; }
inline M& operator*= (M& m) {
set(
tdotx(m[0]), tdotx(m[1]), tdotx(m[2]),
tdoty(m[0]), tdoty(m[1]), tdoty(m[2]),
tdotz(m[0]), tdotz(m[1]), tdotz(m[2])
);
return *this;
}
static M clone (
const S& xx, const S& xy, const S& xz,
const S& yx, const S& yy, const S& yz,
const S& zx, const S& zy, const S& zz) {
Matrix<S> res;
return res.set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
}
}; // struct Matrix
} // namespace lsr
#endif // _MASH_Matrix_HPP