WebCFace 2.5.2
Web-based Communication Framework & Dashboard-like UI
Loading...
Searching...
No Matches
transform.h
Go to the documentation of this file.
1#pragma once
2#ifdef WEBCFACE_MESON
3#include "webcface-config.h"
4#else
5#include "webcface/common/webcface-config.h"
6#endif
7#include "array_like.h"
8#include <array>
9#include <optional>
10#include <cassert>
11
13
14class Transform;
15
23class Point {
24 protected:
25 std::array<double, 3> pos_;
26
27 public:
32 Point(const std::array<double, 3> &pos = {0, 0, 0}) : pos_(pos) {}
37 Point(const std::array<double, 2> &pos) : pos_({pos[0], pos[1], 0}) {}
42 Point(double x, double y, double z = 0)
43 : Point(std::array<double, 3>{x, y, z}) {}
52 template <typename R,
53 typename traits::ArrayLikeTrait<R>::ArrayLike = traits::TraitOk,
54 typename traits::ArraySizeTrait<R, 3>::SizeMatchOrDynamic =
55 traits::TraitOk>
56 Point(const R &pos) : pos_(traits::arrayLikeToArray<3>(pos)) {}
57
62 std::array<double, 3> pos() const { return pos_; }
67 std::array<double, 3> &pos() { return pos_; }
73 double pos(std::size_t index) const { return pos_.at(index); }
79 double &pos(std::size_t i) { return pos_.at(i); }
80
85 Point operator+(const Point &other) const {
86 return {
87 pos_[0] + other.pos_[0],
88 pos_[1] + other.pos_[1],
89 pos_[2] + other.pos_[2],
90 };
91 }
96 Point operator-() const { return {-pos_[0], -pos_[1], -pos_[2]}; }
103 Point operator+() const { return *this; }
110 Point operator-(const Point &other) const { return *this + (-other); }
114 Point &operator+=(const Point &other) {
115 pos_[0] += other.pos_[0];
116 pos_[1] += other.pos_[1];
117 pos_[2] += other.pos_[2];
118 return *this;
119 }
123 Point &operator-=(const Point &other) { return *this += (-other); }
124
129 Point operator*(double scalar) const {
130 return {pos_[0] * scalar, pos_[1] * scalar, pos_[2] * scalar};
131 }
136 friend Point operator*(double scalar, const Point &point) {
137 return point * scalar;
138 }
142 Point &operator*=(double scalar) {
143 pos_[0] *= scalar;
144 pos_[1] *= scalar;
145 pos_[2] *= scalar;
146 return *this;
147 }
152 Point operator/(double scalar) const {
153 return {pos_[0] / scalar, pos_[1] / scalar, pos_[2] / scalar};
154 }
158 Point &operator/=(double scalar) {
159 pos_[0] /= scalar;
160 pos_[1] /= scalar;
161 pos_[2] /= scalar;
162 return *this;
163 }
164
170 WEBCFACE_DLL bool operator==(const Point &other) const;
171 bool operator!=(const Point &other) const { return !(*this == other); }
172
173 bool operator==(const Transform &) = delete;
174 bool operator!=(const Transform &) = delete;
175};
176
191enum class AxisSequence {
192 ZXZ,
193 XYX,
194 YZY,
195 ZYZ,
196 XZX,
197 YXY,
198 XYZ,
199 YZX,
200 ZXY,
201 XZY,
202 ZYX,
203 YXZ,
204};
205
221class Rotation {
222 protected:
223 // rot_とrmat_のどちらかには必ず値が入っている。
224 // 両方に値が入っているなら両方とも同じ回転を表現していなければならない。
225 mutable std::optional<std::array<double, 3>> rot_;
226 mutable std::optional<std::array<std::array<double, 3>, 3>> rmat_;
227
228 Rotation(const std::optional<std::array<double, 3>> &rot,
229 const std::optional<std::array<std::array<double, 3>, 3>> &rmat)
230 : rot_(rot), rmat_(rmat) {}
231
232 public:
233 friend class Transform;
234
239 static WEBCFACE_DLL std::array<std::array<double, 3>, 3>
240 eulerToMatrix(const std::array<double, 3> &rot, AxisSequence axis);
245 static WEBCFACE_DLL std::array<double, 3>
246 matrixToEuler(const std::array<std::array<double, 3>, 3> &rmat,
247 AxisSequence axis);
248
256 static WEBCFACE_DLL std::array<std::array<double, 3>, 3>
257 quaternionToMatrix(const std::array<double, 4> &quat);
262 static WEBCFACE_DLL std::array<double, 4>
263 matrixToQuaternion(const std::array<std::array<double, 3>, 3> &rmat);
264
269 static WEBCFACE_DLL std::array<double, 4>
270 axisAngleToQuaternion(const std::array<double, 3> &axis, double angle);
275 static WEBCFACE_DLL std::pair<std::array<double, 3>, double>
276 quaternionToAxisAngle(const std::array<double, 4> &quat);
277
279 : rot_({0, 0, 0}), rmat_({{
280 {{1, 0, 0}},
281 {{0, 1, 0}},
282 {{0, 0, 1}},
283 }}) {}
284
285 friend Rotation rotFromEuler(const std::array<double, 3> &rot,
286 AxisSequence axis);
287 friend Rotation
288 rotFromMatrix(const std::array<std::array<double, 3>, 3> &matrix);
289
295 [[deprecated("use rotEuler() or rot2D()")]]
296 std::array<double, 3> rot() const {
297 return rotEuler();
298 }
299
306 [[deprecated("use rotEuler() or rot2D()")]]
307 double rot(std::size_t index) const {
308 return rotEuler().at(index);
309 }
315 [[deprecated("use rotEuler() or rot2D()")]]
316 std::array<double, 3> &rot() {
317 rotEuler();
318 rmat_ = std::nullopt;
319 return *rot_;
320 }
327 [[deprecated("use rotEuler() or rot2D()")]]
328 double &rot(std::size_t index) {
329 rotEuler();
330 rmat_ = std::nullopt;
331 return rot_->at(index);
332 }
333
341 double rot2D() const { return rotEuler()[0]; }
349 std::array<double, 3>
350 rotEuler(AxisSequence axis = AxisSequence::ZYX) const {
351 if (axis == AxisSequence::ZYX) {
352 if (!rot_) {
353 assert(rmat_);
354 rot_.emplace(matrixToEuler(*rmat_, AxisSequence::ZYX));
355 }
356 return *rot_;
357 } else {
358 return matrixToEuler(rotMatrix(), axis);
359 }
360 }
361
366 const std::array<std::array<double, 3>, 3> &rotMatrix() const {
367 if (!rmat_) {
368 assert(rot_);
369 rmat_.emplace(eulerToMatrix(*rot_, AxisSequence::ZYX));
370 }
371 return *rmat_;
372 }
377 double rotMatrix(std::size_t row, std::size_t col) const {
378 return rotMatrix().at(row).at(col);
379 }
380
385 std::array<double, 4> rotQuat() const {
386 return matrixToQuaternion(rotMatrix());
387 }
392 std::pair<std::array<double, 3>, double> rotAxisAngle() const {
393 return quaternionToAxisAngle(rotQuat());
394 }
395
404 WEBCFACE_DLL Transform appliedTo(const Transform &target) const;
410 WEBCFACE_DLL Transform operator*(const Transform &target) const;
419 WEBCFACE_DLL Rotation appliedTo(const Rotation &target) const;
425 WEBCFACE_DLL Rotation operator*(const Rotation &target) const;
434 WEBCFACE_DLL Point appliedTo(const Point &target) const;
440 WEBCFACE_DLL Point operator*(const Point &target) const;
441
449 WEBCFACE_DLL Rotation inversed() const;
450
458 Rotation &operator*=(const Rotation &target) {
459 *this = *this * target;
460 return *this;
461 }
462
468 WEBCFACE_DLL bool operator==(const Rotation &other) const;
469 bool operator!=(const Rotation &other) const { return !(*this == other); }
470
471 WEBCFACE_DLL bool operator==(const Transform &other) const;
472 bool operator!=(const Transform &other) const { return !(*this == other); }
473};
474
482inline Rotation rotFromEuler(const std::array<double, 3> &rot,
483 AxisSequence axis = AxisSequence::ZYX) {
484 if (axis == AxisSequence::ZYX) {
485 return {rot, std::nullopt};
486 } else {
487 return {std::nullopt, Rotation::eulerToMatrix(rot, axis)};
488 }
489}
498template <
499 typename R, typename traits::ArrayLikeTrait<R>::ArrayLike = traits::TraitOk,
500 typename traits::ArraySizeTrait<R, 3>::SizeMatchOrDynamic = traits::TraitOk>
501inline Rotation rotFromEuler(const R &rot,
502 AxisSequence axis = AxisSequence::ZYX) {
503 return rotFromEuler(traits::arrayLikeToArray<3>(rot), axis);
504}
511inline Rotation rotFromEuler(double angle1, double angle2, double angle3,
512 AxisSequence axis = AxisSequence::ZYX) {
513 return rotFromEuler(std::array<double, 3>{angle1, angle2, angle3}, axis);
514}
524inline Rotation
525rotFromMatrix(const std::array<std::array<double, 3>, 3> &matrix) {
526 return {std::nullopt, matrix};
527}
534inline Rotation rotFromQuat(const std::array<double, 4> &quat) {
535 return rotFromMatrix(Rotation::quaternionToMatrix(quat));
536}
544template <
545 typename R, typename traits::ArrayLikeTrait<R>::ArrayLike = traits::TraitOk,
546 typename traits::ArraySizeTrait<R, 4>::SizeMatchOrDynamic = traits::TraitOk>
547inline Rotation rotFromQuat(const R &quat) {
548 return rotFromQuat(traits::arrayLikeToArray<4>(quat));
549}
554inline Rotation rotFromQuat(double w, double x, double y, double z) {
555 return rotFromQuat({w, x, y, z});
556}
561inline Rotation rotFromAxisAngle(const std::array<double, 3> &axis,
562 double angle) {
563 return rotFromQuat(Rotation::axisAngleToQuaternion(axis, angle));
564}
572template <
573 typename R, typename traits::ArrayLikeTrait<R>::ArrayLike = traits::TraitOk,
574 typename traits::ArraySizeTrait<R, 3>::SizeMatchOrDynamic = traits::TraitOk>
575inline Rotation rotFromAxisAngle(const R &axis, double angle) {
576 return rotFromAxisAngle(traits::arrayLikeToArray<3>(axis), angle);
577}
578
587inline Rotation rot2D(double rot) { return rotFromEuler(rot, 0, 0); }
592inline Rotation rotX(double rot) { return rotFromEuler(0, 0, rot); }
597inline Rotation rotY(double rot) { return rotFromEuler(0, rot, 0); }
605inline Rotation rotZ(double rot) { return rotFromEuler(rot, 0, 0); }
606
615class Transform : private Point, private Rotation {
616 public:
621 Transform(const Point &pos, const Rotation &rot)
622 : Point(pos), Rotation(rot) {}
623
628 Transform(const Rotation &rot) : Point(), Rotation(rot) {}
629
638 [[deprecated("use Transform(pos, rotEuler(rot))")]]
639 Transform(const Point &pos, const std::array<double, 3> &rot)
640 : Transform(pos, Rotation{rot, std::nullopt}) {}
641
649 Transform(const Point &pos, double rot)
650 : Transform(pos, webcface::rot2D(rot)) {};
656 [[deprecated("use Transform({x, y, z}, rotEuler(z, y, x))")]]
657 Transform(double x, double y, double z, double z_angle, double y_angle,
658 double x_angle)
659 : Transform(std::array<double, 3>{x, y, z},
660 Rotation{std::array<double, 3>{z_angle, y_angle, x_angle},
661 std::nullopt}) {}
667 [[deprecated("use translation(x, y) for translation-only transform")]]
668 Transform(double x, double y)
669 : Transform({x, y}, 0) {}
670
671 friend class Point;
672 friend class Rotation;
673 using Point::pos;
674 using Rotation::rot;
675 using Rotation::rot2D;
676 using Rotation::rotAxisAngle;
677 using Rotation::rotEuler;
678 using Rotation::rotMatrix;
679 using Rotation::rotQuat;
680
692 WEBCFACE_DLL Transform appliedTo(const Transform &target) const;
703 Transform operator*(const Transform &target) const {
704 return this->appliedTo(target);
705 }
718 Transform appliedTo(const Rotation &target) const {
719 return this->appliedTo(Transform(target));
720 }
726 Transform operator*(const Rotation &target) const {
727 return this->appliedTo(target);
728 }
737 *this = *this * target;
738 return *this;
739 }
740
752 WEBCFACE_DLL Point appliedTo(const Point &target) const;
763 Point operator*(const Point &target) const {
764 return this->appliedTo(target);
765 }
766
771 WEBCFACE_DLL Transform inversed() const;
772
778 bool operator==(const Transform &other) const {
779 return Point(*this) == Point(other) &&
780 Rotation(*this) == Rotation(other);
781 }
782 bool operator!=(const Transform &other) const { return !(*this == other); }
783
784 bool operator==(const Rotation &other) const {
785 return *this == Transform(other);
786 }
787 bool operator!=(const Rotation &other) const { return !(*this == other); }
788};
789
794inline Transform identity() { return {}; }
799inline Transform translation(const Point &pos) { return {pos, Rotation{}}; }
804inline Transform translation(double x, double y, double z) {
805 return {{x, y, z}, Rotation{}};
806}
811inline Transform translation(double x, double y) { return {{x, y}, 0}; }
812
3次元 or 2次元の座標を表すクラス。
Definition transform.h:23
Point(const R &pos)
3次元座標を初期化
Definition transform.h:56
Point operator/(double scalar) const
x, y, z の各要素をスカラーで割ったPointを返す
Definition transform.h:152
double pos(std::size_t index) const
座標を取得
Definition transform.h:73
bool operator!=(const Point &other) const
Definition transform.h:171
friend Point operator*(double scalar, const Point &point)
x, y, z の各要素をスカラー倍したPointを返す
Definition transform.h:136
Point & operator/=(double scalar)
Definition transform.h:158
Point operator-() const
x, y, z の各要素の符号を反転したPointを返す
Definition transform.h:96
bool operator!=(const Transform &)=delete
Point operator+(const Point &other) const
2つのPointの x, y, z の各要素を加算したPointを返す
Definition transform.h:85
std::array< double, 3 > pos() const
3次元座標を取得
Definition transform.h:62
Point(const std::array< double, 3 > &pos={0, 0, 0})
3次元座標を初期化
Definition transform.h:32
Point & operator*=(double scalar)
Definition transform.h:142
Point operator-(const Point &other) const
Definition transform.h:110
double & pos(std::size_t i)
座標を取得・変更
Definition transform.h:79
std::array< double, 3 > pos_
Definition transform.h:25
Point & operator+=(const Point &other)
Definition transform.h:114
Point & operator-=(const Point &other)
Definition transform.h:123
Point(const std::array< double, 2 > &pos)
2次元座標を初期化
Definition transform.h:37
Point operator+() const
Definition transform.h:103
Point operator*(double scalar) const
x, y, z の各要素をスカラー倍したPointを返す
Definition transform.h:129
Point(double x, double y, double z=0)
2or3次元座標を初期化
Definition transform.h:42
bool operator==(const Transform &)=delete
std::array< double, 3 > & pos()
3次元座標を取得・変更
Definition transform.h:67
3次元の回転を表すクラス
Definition transform.h:221
bool operator!=(const Transform &other) const
Definition transform.h:472
std::array< double, 3 > & rot()
3次元の回転をオイラー角として取得・変更
Definition transform.h:316
std::pair< std::array< double, 3 >, double > rotAxisAngle() const
回転軸と角度として取得
Definition transform.h:392
double & rot(std::size_t index)
3次元の回転をZYX順のオイラー角として取得・変更
Definition transform.h:328
std::optional< std::array< double, 3 > > rot_
Definition transform.h:225
double rot(std::size_t index) const
3次元の回転をZYX順のオイラー角として取得
Definition transform.h:307
bool operator!=(const Rotation &other) const
Definition transform.h:469
const std::array< std::array< double, 3 >, 3 > & rotMatrix() const
回転行列を取得
Definition transform.h:366
std::array< double, 3 > rot() const
3次元の回転をオイラー角として取得
Definition transform.h:296
Rotation()
Definition transform.h:278
double rot2D() const
2次元の回転を取得
Definition transform.h:341
std::optional< std::array< std::array< double, 3 >, 3 > > rmat_
Definition transform.h:226
double rotMatrix(std::size_t row, std::size_t col) const
回転行列の要素を取得
Definition transform.h:377
Rotation(const std::optional< std::array< double, 3 > > &rot, const std::optional< std::array< std::array< double, 3 >, 3 > > &rmat)
Definition transform.h:228
Rotation & operator*=(const Rotation &target)
このRotationを別のRotationに適用した結果で置き換える
Definition transform.h:458
std::array< double, 3 > rotEuler(AxisSequence axis=AxisSequence::ZYX) const
3次元の回転をオイラー角として取得
Definition transform.h:350
std::array< double, 4 > rotQuat() const
クォータニオンとして取得
Definition transform.h:385
3次元の平行移動と回転
Definition transform.h:615
bool operator!=(const Transform &other) const
Definition transform.h:782
Point operator*(const Point &target) const
このTransformをPointに適用する
Definition transform.h:763
Transform & operator*=(const Transform &target)
このTransformを別のTransformに適用した結果で置き換える
Definition transform.h:736
Transform(double x, double y)
2次元の座標を初期化
Definition transform.h:668
Transform(double x, double y, double z, double z_angle, double y_angle, double x_angle)
3次元の座標と回転をオイラー角から初期化
Definition transform.h:657
bool operator!=(const Rotation &other) const
Definition transform.h:787
Transform(const Point &pos, const Rotation &rot)
Definition transform.h:621
bool operator==(const Rotation &other) const
Definition transform.h:784
Transform(const Point &pos, double rot)
2次元の座標と回転を初期化
Definition transform.h:649
Transform()
Definition transform.h:617
Transform operator*(const Transform &target) const
このTransformを別のTransformに適用する
Definition transform.h:703
bool operator==(const Transform &other) const
Definition transform.h:778
Transform appliedTo(const Rotation &target) const
このTransformをRotationに適用する
Definition transform.h:718
Transform(const Rotation &rot)
回転のみの場合Rotationからキャスト
Definition transform.h:628
Transform(const Point &pos, const std::array< double, 3 > &rot)
オイラー角から初期化
Definition transform.h:639
Transform operator*(const Rotation &target) const
このTransformをRotationに適用する
Definition transform.h:726
Definition arg.h:14
Rotation rotFromQuat(const std::array< double, 4 > &quat)
回転をクォータニオンから初期化
Definition transform.h:534
Rotation rotX(double rot)
X軸周りの回転
Definition transform.h:592
Rotation rotFromMatrix(const std::array< std::array< double, 3 >, 3 > &matrix)
回転を回転行列から初期化
Definition transform.h:525
bool operator==(const T &other, const InputRef &ref)
Definition text.h:566
Rotation rotY(double rot)
Y軸周りの回転
Definition transform.h:597
Rotation rotFromEuler(const std::array< double, 3 > &rot, AxisSequence axis=AxisSequence::ZYX)
回転をオイラー角から初期化
Definition transform.h:482
AxisSequence
オイラー角の回転順序
Definition transform.h:191
Rotation rotFromAxisAngle(const std::array< double, 3 > &axis, double angle)
回転を回転軸と角度から初期化
Definition transform.h:561
Transform identity()
移動なし、回転なしのTransform
Definition transform.h:794
Rotation rotZ(double rot)
Z軸周りの回転
Definition transform.h:605
Transform translation(const Point &pos)
平行移動のみのTransform
Definition transform.h:799
Rotation rot2D(double rot)
2次元の回転を初期化
Definition transform.h:587
Definition array_like.h:58
Definition array_like.h:75
#define WEBCFACE_DLL
Definition webcface-config.h:60
#define WEBCFACE_NS_END
Definition webcface-config.h:104
#define WEBCFACE_NS_BEGIN
Definition webcface-config.h:103