{"id":28,"date":"2011-02-28T07:44:55","date_gmt":"2011-02-28T07:44:55","guid":{"rendered":"https:\/\/davidmazz.com\/?page_id=28"},"modified":"2011-02-28T07:45:41","modified_gmt":"2011-02-28T07:45:41","slug":"code-sample","status":"publish","type":"page","link":"https:\/\/davidmazz.com\/?page_id=28","title":{"rendered":"Code Sample"},"content":{"rendered":"<p>Below is a small sample of code, namely vector and matrix classes. I developed these to help with basic linear algebra, and to use seamlessly with OpenGL. Some examples of how these are used are in the <a href=\"https:\/\/davidmazz.com\/?page_id=11\">Cube World<\/a> project.<\/p>\n<p>vec4.h<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/*\r\n * To avoid normalization problems, addition, subtraction,\r\n * scalar multiplication &amp; division, dot &amp; cross products\r\n * are calculated using xyz only, not w.\r\n *\/\r\n\r\n#ifndef Vec4_H\r\n#define Vec4_H\r\n\r\n#include &lt;iostream&gt;\r\n#include &lt;sstream&gt;\r\n#include &lt;math.h&gt;\r\n#include &lt;string&gt;\r\n#include &lt;assert.h&gt;\r\n\r\ntemplate &lt;class T&gt; class Vec4{\r\n\r\npublic:\r\n\tunion{\r\n\t\tstruct {T x, y, z, w;};\r\n\t\tstruct {T r, g, b, a;};\r\n\t\tstruct {T s, t, p, q;};\r\n\t\tT v&#x5B;4];\r\n\t};\r\n\r\n\t\/\/constructors\r\n\tinline Vec4&lt;T&gt;(T x=0, T y=0, T z=0, T w=0);\r\n\tinline Vec4&lt;T&gt;(const Vec4&lt;T&gt; &amp;r);\r\n\tinline ~Vec4&lt;T&gt;();\r\n\r\n\tinline T &amp;operator&#x5B;](int index);\r\n\tinline operator T*();\r\n\tinline bool operator==(const Vec4&lt;T&gt; &amp;r)const;\r\n\tinline bool operator!=(const Vec4&lt;T&gt; &amp;r)const;\r\n\tinline Vec4&lt;T&gt; &amp;operator=(const Vec4&lt;T&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; &amp;operator=(const Vec4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; &amp;operator=(const U r&#x5B;4]);\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; &amp;operator+=(const Vec4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; operator+(const Vec4&lt;U&gt; &amp;r)const;\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; &amp;operator-=(const Vec4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; operator-(const Vec4&lt;U&gt; &amp;r)const;\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; &amp;operator*=(const Vec4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; operator*(const Vec4&lt;U&gt; &amp;r)const;\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; &amp;operator\/=(const Vec4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;T&gt; operator\/(const Vec4&lt;U&gt; &amp;r)const;\r\n\tinline Vec4&lt;T&gt; &amp;operator*=(double scalar);\r\n\tinline Vec4&lt;T&gt; operator*(double scalar)const;\r\n\tinline Vec4&lt;T&gt; &amp;operator\/=(double scalar);\r\n\tinline Vec4&lt;T&gt; operator\/(double scalar)const;\r\n\r\n\tinline T magnitude()const;\r\n\tinline Vec4&lt;T&gt; &amp;normalize();\r\n\tinline Vec4&lt;T&gt; &amp;divideW();\r\n\tstd::string toString();\r\n};\r\n\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt;::Vec4(T x=0, T y=0, T z=0, T w=0) :\r\n\tx(x), y(y), z(z), w(w){\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt;::Vec4(const Vec4&lt;T&gt; &amp;r) :\r\n\tx(r.x), y(r.y), z(r.z), w(r.w){\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt;::~Vec4(){\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline T &amp;Vec4&lt;T&gt;::operator&#x5B;](int index){\r\n\tassert(index &lt;= 3);\r\n\treturn v&#x5B;index];\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt;::operator T*(){\r\n\treturn &amp;x;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline bool Vec4&lt;T&gt;::operator==(const Vec4&lt;T&gt; &amp;r)const{\r\n\tif(x == r.x &amp;&amp; y == r.y &amp;&amp; z == r.z &amp;&amp; w == r.w)\r\n\t\treturn true;\r\n\treturn false;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline bool Vec4&lt;T&gt;::operator!=(const Vec4&lt;T&gt; &amp;r)const{\r\n\treturn !((*this)==r);\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator=(const Vec4&lt;T&gt; &amp;r){\r\n\tif(this != &amp;r){\r\n\t\tx = r.x;\r\n\t\ty = r.y;\r\n\t\tz = r.z;\r\n\t\tw = r.w;\r\n\t}\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator=(const Vec4&lt;U&gt; &amp;r){\r\n\tx = (T)r.x;\r\n\ty = (T)r.y;\r\n\tz = (T)r.z;\r\n\tw = (T)r.w;\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator=(const U r&#x5B;4]){\r\n\tif(v != r)\r\n\t\tfor(int i = 0; i &lt; 4; i++)\r\n\t\t\tv&#x5B;i] = (T)r&#x5B;i];\r\n\treturn *this;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator+=(const Vec4&lt;U&gt; &amp;r){\r\n\tx += (T)r.x;\r\n\ty += (T)r.y;\r\n\tz += (T)r.z;\r\n\treturn *this;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Vec4&lt;T&gt; Vec4&lt;T&gt;::operator+(const Vec4&lt;U&gt; &amp;r)const{\r\n\treturn Vec4(*this) += r;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator-=(const Vec4&lt;U&gt; &amp;r){\r\n\tx -= (T)r.x;\r\n\ty -= (T)r.y;\r\n\tz -= (T)r.z;\r\n\treturn *this;\r\n}\t\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Vec4&lt;T&gt; Vec4&lt;T&gt;::operator-(const Vec4&lt;U&gt; &amp;r)const{\r\n\treturn Vec4(*this) -= r;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt; template&lt;class U&gt; \r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator*=(const Vec4&lt;U&gt; &amp;r){\r\n\tx *= (T)r.x;\r\n\ty *= (T)r.y;\r\n\tz *= (T)r.z;\r\n\treturn *this;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt; template&lt;class U&gt; \r\ninline Vec4&lt;T&gt; Vec4&lt;T&gt;::operator*(const Vec4&lt;U&gt; &amp;r)const{\r\n\treturn Vec4(*this) *= r;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt; template&lt;class U&gt; \r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator\/=(const Vec4&lt;U&gt; &amp;r){\r\n\tx \/= (T)r.x;\r\n\ty \/= (T)r.y;\r\n\tz \/= (T)r.z;\r\n\treturn *this;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt; template&lt;class U&gt; \r\ninline Vec4&lt;T&gt; Vec4&lt;T&gt;::operator\/(const Vec4&lt;U&gt; &amp;r)const{\r\n\treturn Vec4(*this) \/= r;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator*=(double scalar){\r\n\tx = (T) (x * scalar);\r\n\ty = (T) (y * scalar);\r\n\tz = (T) (z * scalar);\r\n\treturn *this;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt; Vec4&lt;T&gt;::operator*(double scalar)const{\r\n\treturn Vec4(*this) *= scalar;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::operator\/=(double scalar){\r\n\tassert(scalar != 0);\r\n\tx = (T) (x \/ scalar);\r\n\ty = (T) (y \/ scalar);\r\n\tz = (T) (z \/ scalar);\r\n\treturn *this;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt; Vec4&lt;T&gt;::operator\/(double scalar)const{\r\n\treturn Vec4(*this) \/= scalar;\r\n}\r\n\r\n\/\/xyz only--NEEDS TO BE FLOAT\/DOUBLE TO BE ACCURATE\r\ntemplate&lt;class T&gt;\r\ninline T Vec4&lt;T&gt;::magnitude()const{\r\n\treturn (T)sqrt((double)(x*x + y*y + z*z));\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::normalize(){\r\n\tT d = magnitude();\r\n\tx \/= d;\r\n\ty \/= d;\r\n\tz \/= d;\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt; &amp;Vec4&lt;T&gt;::divideW(){\r\n\t*this \/= w;\r\n\tw = 1;\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\nstd::string Vec4&lt;T&gt;::toString(){\r\n\tstd::ostringstream oss;\r\n\toss &lt;&lt; &quot;(&quot;;\r\n\tfor(int i = 0; i &lt; 4; i++){\r\n\t\toss &lt;&lt; v&#x5B;i];\r\n\t\tif(i != 3)\r\n\t\t\toss &lt;&lt; &quot;, &quot;;\r\n\t}\r\n\toss &lt;&lt; &quot;)&quot;;\r\n\treturn oss.str();\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T, class U&gt;\r\ninline T dot(const Vec4&lt;T&gt; &amp;l, const Vec4&lt;U&gt; &amp;r){\r\n\treturn l.x*r.x + l.y*r.y + l.z*r.z;\r\n}\r\n\r\n\/\/xyz only\r\ntemplate&lt;class T, class U&gt;\r\ninline Vec4&lt;T&gt; cross(const Vec4&lt;T&gt; &amp;l, const Vec4&lt;U&gt; &amp;r){\r\n\tVec4&lt;T&gt; temp = Vec4&lt;T&gt;(0,0,0,1);\r\n\ttemp.x = l.y*r.z + l.z*r.y;\r\n\ttemp.y = l.z*r.x + l.x*r.z;\r\n\ttemp.z = l.x*r.y + l.y*r.x;\r\n\treturn temp;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Vec4&lt;T&gt; operator*(double scalar, Vec4&lt;T&gt; &amp;r){\r\n\treturn r * scalar;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline std::ostream &amp;operator &lt;&lt;(std::ostream &amp;stream, Vec4&lt;T&gt; &amp;r){\r\n\treturn stream &lt;&lt; r.toString();\r\n}\r\n\r\ntypedef Vec4&lt;float&gt;\tVec4f;\r\ntypedef Vec4&lt;double&gt;\tVec4d;\r\ntypedef Vec4&lt;int&gt;\t\tVec4i;\r\ntypedef Vec4&lt;float&gt;\tColor4f;\r\ntypedef Vec4&lt;double&gt;\tColor4d;\r\ntypedef Vec4&lt;int&gt;\t\tColor4i;\r\n\r\n#endif \/\/ Vec4_H\r\n<\/pre>\n<p>mat4.h<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/*\r\n * Mat4 is stored in row-major order.\r\n *\/\r\n\r\n#ifndef Mat4_H\r\n#define Mat4_H\r\n\r\n#include &quot;Vec4.h&quot;\r\n\r\ntemplate&lt;class T&gt; class Mat4{\r\nprivate:\r\n\tT mi&#x5B;4]&#x5B;4];\r\n\r\npublic:\r\n\tinline Mat4&lt;T&gt;(const Mat4&lt;T&gt; &amp;r);\r\n\tinline Mat4&lt;T&gt;(T m00=0, T m01=0, T m02=0, T m03=0,\r\n\t\t\tT m10=0, T m11=0, T m12=0, T m13=0,\r\n\t\t\tT m20=0, T m21=0, T m22=0, T m23=0,\r\n\t\t\tT m30=0, T m31=0, T m32=0, T m33=0);\r\n\tinline ~Mat4&lt;T&gt;();\r\n\tinline T *operator&#x5B;](int index);\r\n\tinline operator T*();\r\n\tinline bool operator==(const Mat4&lt;T&gt; &amp;r);\r\n\tinline bool operator!=(const Mat4&lt;T&gt; &amp;r);\r\n\tinline Mat4&lt;T&gt; &amp;operator=(const Mat4&lt;T&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Mat4&lt;T&gt; &amp;operator=(const Mat4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Mat4&lt;T&gt; &amp;operator=(const U r&#x5B;16]);\r\n\ttemplate&lt;class U&gt; inline Mat4&lt;T&gt; &amp;operator+=(const Mat4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Mat4&lt;T&gt; operator+(const Mat4&lt;U&gt; &amp;r)const;\r\n\ttemplate&lt;class U&gt; inline Mat4&lt;T&gt; &amp;operator-=(const Mat4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Mat4&lt;T&gt; operator-(const Mat4&lt;U&gt; &amp;r)const;\r\n\ttemplate&lt;class U&gt; inline Mat4&lt;T&gt; &amp;operator*=(const Mat4&lt;U&gt; &amp;r);\r\n\ttemplate&lt;class U&gt; inline Mat4&lt;T&gt; operator*(const Mat4&lt;U&gt; &amp;r)const;\r\n\ttemplate&lt;class U&gt; inline Vec4&lt;U&gt; operator*(const Vec4&lt;U&gt; &amp;r)const;\r\n\tinline Mat4&lt;T&gt; &amp;operator*=(double scalar);\r\n\tinline Mat4&lt;T&gt; operator*(double scalar)const;\r\n\tinline Mat4&lt;T&gt; &amp;operator\/=(double scalar);\r\n\tinline Mat4&lt;T&gt; operator\/(double scalar)const;\r\n\tinline Mat4&lt;T&gt; &amp;transpose();\r\n\tstd::string toString();\r\n};\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt;::Mat4(const Mat4&lt;T&gt; &amp;r){\r\n\t*this = r;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt;::Mat4(T m00=0, T m01=0, T m02=0, T m03=0,\r\n\t\t\t  T m10=0, T m11=0, T m12=0, T m13=0,\r\n\t\t\t  T m20=0, T m21=0, T m22=0, T m23=0,\r\n\t\t\t  T m30=0, T m31=0, T m32=0, T m33=0){\r\n\tmi&#x5B;0]&#x5B;0] = m00; mi&#x5B;0]&#x5B;1] = m01; mi&#x5B;0]&#x5B;2] = m02; mi&#x5B;0]&#x5B;3] = m03;\r\n\tmi&#x5B;1]&#x5B;0] = m10; mi&#x5B;1]&#x5B;1] = m11; mi&#x5B;1]&#x5B;2] = m12; mi&#x5B;1]&#x5B;3] = m13;\r\n\tmi&#x5B;2]&#x5B;0] = m20; mi&#x5B;2]&#x5B;1] = m21; mi&#x5B;2]&#x5B;2] = m22; mi&#x5B;2]&#x5B;3] = m23;\r\n\tmi&#x5B;3]&#x5B;0] = m30; mi&#x5B;3]&#x5B;1] = m31; mi&#x5B;3]&#x5B;2] = m32; mi&#x5B;3]&#x5B;3] = m33;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt;::~Mat4(){\r\n}\t\r\n\r\ntemplate&lt;class T&gt;\r\ninline T* Mat4&lt;T&gt;::operator&#x5B;](int index){\r\n\treturn mi&#x5B;index];\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt;::operator T*(){\r\n\treturn &amp;mi&#x5B;0]&#x5B;0];\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline bool Mat4&lt;T&gt;::operator==(const Mat4 &amp;r){\r\n\tfor(int i = 0; i &lt; 4; i++)\r\n\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\tif(mi&#x5B;i]&#x5B;j] != r.mi&#x5B;i]&#x5B;j])\r\n\t\t\t\treturn false;\r\n\treturn true;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline bool Mat4&lt;T&gt;::operator!=(const Mat4 &amp;r){\r\n\treturn !((*this)==r);\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::operator=(const Mat4&lt;T&gt; &amp;r){\r\n\tif(this != &amp;r)\r\n\t\tfor(int i = 0; i &lt; 4; i++)\r\n\t\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\t\tmi&#x5B;i]&#x5B;j] = r.mi&#x5B;i]&#x5B;j];\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::operator=(const Mat4&lt;U&gt; &amp;r){\r\n\tfor(int i = 0; i &lt; 4; i++)\r\n\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\tmi&#x5B;i]&#x5B;j] = (T)r.mi&#x5B;i]&#x5B;j];\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::operator=(const U r&#x5B;16]){\r\n\tfor(int i = 0; i &lt; 4; i++)\r\n\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\tmi&#x5B;i]&#x5B;j] = (T)r&#x5B;i*4 + j];\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::operator+=(const Mat4&lt;U&gt; &amp;r){\r\n\tfor(int i = 0; i &lt; 4; i++)\r\n\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\tmi&#x5B;i]&#x5B;j] += (T)r.mi&#x5B;i]&#x5B;j];\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Mat4&lt;T&gt; Mat4&lt;T&gt;::operator+(const Mat4&lt;U&gt; &amp;r)const{\r\n\treturn Mat4(*this) += r;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::operator-=(const Mat4&lt;U&gt; &amp;r){\r\n\tfor(int i = 0; i &lt; 4; i++)\r\n\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\tmi&#x5B;i]&#x5B;j] -= (T)r.mi&#x5B;i]&#x5B;j];\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Mat4&lt;T&gt; Mat4&lt;T&gt;::operator-(const Mat4&lt;U&gt; &amp;r)const{\r\n\treturn Mat4(*this) -= r;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::operator*=(const Mat4&lt;U&gt; &amp;r){\r\n\tMat4&lt;T&gt; temp;\r\n\tfor(int i = 0; i &lt; 4; i++){\r\n\t\tfor(int j = 0; j &lt; 4; j++){\r\n\t\t\tT tot = 0;\r\n\t\t\tfor(int k = 0; k &lt; 4; k++)\r\n\t\t\t\ttot += mi&#x5B;i]&#x5B;k]*(T)r.mi&#x5B;k]&#x5B;j];\r\n\t\t\ttemp&#x5B;i]&#x5B;j] = tot;\r\n\t\t}\r\n\t}\r\n\t*this = temp;\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt; template&lt;class U&gt;\r\ninline Mat4&lt;T&gt; Mat4&lt;T&gt;::operator*(const Mat4&lt;U&gt; &amp;r)const{\r\n\treturn Mat4(*this) *= r;\r\n}\r\n\r\n\/\/Vec4 is treated as 4x1 matrix on rhs\r\ntemplate&lt;class T&gt; template &lt;class U&gt;\r\ninline Vec4&lt;U&gt; Mat4&lt;T&gt;::operator*(const Vec4&lt;U&gt; &amp;r)const{\r\n\tVec4&lt;U&gt; final;\r\n\tfor(int i = 0; i &lt; 4; i++){\r\n\t\tT tot = 0;\r\n\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\ttot += mi&#x5B;i]&#x5B;j] * (T)r.v&#x5B;j];\r\n\t\tfinal&#x5B;i] = tot;\r\n\t}\r\n\treturn final;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::operator*=(double scalar){\r\n\tfor(int i = 0; i &lt; 4; i++)\r\n\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\tmi&#x5B;i]&#x5B;j] = (T) (mi&#x5B;i]&#x5B;j] * scalar);\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt; Mat4&lt;T&gt;::operator*(double scalar)const{\r\n\treturn Mat4(*this) *= scalar;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::operator\/=(double scalar){\r\n\tif(scalar != 0){\r\n\t\tfor(int i = 0; i &lt; 4; i++)\r\n\t\t\tfor(int j = 0; j &lt; 4; j++)\r\n\t\t\t\tmi&#x5B;i]&#x5B;j] = (T) (mi&#x5B;i]&#x5B;j] \/ scalar);\r\n\t}\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt; Mat4&lt;T&gt;::operator\/(double scalar)const{\r\n\treturn Mat4(*this) \/= scalar;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt; &amp;Mat4&lt;T&gt;::transpose(){\r\n\tT temp;\r\n\tfor(int i = 0; i &lt; 3; i++)\r\n\t\tfor(int j = 1; j &lt; 4; j++)\r\n\t\t\tif(j &gt; i){\r\n\t\t\t\ttemp = mi&#x5B;i]&#x5B;j];\r\n\t\t\t\tmi&#x5B;i]&#x5B;j] = mi&#x5B;j]&#x5B;i];\r\n\t\t\t\tmi&#x5B;j]&#x5B;i] = temp;\r\n\t\t\t}\r\n\treturn *this;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\nstd::string Mat4&lt;T&gt;::toString(){\r\n\tstd::ostringstream oss;\r\n\tfor(int i = 0; i &lt; 4; i++){\r\n\t\tfor(int j = 0; j &lt; 4; j++){\r\n\t\t\toss &lt;&lt; mi&#x5B;i]&#x5B;j];\r\n\t\t\tif(j != 3) \r\n\t\t\t\toss &lt;&lt; &quot;\\t&quot;;\r\n\t\t}\r\n\t\tif(i != 3)\r\n\t\t\toss &lt;&lt; &quot;\\n&quot;;\r\n\t}\r\n\treturn oss.str();\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\ninline Mat4&lt;T&gt; operator*(double scalar, Mat4&lt;T&gt; &amp;r){\r\n\treturn r * scalar;\r\n}\r\n\r\ntemplate&lt;class T&gt;\r\nstd::ostream &amp;operator&lt;&lt;(std::ostream &amp;stream, Mat4&lt;T&gt; &amp;r){\r\n\treturn stream &lt;&lt; r.toString();\r\n}\r\n\r\ntypedef Mat4&lt;float&gt;\tMat4f;\r\ntypedef Mat4&lt;double&gt;\tMat4d;\r\ntypedef Mat4&lt;int&gt;\tMat4i;\r\n\r\n#endif \/\/Mat4_H\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Below is a small sample of code, namely vector and matrix classes. I developed these to help with basic linear algebra, and to use seamlessly with OpenGL. Some examples of how these are used are in the Cube World project. vec4.h \/* * To avoid normalization problems, addition, subtraction, * scalar multiplication &amp; division, dot [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":2,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-28","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/pages\/28","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/davidmazz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=28"}],"version-history":[{"count":0,"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/pages\/28\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/pages\/2"}],"wp:attachment":[{"href":"https:\/\/davidmazz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=28"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}