fork download
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <cmath>
  4.  
  5. using namespace std;
  6.  
  7. inline float degToRad(float angle) { return 3.141593f * angle / 180.f; }
  8.  
  9. struct Vec2 {
  10. float x, y;
  11. Vec2(float x, float y): x(x), y(y) { }
  12. };
  13.  
  14. ostream& operator<<(ostream &out, const Vec2 &v)
  15. {
  16. return out << "( " << v.x << ", " << v.y << " )";
  17. }
  18.  
  19. struct Vec3 {
  20. float x, y, z;
  21. Vec3(float x, float y, float z): x(x), y(y), z(z) { }
  22. Vec3(const Vec2 &xy, float z): x(xy.x), y(xy.y), z(z) { }
  23. };
  24.  
  25. ostream& operator<<(ostream &out, const Vec3 &v)
  26. {
  27. return out << "( " << v.x << ", " << v.y << ", " << v.z << " )";
  28. }
  29.  
  30. enum ArgInitRotX { InitRotX };
  31. enum ArgInitRotY { InitRotY };
  32.  
  33. struct Mat3x3 {
  34. union {
  35. float comp[3 * 3];
  36. struct {
  37. float _00, _01, _02, _10, _11, _12, _20, _21, _22;
  38. };
  39. };
  40.  
  41. // constructor to build a matrix by elements
  42. Mat3x3(
  43. float _00, float _01, float _02,
  44. float _10, float _11, float _12,
  45. float _20, float _21, float _22)
  46. {
  47. this->_00 = _00; this->_01 = _01; this->_02 = _02;
  48. this->_10 = _10; this->_11 = _11; this->_12 = _12;
  49. this->_20 = _20; this->_21 = _21; this->_22 = _22;
  50. }
  51. // constructor to build a matrix for rotation about x axis
  52. Mat3x3(ArgInitRotX, float angle)
  53. {
  54. this->_00 = 1.0f; this->_01 = 0.0f; this->_02 = 0.0f;
  55. this->_10 = 0.0f; this->_11 = cos(angle); this->_12 = sin(angle);
  56. this->_20 = 0.0f; this->_21 = -sin(angle); this->_22 = cos(angle);
  57. }
  58. // constructor to build a matrix for rotation about y axis
  59. Mat3x3(ArgInitRotY, float angle)
  60. {
  61. this->_00 = cos(angle); this->_01 = 0.0f; this->_02 = -sin(angle);
  62. this->_10 = 0.0f; this->_11 = 1.0f; this->_12 = 0.0f;
  63. this->_20 = sin(angle); this->_21 = 0.0f; this->_22 = cos(angle);
  64. }
  65. // multiply matrix with matrix -> matrix
  66. Mat3x3 operator * (const Mat3x3 &mat) const
  67. {
  68. return Mat3x3(
  69. _00 * mat._20 + _01 * mat._10 + _02 * mat._20,
  70. _00 * mat._21 + _01 * mat._11 + _02 * mat._21,
  71. _00 * mat._22 + _01 * mat._12 + _02 * mat._22,
  72. _10 * mat._20 + _11 * mat._10 + _12 * mat._20,
  73. _10 * mat._21 + _11 * mat._11 + _12 * mat._21,
  74. _10 * mat._22 + _11 * mat._12 + _12 * mat._22,
  75. _20 * mat._20 + _21 * mat._10 + _22 * mat._20,
  76. _20 * mat._21 + _21 * mat._11 + _22 * mat._21,
  77. _20 * mat._22 + _21 * mat._12 + _22 * mat._22);
  78. }
  79. // multiply matrix with vector -> vector
  80. Vec3 operator * (const Vec3 &vec) const
  81. {
  82. return Vec3(
  83. _00 * vec.x + _01 * vec.y + _02 * vec.z,
  84. _10 * vec.x + _11 * vec.y + _12 * vec.z,
  85. _20 * vec.x + _21 * vec.y + _22 * vec.z);
  86. }
  87. };
  88.  
  89. ostream& operator<<(ostream &out, const Mat3x3 &mat)
  90. {
  91. return out
  92. << mat._20 << ", " << mat._21 << ", " << mat._22 << endl
  93. << mat._10 << ", " << mat._11 << ", " << mat._12 << endl
  94. << mat._20 << ", " << mat._21 << ", " << mat._22;
  95. }
  96.  
  97. int main()
  98. {
  99. // some 2D vector samples (for a quad)
  100. Vec2 quad[] = {
  101. { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }
  102. };
  103. /* Something like this:
  104.   * ^ y
  105.   * |
  106.   * v[3] ---- v[2]
  107.   * | |
  108.   * | |
  109.   * | |
  110.   * v[0] ---- v[1] --> x
  111.   */
  112. // the rotation matrix for isometric view build by multiplying the rotations
  113. Mat3x3 matIso = Mat3x3(InitRotX, degToRad(30.0)) * Mat3x3(InitRotY, degToRad(45.0));
  114. // prepare output formatting
  115. cout << fixed << setprecision(5);
  116. // the rotation matrix for isometric view:
  117. cout << "The matrix for isometric projection:" << endl
  118. << matIso << endl;
  119. // prepare output formatting
  120. cout << fixed << setprecision(3);
  121. // do it for all sample 2D vectors:
  122. cout << "Isometric projection of the 2d quad:" << endl;
  123. for (const Vec2 &v : quad) {
  124. // 2D vector -> 3D vector
  125. Vec3 v_(v, 0.0f);
  126. // project v_ to iso view
  127. v_ = matIso * v_;
  128. // print the result:
  129. cout << v << " -> " << v_ << endl;
  130. }
  131. // doing it again with a 3d cube (centered)
  132. Vec3 cube[] = {
  133. { -0.5f, -0.5f, -0.5f }, { +0.5f, -0.5f, -0.5f }, { +0.5f, +0.5f, -0.5f }, { -0.5f, +0.5f, -0.5f },
  134. { -0.5f, -0.5f, +0.5f }, { +0.5f, -0.5f, +0.5f }, { +0.5f, +0.5f, +0.5f }, { -0.5f, +0.5f, +0.5f }
  135. };
  136. cout << "Isometric projection of the centered 3d cube:" << endl;
  137. for (const Vec3 &v : cube) {
  138. // project v to iso view
  139. Vec3 v_ = matIso * v;
  140. // print the result:
  141. cout << v << " -> " << v_ << endl;
  142. }
  143. // done
  144. return 0;
  145. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
The matrix for isometric projection:
0.61237, -0.50000, 0.61237
0.35355, 0.86603, 0.35355
0.61237, -0.50000, 0.61237
Isometric projection of the 2d quad:
( 0.000, 0.000 ) -> ( 0.000, 0.000, 0.000 )
( 0.000, 1.000 ) -> ( 0.000, 0.866, -0.500 )
( 1.000, 1.000 ) -> ( 0.707, 1.220, 0.112 )
( 1.000, 0.000 ) -> ( 0.707, 0.354, 0.612 )
Isometric projection of the centered 3d cube:
( -0.500, -0.500, -0.500 ) -> ( -0.707, -0.787, -0.362 )
( 0.500, -0.500, -0.500 ) -> ( 0.000, -0.433, 0.250 )
( 0.500, 0.500, -0.500 ) -> ( 0.000, 0.433, -0.250 )
( -0.500, 0.500, -0.500 ) -> ( -0.707, 0.079, -0.862 )
( -0.500, -0.500, 0.500 ) -> ( -0.000, -0.433, 0.250 )
( 0.500, -0.500, 0.500 ) -> ( 0.707, -0.079, 0.862 )
( 0.500, 0.500, 0.500 ) -> ( 0.707, 0.787, 0.362 )
( -0.500, 0.500, 0.500 ) -> ( -0.000, 0.433, -0.250 )