WebCFace 2.9.0
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
219struct AxisAngle {
220 std::array<double, 3> axis;
221 double angle;
222 AxisAngle(const std::array<double, 3> &axis, double angle) noexcept
223 : axis(axis), angle(angle) {}
224
225 [[deprecated]]
226 operator std::pair<std::array<double, 3>, double>() const noexcept {
227 return {axis, angle};
228 }
229};
230template <std::size_t I>
231const auto &get(const AxisAngle &aa) {
232 static_assert(I < 2);
233 if constexpr (I == 0) {
234 return aa.axis;
235 } else {
236 return aa.angle;
237 }
238}
239
255class Rotation {
256 protected:
257 // rot_とrmat_のどちらかには必ず値が入っている。
258 // 両方に値が入っているなら両方とも同じ回転を表現していなければならない。
259 mutable std::optional<std::array<double, 3>> rot_;
260 mutable std::optional<std::array<std::array<double, 3>, 3>> rmat_;
261
262 Rotation(const std::optional<std::array<double, 3>> &rot,
263 const std::optional<std::array<std::array<double, 3>, 3>> &rmat)
264 : rot_(rot), rmat_(rmat) {}
265
266 public:
267 friend class Transform;
268
273 static WEBCFACE_DLL std::array<std::array<double, 3>, 3>
274 eulerToMatrix(const std::array<double, 3> &rot, AxisSequence axis);
279 static WEBCFACE_DLL std::array<double, 3>
280 matrixToEuler(const std::array<std::array<double, 3>, 3> &rmat,
281 AxisSequence axis);
282
290 static WEBCFACE_DLL std::array<std::array<double, 3>, 3>
291 quaternionToMatrix(const std::array<double, 4> &quat);
296 static WEBCFACE_DLL std::array<double, 4>
297 matrixToQuaternion(const std::array<std::array<double, 3>, 3> &rmat);
298
303 static WEBCFACE_DLL std::array<double, 4>
304 axisAngleToQuaternion(const std::array<double, 3> &axis, double angle);
310 quaternionToAxisAngle(const std::array<double, 4> &quat);
311
313 : rot_({0, 0, 0}), rmat_({{
314 {{1, 0, 0}},
315 {{0, 1, 0}},
316 {{0, 0, 1}},
317 }}) {}
318
319 friend Rotation rotFromEuler(const std::array<double, 3> &rot,
320 AxisSequence axis);
321 friend Rotation
322 rotFromMatrix(const std::array<std::array<double, 3>, 3> &matrix);
323
329 [[deprecated("use rotEuler() or rot2D()")]]
330 std::array<double, 3> rot() const {
331 return rotEuler();
332 }
333
340 [[deprecated("use rotEuler() or rot2D()")]]
341 double rot(std::size_t index) const {
342 return rotEuler().at(index);
343 }
349 [[deprecated("use rotEuler() or rot2D()")]]
350 std::array<double, 3> &rot() {
351 rotEuler();
352 rmat_ = std::nullopt;
353 return *rot_;
354 }
361 [[deprecated("use rotEuler() or rot2D()")]]
362 double &rot(std::size_t index) {
363 rotEuler();
364 rmat_ = std::nullopt;
365 return rot_->at(index);
366 }
367
375 double rot2D() const { return rotEuler()[0]; }
383 std::array<double, 3>
384 rotEuler(AxisSequence axis = AxisSequence::ZYX) const {
385 if (axis == AxisSequence::ZYX) {
386 if (!rot_) {
387 assert(rmat_);
388 rot_.emplace(matrixToEuler(*rmat_, AxisSequence::ZYX));
389 }
390 return *rot_;
391 } else {
392 return matrixToEuler(rotMatrix(), axis);
393 }
394 }
395
400 const std::array<std::array<double, 3>, 3> &rotMatrix() const {
401 if (!rmat_) {
402 assert(rot_);
403 rmat_.emplace(eulerToMatrix(*rot_, AxisSequence::ZYX));
404 }
405 return *rmat_;
406 }
411 double rotMatrix(std::size_t row, std::size_t col) const {
412 return rotMatrix().at(row).at(col);
413 }
414
419 std::array<double, 4> rotQuat() const {
420 return matrixToQuaternion(rotMatrix());
421 }
431 AxisAngle rotAxisAngle() const { return quaternionToAxisAngle(rotQuat()); }
432
441 WEBCFACE_DLL Transform appliedTo(const Transform &target) const;
447 WEBCFACE_DLL Transform operator*(const Transform &target) const;
456 WEBCFACE_DLL Rotation appliedTo(const Rotation &target) const;
462 WEBCFACE_DLL Rotation operator*(const Rotation &target) const;
471 WEBCFACE_DLL Point appliedTo(const Point &target) const;
477 WEBCFACE_DLL Point operator*(const Point &target) const;
478
486 WEBCFACE_DLL Rotation inversed() const;
487
495 Rotation &operator*=(const Rotation &target) {
496 *this = *this * target;
497 return *this;
498 }
499
505 WEBCFACE_DLL bool operator==(const Rotation &other) const;
506 bool operator!=(const Rotation &other) const { return !(*this == other); }
507
508 WEBCFACE_DLL bool operator==(const Transform &other) const;
509 bool operator!=(const Transform &other) const { return !(*this == other); }
510};
511
519inline Rotation rotFromEuler(const std::array<double, 3> &rot,
520 AxisSequence axis = AxisSequence::ZYX) {
521 if (axis == AxisSequence::ZYX) {
522 return {rot, std::nullopt};
523 } else {
524 return {std::nullopt, Rotation::eulerToMatrix(rot, axis)};
525 }
526}
535template <
536 typename R, typename traits::ArrayLikeTrait<R>::ArrayLike = traits::TraitOk,
537 typename traits::ArraySizeTrait<R, 3>::SizeMatchOrDynamic = traits::TraitOk>
538inline Rotation rotFromEuler(const R &rot,
539 AxisSequence axis = AxisSequence::ZYX) {
540 return rotFromEuler(traits::arrayLikeToArray<3>(rot), axis);
541}
548inline Rotation rotFromEuler(double angle1, double angle2, double angle3,
549 AxisSequence axis = AxisSequence::ZYX) {
550 return rotFromEuler(std::array<double, 3>{angle1, angle2, angle3}, axis);
551}
561inline Rotation
562rotFromMatrix(const std::array<std::array<double, 3>, 3> &matrix) {
563 return {std::nullopt, matrix};
564}
571inline Rotation rotFromQuat(const std::array<double, 4> &quat) {
572 return rotFromMatrix(Rotation::quaternionToMatrix(quat));
573}
581template <
582 typename R, typename traits::ArrayLikeTrait<R>::ArrayLike = traits::TraitOk,
583 typename traits::ArraySizeTrait<R, 4>::SizeMatchOrDynamic = traits::TraitOk>
584inline Rotation rotFromQuat(const R &quat) {
585 return rotFromQuat(traits::arrayLikeToArray<4>(quat));
586}
591inline Rotation rotFromQuat(double w, double x, double y, double z) {
592 return rotFromQuat({w, x, y, z});
593}
598inline Rotation rotFromAxisAngle(const std::array<double, 3> &axis,
599 double angle) {
600 return rotFromQuat(Rotation::axisAngleToQuaternion(axis, angle));
601}
609template <
610 typename R, typename traits::ArrayLikeTrait<R>::ArrayLike = traits::TraitOk,
611 typename traits::ArraySizeTrait<R, 3>::SizeMatchOrDynamic = traits::TraitOk>
612inline Rotation rotFromAxisAngle(const R &axis, double angle) {
613 return rotFromAxisAngle(traits::arrayLikeToArray<3>(axis), angle);
614}
615
624inline Rotation rot2D(double rot) { return rotFromEuler(rot, 0, 0); }
629inline Rotation rotX(double rot) { return rotFromEuler(0, 0, rot); }
634inline Rotation rotY(double rot) { return rotFromEuler(0, rot, 0); }
642inline Rotation rotZ(double rot) { return rotFromEuler(rot, 0, 0); }
643
652class Transform : private Point, private Rotation {
653 public:
658 Transform(const Point &pos, const Rotation &rot)
659 : Point(pos), Rotation(rot) {}
660
665 Transform(const Rotation &rot) : Point(), Rotation(rot) {}
666
675 [[deprecated("use Transform(pos, rotEuler(rot))")]]
676 Transform(const Point &pos, const std::array<double, 3> &rot)
677 : Transform(pos, Rotation{rot, std::nullopt}) {}
678
686 Transform(const Point &pos, double rot)
687 : Transform(pos, webcface::rot2D(rot)) {};
693 [[deprecated("use Transform({x, y, z}, rotEuler(z, y, x))")]]
694 Transform(double x, double y, double z, double z_angle, double y_angle,
695 double x_angle)
696 : Transform(std::array<double, 3>{x, y, z},
697 Rotation{std::array<double, 3>{z_angle, y_angle, x_angle},
698 std::nullopt}) {}
704 [[deprecated("use translation(x, y) for translation-only transform")]]
705 Transform(double x, double y)
706 : Transform({x, y}, 0) {}
707
708 friend class Point;
709 friend class Rotation;
710 using Point::pos;
711 using Rotation::rot;
712 using Rotation::rot2D;
713 using Rotation::rotAxisAngle;
714 using Rotation::rotEuler;
715 using Rotation::rotMatrix;
716 using Rotation::rotQuat;
717
729 WEBCFACE_DLL Transform appliedTo(const Transform &target) const;
740 Transform operator*(const Transform &target) const {
741 return this->appliedTo(target);
742 }
755 Transform appliedTo(const Rotation &target) const {
756 return this->appliedTo(Transform(target));
757 }
763 Transform operator*(const Rotation &target) const {
764 return this->appliedTo(target);
765 }
774 *this = *this * target;
775 return *this;
776 }
777
789 WEBCFACE_DLL Point appliedTo(const Point &target) const;
800 Point operator*(const Point &target) const {
801 return this->appliedTo(target);
802 }
803
808 WEBCFACE_DLL Transform inversed() const;
809
815 bool operator==(const Transform &other) const {
816 return Point(*this) == Point(other) &&
817 Rotation(*this) == Rotation(other);
818 }
819 bool operator!=(const Transform &other) const { return !(*this == other); }
820
821 bool operator==(const Rotation &other) const {
822 return *this == Transform(other);
823 }
824 bool operator!=(const Rotation &other) const { return !(*this == other); }
825};
826
831inline Transform identity() { return {}; }
836inline Transform translation(const Point &pos) { return {pos, Rotation{}}; }
841inline Transform translation(double x, double y, double z) {
842 return {{x, y, z}, Rotation{}};
843}
848inline Transform translation(double x, double y) { return {{x, y}, 0}; }
849
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:255
bool operator!=(const Transform &other) const
Definition transform.h:509
std::array< double, 3 > & rot()
3次元の回転をオイラー角として取得・変更
Definition transform.h:350
AxisAngle rotAxisAngle() const
回転軸と角度として取得
Definition transform.h:431
double & rot(std::size_t index)
3次元の回転をZYX順のオイラー角として取得・変更
Definition transform.h:362
std::optional< std::array< double, 3 > > rot_
Definition transform.h:259
double rot(std::size_t index) const
3次元の回転をZYX順のオイラー角として取得
Definition transform.h:341
bool operator!=(const Rotation &other) const
Definition transform.h:506
const std::array< std::array< double, 3 >, 3 > & rotMatrix() const
回転行列を取得
Definition transform.h:400
std::array< double, 3 > rot() const
3次元の回転をオイラー角として取得
Definition transform.h:330
Rotation()
Definition transform.h:312
double rot2D() const
2次元の回転を取得
Definition transform.h:375
std::optional< std::array< std::array< double, 3 >, 3 > > rmat_
Definition transform.h:260
double rotMatrix(std::size_t row, std::size_t col) const
回転行列の要素を取得
Definition transform.h:411
Rotation(const std::optional< std::array< double, 3 > > &rot, const std::optional< std::array< std::array< double, 3 >, 3 > > &rmat)
Definition transform.h:262
Rotation & operator*=(const Rotation &target)
このRotationを別のRotationに適用した結果で置き換える
Definition transform.h:495
std::array< double, 3 > rotEuler(AxisSequence axis=AxisSequence::ZYX) const
3次元の回転をオイラー角として取得
Definition transform.h:384
std::array< double, 4 > rotQuat() const
クォータニオンとして取得
Definition transform.h:419
3次元の平行移動と回転
Definition transform.h:652
bool operator!=(const Transform &other) const
Definition transform.h:819
Point operator*(const Point &target) const
このTransformをPointに適用する
Definition transform.h:800
Transform & operator*=(const Transform &target)
このTransformを別のTransformに適用した結果で置き換える
Definition transform.h:773
Transform(double x, double y)
2次元の座標を初期化
Definition transform.h:705
Transform(double x, double y, double z, double z_angle, double y_angle, double x_angle)
3次元の座標と回転をオイラー角から初期化
Definition transform.h:694
bool operator!=(const Rotation &other) const
Definition transform.h:824
Transform(const Point &pos, const Rotation &rot)
Definition transform.h:658
bool operator==(const Rotation &other) const
Definition transform.h:821
Transform(const Point &pos, double rot)
2次元の座標と回転を初期化
Definition transform.h:686
Transform()
Definition transform.h:654
Transform operator*(const Transform &target) const
このTransformを別のTransformに適用する
Definition transform.h:740
bool operator==(const Transform &other) const
Definition transform.h:815
Transform appliedTo(const Rotation &target) const
このTransformをRotationに適用する
Definition transform.h:755
Transform(const Rotation &rot)
回転のみの場合Rotationからキャスト
Definition transform.h:665
Transform(const Point &pos, const std::array< double, 3 > &rot)
オイラー角から初期化
Definition transform.h:676
Transform operator*(const Rotation &target) const
このTransformをRotationに適用する
Definition transform.h:763
Definition arg.h:14
Rotation rotFromQuat(const std::array< double, 4 > &quat)
回転をクォータニオンから初期化
Definition transform.h:571
Rotation rotX(double rot)
X軸周りの回転
Definition transform.h:629
Rotation rotFromMatrix(const std::array< std::array< double, 3 >, 3 > &matrix)
回転を回転行列から初期化
Definition transform.h:562
bool operator==(const T &other, const InputRef &ref)
Definition text.h:574
Rotation rotY(double rot)
Y軸周りの回転
Definition transform.h:634
Rotation rotFromEuler(const std::array< double, 3 > &rot, AxisSequence axis=AxisSequence::ZYX)
回転をオイラー角から初期化
Definition transform.h:519
AxisSequence
オイラー角の回転順序
Definition transform.h:191
const auto & get(const AxisAngle &aa)
Definition transform.h:231
Rotation rotFromAxisAngle(const std::array< double, 3 > &axis, double angle)
回転を回転軸と角度から初期化
Definition transform.h:598
Transform identity()
移動なし、回転なしのTransform
Definition transform.h:831
Rotation rotZ(double rot)
Z軸周りの回転
Definition transform.h:642
Transform translation(const Point &pos)
平行移動のみのTransform
Definition transform.h:836
Rotation rot2D(double rot)
2次元の回転を初期化
Definition transform.h:624
Definition transform.h:219
double angle
Definition transform.h:221
AxisAngle(const std::array< double, 3 > &axis, double angle) noexcept
Definition transform.h:222
std::array< double, 3 > axis
Definition transform.h:220
Definition array_like.h:58
Definition array_like.h:75
#define WEBCFACE_DLL
Definition webcface-config.h:69
#define WEBCFACE_NS_END
Definition webcface-config.h:118
#define WEBCFACE_NS_BEGIN
Definition webcface-config.h:117