mirror of https://gitee.com/bigwinds/arangodb
8179 lines
365 KiB
HTML
8179 lines
365 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="generator" content="Asciidoctor 1.5.5">
|
||
<meta name="keywords" content="c++, boost, matrix, vector, quaternion">
|
||
<meta name="author" content="Generic C++ library for working with Quaternions Vectors and Matrices">
|
||
<title>Boost QVM</title>
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
|
||
<style>
|
||
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
|
||
/* Remove comment around @import statement below when using as a custom stylesheet */
|
||
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
|
||
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
|
||
audio,canvas,video{display:inline-block}
|
||
audio:not([controls]){display:none;height:0}
|
||
[hidden],template{display:none}
|
||
script{display:none!important}
|
||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
|
||
a{background:transparent}
|
||
a:focus{outline:thin dotted}
|
||
a:active,a:hover{outline:0}
|
||
h1{font-size:2em;margin:.67em 0}
|
||
abbr[title]{border-bottom:1px dotted}
|
||
b,strong{font-weight:bold}
|
||
dfn{font-style:italic}
|
||
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
|
||
mark{background:#ff0;color:#000}
|
||
code,kbd,pre,samp{font-family:monospace;font-size:1em}
|
||
pre{white-space:pre-wrap}
|
||
q{quotes:"\201C" "\201D" "\2018" "\2019"}
|
||
small{font-size:80%}
|
||
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
|
||
sup{top:-.5em}
|
||
sub{bottom:-.25em}
|
||
img{border:0}
|
||
svg:not(:root){overflow:hidden}
|
||
figure{margin:0}
|
||
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
|
||
legend{border:0;padding:0}
|
||
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
|
||
button,input{line-height:normal}
|
||
button,select{text-transform:none}
|
||
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
|
||
button[disabled],html input[disabled]{cursor:default}
|
||
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
|
||
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
|
||
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
|
||
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
|
||
textarea{overflow:auto;vertical-align:top}
|
||
table{border-collapse:collapse;border-spacing:0}
|
||
*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||
html,body{font-size:100%}
|
||
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
|
||
a:hover{cursor:pointer}
|
||
img,object,embed{max-width:100%;height:auto}
|
||
object,embed{height:100%}
|
||
img{-ms-interpolation-mode:bicubic}
|
||
.left{float:left!important}
|
||
.right{float:right!important}
|
||
.text-left{text-align:left!important}
|
||
.text-right{text-align:right!important}
|
||
.text-center{text-align:center!important}
|
||
.text-justify{text-align:justify!important}
|
||
.hide{display:none}
|
||
img,object,svg{display:inline-block;vertical-align:middle}
|
||
textarea{height:auto;min-height:50px}
|
||
select{width:100%}
|
||
.center{margin-left:auto;margin-right:auto}
|
||
.spread{width:100%}
|
||
p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
|
||
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
|
||
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
|
||
a{color:#2156a5;text-decoration:underline;line-height:inherit}
|
||
a:hover,a:focus{color:#1d4b8f}
|
||
a img{border:none}
|
||
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
|
||
p aside{font-size:.875em;line-height:1.35;font-style:italic}
|
||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
|
||
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
|
||
h1{font-size:2.125em}
|
||
h2{font-size:1.6875em}
|
||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
|
||
h4,h5{font-size:1.125em}
|
||
h6{font-size:1em}
|
||
hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
|
||
em,i{font-style:italic;line-height:inherit}
|
||
strong,b{font-weight:bold;line-height:inherit}
|
||
small{font-size:60%;line-height:inherit}
|
||
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
|
||
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
|
||
ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
|
||
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
|
||
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
|
||
ul.square{list-style-type:square}
|
||
ul.circle{list-style-type:circle}
|
||
ul.disc{list-style-type:disc}
|
||
ul.no-bullet{list-style:none}
|
||
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
|
||
dl dt{margin-bottom:.3125em;font-weight:bold}
|
||
dl dd{margin-bottom:1.25em}
|
||
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
|
||
abbr{text-transform:none}
|
||
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
|
||
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
|
||
blockquote cite:before{content:"\2014 \0020"}
|
||
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
|
||
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
|
||
@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
|
||
h1{font-size:2.75em}
|
||
h2{font-size:2.3125em}
|
||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
|
||
h4{font-size:1.4375em}}
|
||
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
|
||
table thead,table tfoot{background:#f7f8f7;font-weight:bold}
|
||
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
|
||
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
|
||
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
|
||
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
|
||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
|
||
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
|
||
.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
|
||
.clearfix:after,.float-group:after{clear:both}
|
||
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
|
||
*:not(pre)>code.nobreak{word-wrap:normal}
|
||
*:not(pre)>code.nowrap{white-space:nowrap}
|
||
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
|
||
em em{font-style:normal}
|
||
strong strong{font-weight:400}
|
||
.keyseq{color:rgba(51,51,51,.8)}
|
||
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
|
||
.keyseq kbd:first-child{margin-left:0}
|
||
.keyseq kbd:last-child{margin-right:0}
|
||
.menuseq,.menu{color:rgba(0,0,0,.8)}
|
||
b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
|
||
b.button:before{content:"[";padding:0 3px 0 2px}
|
||
b.button:after{content:"]";padding:0 2px 0 3px}
|
||
p a>code:hover{color:rgba(0,0,0,.9)}
|
||
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
|
||
#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
|
||
#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
|
||
#content{margin-top:1.25em}
|
||
#content:before{content:none}
|
||
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
|
||
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
|
||
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
|
||
#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
|
||
#header .details span:first-child{margin-left:-.125em}
|
||
#header .details span.email a{color:rgba(0,0,0,.85)}
|
||
#header .details br{display:none}
|
||
#header .details br+span:before{content:"\00a0\2013\00a0"}
|
||
#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
|
||
#header .details br+span#revremark:before{content:"\00a0|\00a0"}
|
||
#header #revnumber{text-transform:capitalize}
|
||
#header #revnumber:after{content:"\00a0"}
|
||
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
|
||
#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
|
||
#toc>ul{margin-left:.125em}
|
||
#toc ul.sectlevel0>li>a{font-style:italic}
|
||
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
|
||
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
|
||
#toc li{line-height:1.3334;margin-top:.3334em}
|
||
#toc a{text-decoration:none}
|
||
#toc a:active{text-decoration:underline}
|
||
#toctitle{color:#7a2518;font-size:1.2em}
|
||
@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
|
||
body.toc2{padding-left:15em;padding-right:0}
|
||
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
|
||
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
|
||
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
|
||
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
|
||
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
|
||
body.toc2.toc-right{padding-left:0;padding-right:15em}
|
||
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
|
||
@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
|
||
#toc.toc2{width:20em}
|
||
#toc.toc2 #toctitle{font-size:1.375em}
|
||
#toc.toc2>ul{font-size:.95em}
|
||
#toc.toc2 ul ul{padding-left:1.25em}
|
||
body.toc2.toc-right{padding-left:0;padding-right:20em}}
|
||
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
|
||
#content #toc>:first-child{margin-top:0}
|
||
#content #toc>:last-child{margin-bottom:0}
|
||
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
|
||
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
|
||
.sect1{padding-bottom:.625em}
|
||
@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
|
||
.sect1+.sect1{border-top:1px solid #efefed}
|
||
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
|
||
#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
|
||
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
|
||
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
|
||
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
|
||
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
|
||
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
|
||
table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
|
||
.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
|
||
table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
|
||
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
|
||
.admonitionblock>table td.icon{text-align:center;width:80px}
|
||
.admonitionblock>table td.icon img{max-width:none}
|
||
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
|
||
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
|
||
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
|
||
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
|
||
.exampleblock>.content>:first-child{margin-top:0}
|
||
.exampleblock>.content>:last-child{margin-bottom:0}
|
||
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
|
||
.sidebarblock>:first-child{margin-top:0}
|
||
.sidebarblock>:last-child{margin-bottom:0}
|
||
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
|
||
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
|
||
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
|
||
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
|
||
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
|
||
.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
|
||
@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
|
||
@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
|
||
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
|
||
.listingblock pre.highlightjs{padding:0}
|
||
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
|
||
.listingblock pre.prettyprint{border-width:0}
|
||
.listingblock>.content{position:relative}
|
||
.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
|
||
.listingblock:hover code[data-lang]:before{display:block}
|
||
.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
|
||
.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
|
||
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
|
||
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
|
||
table.pyhltable td.code{padding-left:.75em;padding-right:0}
|
||
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
|
||
pre.pygments .lineno{display:inline-block;margin-right:.25em}
|
||
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
|
||
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
|
||
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
|
||
.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
|
||
.quoteblock blockquote{margin:0;padding:0;border:0}
|
||
.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
|
||
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
|
||
.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
|
||
.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
|
||
.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
|
||
.quoteblock .quoteblock blockquote:before{display:none}
|
||
.verseblock{margin:0 1em 1.25em 1em}
|
||
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
|
||
.verseblock pre strong{font-weight:400}
|
||
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
|
||
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
|
||
.quoteblock .attribution br,.verseblock .attribution br{display:none}
|
||
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
|
||
.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
|
||
.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
|
||
.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
|
||
table.tableblock{max-width:100%;border-collapse:separate}
|
||
table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
|
||
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
|
||
table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
|
||
table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
|
||
table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
|
||
table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
|
||
table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
|
||
table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
|
||
table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
|
||
table.frame-all{border-width:1px}
|
||
table.frame-sides{border-width:0 1px}
|
||
table.frame-topbot{border-width:1px 0}
|
||
th.halign-left,td.halign-left{text-align:left}
|
||
th.halign-right,td.halign-right{text-align:right}
|
||
th.halign-center,td.halign-center{text-align:center}
|
||
th.valign-top,td.valign-top{vertical-align:top}
|
||
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
|
||
th.valign-middle,td.valign-middle{vertical-align:middle}
|
||
table thead th,table tfoot th{font-weight:bold}
|
||
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
|
||
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
|
||
p.tableblock>code:only-child{background:none;padding:0}
|
||
p.tableblock{font-size:1em}
|
||
td>div.verse{white-space:pre}
|
||
ol{margin-left:1.75em}
|
||
ul li ol{margin-left:1.5em}
|
||
dl dd{margin-left:1.125em}
|
||
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
|
||
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
|
||
ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
|
||
ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
|
||
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
|
||
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
|
||
ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
|
||
ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
|
||
ul.inline>li>*{display:block}
|
||
.unstyled dl dt{font-weight:400;font-style:normal}
|
||
ol.arabic{list-style-type:decimal}
|
||
ol.decimal{list-style-type:decimal-leading-zero}
|
||
ol.loweralpha{list-style-type:lower-alpha}
|
||
ol.upperalpha{list-style-type:upper-alpha}
|
||
ol.lowerroman{list-style-type:lower-roman}
|
||
ol.upperroman{list-style-type:upper-roman}
|
||
ol.lowergreek{list-style-type:lower-greek}
|
||
.hdlist>table,.colist>table{border:0;background:none}
|
||
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
|
||
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
|
||
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
|
||
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
|
||
.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
|
||
.colist>table tr>td:last-of-type{padding:.25em 0}
|
||
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
|
||
.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
|
||
.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
|
||
.imageblock>.title{margin-bottom:0}
|
||
.imageblock.thumb,.imageblock.th{border-width:6px}
|
||
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
|
||
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
|
||
.image.left{margin-right:.625em}
|
||
.image.right{margin-left:.625em}
|
||
a.image{text-decoration:none;display:inline-block}
|
||
a.image object{pointer-events:none}
|
||
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
|
||
sup.footnote a,sup.footnoteref a{text-decoration:none}
|
||
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
|
||
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
|
||
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
|
||
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
|
||
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
|
||
#footnotes .footnote:last-of-type{margin-bottom:0}
|
||
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
|
||
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
|
||
.gist .file-data>table td.line-data{width:99%}
|
||
div.unbreakable{page-break-inside:avoid}
|
||
.big{font-size:larger}
|
||
.small{font-size:smaller}
|
||
.underline{text-decoration:underline}
|
||
.overline{text-decoration:overline}
|
||
.line-through{text-decoration:line-through}
|
||
.aqua{color:#00bfbf}
|
||
.aqua-background{background-color:#00fafa}
|
||
.black{color:#000}
|
||
.black-background{background-color:#000}
|
||
.blue{color:#0000bf}
|
||
.blue-background{background-color:#0000fa}
|
||
.fuchsia{color:#bf00bf}
|
||
.fuchsia-background{background-color:#fa00fa}
|
||
.gray{color:#606060}
|
||
.gray-background{background-color:#7d7d7d}
|
||
.green{color:#006000}
|
||
.green-background{background-color:#007d00}
|
||
.lime{color:#00bf00}
|
||
.lime-background{background-color:#00fa00}
|
||
.maroon{color:#600000}
|
||
.maroon-background{background-color:#7d0000}
|
||
.navy{color:#000060}
|
||
.navy-background{background-color:#00007d}
|
||
.olive{color:#606000}
|
||
.olive-background{background-color:#7d7d00}
|
||
.purple{color:#600060}
|
||
.purple-background{background-color:#7d007d}
|
||
.red{color:#bf0000}
|
||
.red-background{background-color:#fa0000}
|
||
.silver{color:#909090}
|
||
.silver-background{background-color:#bcbcbc}
|
||
.teal{color:#006060}
|
||
.teal-background{background-color:#007d7d}
|
||
.white{color:#bfbfbf}
|
||
.white-background{background-color:#fafafa}
|
||
.yellow{color:#bfbf00}
|
||
.yellow-background{background-color:#fafa00}
|
||
span.icon>.fa{cursor:default}
|
||
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
|
||
.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
|
||
.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
|
||
.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
|
||
.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
|
||
.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
|
||
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
|
||
.conum[data-value] *{color:#fff!important}
|
||
.conum[data-value]+b{display:none}
|
||
.conum[data-value]:after{content:attr(data-value)}
|
||
pre .conum[data-value]{position:relative;top:-.125em}
|
||
b.conum *{color:inherit!important}
|
||
.conum:not([data-value]):empty{display:none}
|
||
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
|
||
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
|
||
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
|
||
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
|
||
p{margin-bottom:1.25rem}
|
||
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
|
||
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
|
||
.print-only{display:none!important}
|
||
@media print{@page{margin:1.25cm .75cm}
|
||
*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
|
||
a{color:inherit!important;text-decoration:underline!important}
|
||
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
|
||
a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
|
||
abbr[title]:after{content:" (" attr(title) ")"}
|
||
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
|
||
thead{display:table-header-group}
|
||
svg{max-width:100%}
|
||
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
|
||
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
|
||
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
|
||
#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
|
||
.sect1{padding-bottom:0!important}
|
||
.sect1+.sect1{border:0!important}
|
||
#header>h1:first-child{margin-top:1.25rem}
|
||
body.book #header{text-align:center}
|
||
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
|
||
body.book #header .details{border:0!important;display:block;padding:0!important}
|
||
body.book #header .details span:first-child{margin-left:0!important}
|
||
body.book #header .details br{display:block}
|
||
body.book #header .details br+span:before{content:none!important}
|
||
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
|
||
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
|
||
.listingblock code[data-lang]:before{display:block}
|
||
#footer{background:none!important;padding:0 .9375em}
|
||
#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
|
||
.hide-on-print{display:none!important}
|
||
.print-only{display:block!important}
|
||
.hide-for-print{display:none!important}
|
||
.show-for-print{display:inherit!important}}
|
||
</style>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
|
||
<style>
|
||
/* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
|
||
/*pre.CodeRay {background-color:#f7f7f8;}*/
|
||
.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
|
||
.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
|
||
.CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
|
||
table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
|
||
table.CodeRay td{vertical-align: top;line-height:1.45}
|
||
table.CodeRay td.line-numbers{text-align:right}
|
||
table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
|
||
table.CodeRay td.code{padding:0 0 0 .5em}
|
||
table.CodeRay td.code>pre{padding:0}
|
||
.CodeRay .debug{color:#fff !important;background:#000080 !important}
|
||
.CodeRay .annotation{color:#007}
|
||
.CodeRay .attribute-name{color:#000080}
|
||
.CodeRay .attribute-value{color:#700}
|
||
.CodeRay .binary{color:#509}
|
||
.CodeRay .comment{color:#998;font-style:italic}
|
||
.CodeRay .char{color:#04d}
|
||
.CodeRay .char .content{color:#04d}
|
||
.CodeRay .char .delimiter{color:#039}
|
||
.CodeRay .class{color:#458;font-weight:bold}
|
||
.CodeRay .complex{color:#a08}
|
||
.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
|
||
.CodeRay .color{color:#099}
|
||
.CodeRay .class-variable{color:#369}
|
||
.CodeRay .decorator{color:#b0b}
|
||
.CodeRay .definition{color:#099}
|
||
.CodeRay .delimiter{color:#000}
|
||
.CodeRay .doc{color:#970}
|
||
.CodeRay .doctype{color:#34b}
|
||
.CodeRay .doc-string{color:#d42}
|
||
.CodeRay .escape{color:#666}
|
||
.CodeRay .entity{color:#800}
|
||
.CodeRay .error{color:#808}
|
||
.CodeRay .exception{color:inherit}
|
||
.CodeRay .filename{color:#099}
|
||
.CodeRay .function{color:#900;font-weight:bold}
|
||
.CodeRay .global-variable{color:#008080}
|
||
.CodeRay .hex{color:#058}
|
||
.CodeRay .integer,.CodeRay .float{color:#099}
|
||
.CodeRay .include{color:#555}
|
||
.CodeRay .inline{color:#000}
|
||
.CodeRay .inline .inline{background:#ccc}
|
||
.CodeRay .inline .inline .inline{background:#bbb}
|
||
.CodeRay .inline .inline-delimiter{color:#d14}
|
||
.CodeRay .inline-delimiter{color:#d14}
|
||
.CodeRay .important{color:#555;font-weight:bold}
|
||
.CodeRay .interpreted{color:#b2b}
|
||
.CodeRay .instance-variable{color:#008080}
|
||
.CodeRay .label{color:#970}
|
||
.CodeRay .local-variable{color:#963}
|
||
.CodeRay .octal{color:#40e}
|
||
.CodeRay .predefined{color:#369}
|
||
.CodeRay .preprocessor{color:#579}
|
||
.CodeRay .pseudo-class{color:#555}
|
||
.CodeRay .directive{font-weight:bold}
|
||
.CodeRay .type{font-weight:bold}
|
||
.CodeRay .predefined-type{color:inherit}
|
||
.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
|
||
.CodeRay .key{color:#808}
|
||
.CodeRay .key .delimiter{color:#606}
|
||
.CodeRay .key .char{color:#80f}
|
||
.CodeRay .value{color:#088}
|
||
.CodeRay .regexp .delimiter{color:#808}
|
||
.CodeRay .regexp .content{color:#808}
|
||
.CodeRay .regexp .modifier{color:#808}
|
||
.CodeRay .regexp .char{color:#d14}
|
||
.CodeRay .regexp .function{color:#404;font-weight:bold}
|
||
.CodeRay .string{color:#d20}
|
||
.CodeRay .string .string .string{background:#ffd0d0}
|
||
.CodeRay .string .content{color:#d14}
|
||
.CodeRay .string .char{color:#d14}
|
||
.CodeRay .string .delimiter{color:#d14}
|
||
.CodeRay .shell{color:#d14}
|
||
.CodeRay .shell .delimiter{color:#d14}
|
||
.CodeRay .symbol{color:#990073}
|
||
.CodeRay .symbol .content{color:#a60}
|
||
.CodeRay .symbol .delimiter{color:#630}
|
||
.CodeRay .tag{color:#008080}
|
||
.CodeRay .tag-special{color:#d70}
|
||
.CodeRay .variable{color:#036}
|
||
.CodeRay .insert{background:#afa}
|
||
.CodeRay .delete{background:#faa}
|
||
.CodeRay .change{color:#aaf;background:#007}
|
||
.CodeRay .head{color:#f8f;background:#505}
|
||
.CodeRay .insert .insert{color:#080}
|
||
.CodeRay .delete .delete{color:#800}
|
||
.CodeRay .change .change{color:#66f}
|
||
.CodeRay .head .head{color:#f4f}
|
||
</style>
|
||
</head>
|
||
<body class="article toc2 toc-left">
|
||
<div id="header">
|
||
<h1>Boost QVM</h1>
|
||
<div class="details">
|
||
<span id="author" class="author">Generic C++ library for working with Quaternions Vectors and Matrices</span><br>
|
||
</div>
|
||
<div id="toc" class="toc2">
|
||
<div id="toctitle">Boost QVM</div>
|
||
<ul class="sectlevel1">
|
||
<li><a href="#_abstract">Abstract</a></li>
|
||
<li><a href="#_distribution">Distribution</a></li>
|
||
<li><a href="#_feedback_support">Feedback / support</a></li>
|
||
<li><a href="#_portability">Portability</a></li>
|
||
<li><a href="#_tutorial">Tutorial</a>
|
||
<ul class="sectlevel2">
|
||
<li><a href="#_quaternions_vectors_matrices">Quaternions, Vectors, Matrices</a></li>
|
||
<li><a href="#_c_arrays">C Arrays</a></li>
|
||
<li><a href="#view_proxy">View proxies</a></li>
|
||
<li><a href="#_swizzling">Swizzling</a></li>
|
||
<li><a href="#enable_if">SFINAE/enable_if</a></li>
|
||
<li><a href="#_interoperability">Interoperability</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#_specifying_return_types_for_binary_operations">Specifying return types for binary operations</a></li>
|
||
<li><a href="#_specifying_return_types_for_unary_operations">Specifying return types for unary operations</a></li>
|
||
<li><a href="#_converting_between_different_quaternion_vector_and_matrix_types">Converting between different quaternion, vector and matrix types</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_header_files">Header files</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_reference">Reference</a>
|
||
<ul class="sectlevel2">
|
||
<li><a href="#type_traits">Type traits system</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#scalar_requirements">Scalar requirements</a></li>
|
||
<li><a href="#is_scalar"><code>is_scalar</code></a></li>
|
||
<li><a href="#scalar_traits"><code>scalar_traits</code></a></li>
|
||
<li><a href="#deduce_scalar"><code>deduce_scalar</code></a></li>
|
||
<li><a href="#scalar"><code>scalar</code></a></li>
|
||
<li><a href="#is_quat"><code>is_quat</code></a></li>
|
||
<li><a href="#quat_traits"><code>quat_traits</code></a></li>
|
||
<li><a href="#quat_traits_defaults"><code>quat_traits_defaults</code></a></li>
|
||
<li><a href="#deduce_quat"><code>deduce_quat</code></a></li>
|
||
<li><a href="#deduce_quat2"><code>deduce_quat2</code></a></li>
|
||
<li><a href="#is_vec"><code>is_vec</code></a></li>
|
||
<li><a href="#vec_traits"><code>vec_traits</code></a></li>
|
||
<li><a href="#vec_traits_defaults"><code>vec_traits_defaults</code></a></li>
|
||
<li><a href="#deduce_vec"><code>deduce_vec</code></a></li>
|
||
<li><a href="#deduce_vec2"><code>deduce_vec2</code></a></li>
|
||
<li><a href="#is_mat"><code>is_mat</code></a></li>
|
||
<li><a href="#mat_traits"><code>mat_traits</code></a></li>
|
||
<li><a href="#mat_traits_defaults"><code>mat_traits_defaults</code></a></li>
|
||
<li><a href="#deduce_mat"><code>deduce_mat</code></a></li>
|
||
<li><a href="#deduce_mat2"><code>deduce_mat2</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_built_in_quaternion_vector_and_matrix_types">Built-in quaternion, vector and matrix types</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#quat"><code>quat</code></a></li>
|
||
<li><a href="#vec"><code>vec</code></a></li>
|
||
<li><a href="#mat"><code>mat</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_element_access">Generic element access</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#quat_access">Quaternions</a></li>
|
||
<li><a href="#vec_access">Vectors</a></li>
|
||
<li><a href="#swizzling">Vector element swizzling</a></li>
|
||
<li><a href="#mat_access">Matrices</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_quaternion_operations">Generic quaternion operations</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#quat_assign"><code>assign</code></a></li>
|
||
<li><a href="#quat_convert_to"><code>convert_to</code></a></li>
|
||
<li><a href="#quat_minus_eq"><code>operator-=</code></a></li>
|
||
<li><a href="#quat_minus_unary"><code>operator-</code> (unary)</a></li>
|
||
<li><a href="#quat_minus"><code>operator-</code> (binary)</a></li>
|
||
<li><a href="#quat_plus_eq"><code>operator+=</code></a></li>
|
||
<li><a href="#quat_plus"><code>operator+</code></a></li>
|
||
<li><a href="#quat_div_eq_scalar"><code>operator/=</code> (scalar)</a></li>
|
||
<li><a href="#quat_div_scalar"><code>operator/</code> (scalar)</a></li>
|
||
<li><a href="#quat_mul_eq_scalar"><code>operator*=</code> (scalar)</a></li>
|
||
<li><a href="#quat_mul_eq"><code>operator*=</code></a></li>
|
||
<li><a href="#quat_mul_scalar"><code>operator*</code> (scalar)</a></li>
|
||
<li><a href="#quat_mul"><code>operator*</code></a></li>
|
||
<li><a href="#quat_eq"><code>operator==</code></a></li>
|
||
<li><a href="#quat_neq"><code>operator!=</code></a></li>
|
||
<li><a href="#quat_cmp"><code>cmp</code></a></li>
|
||
<li><a href="#quat_mag_sqr"><code>mag_sqr</code></a></li>
|
||
<li><a href="#quat_mag"><code>mag</code></a></li>
|
||
<li><a href="#quat_normalized"><code>normalized</code></a></li>
|
||
<li><a href="#quat_normalize"><code>normalize</code></a></li>
|
||
<li><a href="#quat_dot"><code>dot</code></a></li>
|
||
<li><a href="#conjugate"><code>conjugate</code></a></li>
|
||
<li><a href="#quat_inverse"><code>inverse</code></a></li>
|
||
<li><a href="#slerp"><code>slerp</code></a></li>
|
||
<li><a href="#zero_quat"><code>zero_quat</code></a></li>
|
||
<li><a href="#quat_set_zero"><code>set_zero</code></a></li>
|
||
<li><a href="#identity_quat"><code>identity_quat</code></a></li>
|
||
<li><a href="#quat_set_identity"><code>set_identity</code></a></li>
|
||
<li><a href="#rot_quat"><code>rot_quat</code></a></li>
|
||
<li><a href="#quat_set_rot"><code>set_rot</code></a></li>
|
||
<li><a href="#quat_rotate"><code>rotate</code></a></li>
|
||
<li><a href="#rotx_quat"><code>rotx_quat</code></a></li>
|
||
<li><a href="#quat_set_rotx"><code>set_rotx</code></a></li>
|
||
<li><a href="#quat_rotate_x"><code>rotate_x</code></a></li>
|
||
<li><a href="#roty_quat"><code>roty_quat</code></a></li>
|
||
<li><a href="#quat_set_roty"><code>set_roty</code></a></li>
|
||
<li><a href="#quat_rotate_y"><code>rotate_y</code></a></li>
|
||
<li><a href="#rotz_quat"><code>rotz_quat</code></a></li>
|
||
<li><a href="#quat_set_rotz"><code>set_rotz</code></a></li>
|
||
<li><a href="#quat_rotate_z"><code>rotate_z</code></a></li>
|
||
<li><a href="#quat_scalar_cast"><code>scalar_cast</code></a></li>
|
||
<li><a href="#qref"><code>qref</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_vector_operations">Generic vector operations</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#vec_assign"><code>assign</code></a></li>
|
||
<li><a href="#vec_convert_to"><code>convert_to</code></a></li>
|
||
<li><a href="#vec_minus_eq"><code>operator-=</code></a></li>
|
||
<li><a href="#vec_minus_unary"><code>operator-</code> (unary)</a></li>
|
||
<li><a href="#vec_minus"><code>operator-</code> (binary)</a></li>
|
||
<li><a href="#vec_plus_eq"><code>operator+=</code></a></li>
|
||
<li><a href="#vec_plus"><code>operator+</code></a></li>
|
||
<li><a href="#vec_div_eq_scalar"><code>operator/=</code> (scalar)</a></li>
|
||
<li><a href="#vec_div_scalar"><code>operator/</code></a></li>
|
||
<li><a href="#vec_mul_eq_scalar"><code>operator*=</code></a></li>
|
||
<li><a href="#vec_mul_scalar"><code>operator*</code></a></li>
|
||
<li><a href="#vec_eq"><code>operator==</code></a></li>
|
||
<li><a href="#vec_neq"><code>operator!=</code></a></li>
|
||
<li><a href="#vec_cmp"><code>cmp</code></a></li>
|
||
<li><a href="#vec_mag_sqr"><code>mag_sqr</code></a></li>
|
||
<li><a href="#vec_mag"><code>mag</code></a></li>
|
||
<li><a href="#vec_normalized"><code>normalized</code></a></li>
|
||
<li><a href="#vec_normalize"><code>normalize</code></a></li>
|
||
<li><a href="#vec_dot"><code>dot</code></a></li>
|
||
<li><a href="#vec_cross"><code>cross</code></a></li>
|
||
<li><a href="#zero_vec"><code>zero_vec</code></a></li>
|
||
<li><a href="#vec_set_zero"><code>set_zero</code></a></li>
|
||
<li><a href="#vec_scalar_cast"><code>scalar_cast</code></a></li>
|
||
<li><a href="#vref"><code>vref</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_matrix_operations">Generic matrix operations</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#mat_assign"><code>assign</code></a></li>
|
||
<li><a href="#mat_convert_to"><code>convert_to</code></a></li>
|
||
<li><a href="#mat_minus_eq_scalar"><code>operator-=</code></a></li>
|
||
<li><a href="#mat_minus_unary"><code>operator-</code> (unary)</a></li>
|
||
<li><a href="#mat_minus"><code>operator-</code></a></li>
|
||
<li><a href="#mat_plus_eq_scalar"><code>operator+=</code></a></li>
|
||
<li><a href="#mat_plus"><code>operator+</code></a></li>
|
||
<li><a href="#mat_div_eq_scalar"><code>operator/=</code> (scalar)</a></li>
|
||
<li><a href="#mat_div_scalar"><code>operator/</code> (scalar)</a></li>
|
||
<li><a href="#mat_mul_eq"><code>operator*=</code></a></li>
|
||
<li><a href="#mat_mul_eq_scalar"><code>operator*=</code> (scalar)</a></li>
|
||
<li><a href="#mat_mul"><code>operator*</code></a></li>
|
||
<li><a href="#mat_mul_scalar"><code>operator*</code> (scalar)</a></li>
|
||
<li><a href="#mat_eq"><code>operator==</code></a></li>
|
||
<li><a href="#mat_neq"><code>operator!=</code></a></li>
|
||
<li><a href="#mat_cmp"><code>cmp</code></a></li>
|
||
<li><a href="#mat_inverse"><code>inverse</code></a></li>
|
||
<li><a href="#zero_mat"><code>zero_mat</code></a></li>
|
||
<li><a href="#mat_set_zero"><code>set_zero</code></a></li>
|
||
<li><a href="#identity_mat"><code>identity_mat</code></a></li>
|
||
<li><a href="#mat_set_identity"><code>set_identity</code></a></li>
|
||
<li><a href="#rot_mat"><code>rot_mat</code> / Euler angles</a></li>
|
||
<li><a href="#mat_set_rot"><code>set_rot</code> / Euler angles</a></li>
|
||
<li><a href="#mat_rotate"><code>rotate</code> / Euler angles</a></li>
|
||
<li><a href="#rotx_mat"><code>rotx_mat</code></a></li>
|
||
<li><a href="#mat_set_rotx"><code>set_rotx</code></a></li>
|
||
<li><a href="#mat_rotate_x"><code>rotate_x</code></a></li>
|
||
<li><a href="#roty_mat"><code>roty_mat</code></a></li>
|
||
<li><a href="#mat_set_roty"><code>set_roty</code></a></li>
|
||
<li><a href="#mat_rotate_y"><code>rotate_y</code></a></li>
|
||
<li><a href="#rotz_mat"><code>rotz_mat</code></a></li>
|
||
<li><a href="#mat_set_rotz"><code>set_rotz</code></a></li>
|
||
<li><a href="#mat_rotate_z"><code>rotate_z</code></a></li>
|
||
<li><a href="#determinant"><code>determinant</code></a></li>
|
||
<li><a href="#perspective_lh"><code>perspective_lh</code></a></li>
|
||
<li><a href="#perspective_rh"><code>perspective_rh</code></a></li>
|
||
<li><a href="#mat_scalar_cast"><code>scalar_cast</code></a></li>
|
||
<li><a href="#mref"><code>mref</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_quaternion_vector_operations">Generic quaternion-vector operations</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#quat_vec_mul"><code>operator*</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_matrix_vector_operations">Generic matrix-vector operations</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#mat_vec_mul"><code>operator*</code></a></li>
|
||
<li><a href="#transform_vector"><code>transform_vector</code></a></li>
|
||
<li><a href="#transform_point"><code>transform_pointt</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_matrix_to_matrix_view_proxies">Generic matrix-to-matrix view proxies</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#del_row"><code>del_row</code></a></li>
|
||
<li><a href="#del_col"><code>del_col</code></a></li>
|
||
<li><a href="#del_row_col"><code>del_row_col</code></a></li>
|
||
<li><a href="#neg_row"><code>neg_row</code></a></li>
|
||
<li><a href="#neg_col"><code>neg_col</code></a></li>
|
||
<li><a href="#swap_rows"><code>swap_rows</code></a></li>
|
||
<li><a href="#swap_cols"><code>swap_cols</code></a></li>
|
||
<li><a href="#transposed"><code>transposed</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_vector_to_matrix_view_proxies">Generic vector-to-matrix view proxies</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#col_mat"><code>col_mat</code></a></li>
|
||
<li><a href="#row_mat"><code>row_mat</code></a></li>
|
||
<li><a href="#translation_mat"><code>translation_mat</code></a></li>
|
||
<li><a href="#diag_mat"><code>diag_mat</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_generic_matrix_to_vector_view_proxies">Generic matrix-to-vector view proxies</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#col"><code>col</code></a></li>
|
||
<li><a href="#row"><code>row</code></a></li>
|
||
<li><a href="#diag"><code>diag</code></a></li>
|
||
<li><a href="#translation"><code>translation</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_exceptions">Exceptions</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#error"><code>error</code></a></li>
|
||
<li><a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a></li>
|
||
<li><a href="#zero_determinant_error"><code>zero_determinant_error</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_macros_and_configuration_boost_qvm">Macros and configuration: BOOST_QVM_</a>
|
||
<ul class="sectlevel3">
|
||
<li><a href="#BOOST_QVM_INLINE"><code>INLINE</code></a></li>
|
||
<li><a href="#BOOST_QVM_FORCE_INLINE"><code>FORCE_INLINE</code></a></li>
|
||
<li><a href="#BOOST_QVM_INLINE_TRIVIAL"><code>INLINE_TRIVIAL</code></a></li>
|
||
<li><a href="#BOOST_QVM_INLINE_CRITICAL"><code>INLINE_CRITICAL</code></a></li>
|
||
<li><a href="#BOOST_QVM_INLINE_OPERATIONS"><code>INLINE_OPERATIONS</code></a></li>
|
||
<li><a href="#BOOST_QVM_INLINE_RECURSION"><code>INLINE_RECURSION</code></a></li>
|
||
<li><a href="#BOOST_QVM_ASSERT"><code>ASSERT</code></a></li>
|
||
<li><a href="#BOOST_QVM_STATIC_ASSERT"><code>STATIC_ASSERT</code></a></li>
|
||
<li><a href="#BOOST_QVM_THROW_EXCEPTION"><code>THROW_EXCEPTION</code></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_design_rationale">Design rationale</a></li>
|
||
<li><a href="#_code_generator">Code generator</a></li>
|
||
<li><a href="#_known_quirks_and_issues">Known quirks and issues</a>
|
||
<ul class="sectlevel2">
|
||
<li><a href="#_capturing_view_proxies_with_code_auto_code">Capturing view proxies with <code>auto</code></a></li>
|
||
<li><a href="#_binding_qvm_overloads_from_an_unrelated_namespace">Binding QVM overloads from an unrelated namespace</a></li>
|
||
<li><a href="#_link_errors_when_calling_math_functions_with_int_arguments">Link errors when calling math functions with int arguments</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#_q_a">Q&A</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div id="content">
|
||
<div class="sect1">
|
||
<h2 id="_abstract">Abstract</h2>
|
||
<div class="sectionbody">
|
||
<div class="paragraph">
|
||
<p>Boost QVM is a generic library for working with Quaternions, Vectors and Matrices of static size with the emphasis on 2, 3 and 4-dimensional operations needed in graphics, video games and simulation applications.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>All operations are implemented in terms of free function templates using <a href="https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error">SFINAE</a>, compatible with any user-defined quaternion, vector or matrix type. Binary operations are able to work with disparate value types.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The library also provides <a href="#view_proxy">view proxies</a> that can be used to map one lvalue type to another with zero overhead, and without the creating temporary objects.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_distribution">Distribution</h2>
|
||
<div class="sectionbody">
|
||
<div class="paragraph">
|
||
<p>QVM is part of <a href="https://www.boost.org/">Boost</a> and is distributed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The source code is available in <a href="https://github.com/boostorg/qvm">BOOST QVM GitHub repository</a>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>© 2008-2018 Emil Dotchevski and Reverge Studios, Inc.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_feedback_support">Feedback / support</h2>
|
||
<div class="sectionbody">
|
||
<div class="paragraph">
|
||
<p>Please use the <a href="https://lists.boost.org/mailman/listinfo.cgi/boost">Boost Developers mailing list</a>.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_portability">Portability</h2>
|
||
<div class="sectionbody">
|
||
<div class="paragraph">
|
||
<p>See the <a href="https://travis-ci.org/boostorg/qvm">Boost QVM Travis CI Builds</a>.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_tutorial">Tutorial</h2>
|
||
<div class="sectionbody">
|
||
<div class="sect2">
|
||
<h3 id="_quaternions_vectors_matrices">Quaternions, Vectors, Matrices</h3>
|
||
<div class="paragraph">
|
||
<p>Out of the box Boost QVM defines generic yet simple <a href="#quat"><code>quat</code></a>, <a href="#vec"><code>vec</code></a> and <a href="#mat"><code>mat</code></a> types. For example, the following snippet creates a quaternion object that rotates around the X axis:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">quat<<span class="predefined-type">float</span>> rx = rotx_quat(<span class="float">3</span><span class="float">.14159f</span>);</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Similarly, a matrix that translates by a given vector can be created as follows:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">vec<<span class="predefined-type">float</span>,<span class="integer">3</span>> v = {<span class="integer">0</span>,<span class="integer">0</span>,<span class="integer">7</span>};
|
||
mat<<span class="predefined-type">float</span>,<span class="integer">4</span>,<span class="integer">4</span>> tr = translation_mat(v);</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The usual quaternion, vector and matrix operations work on these Boost QVM types, however the operations are decoupled from any specific type: they work on any suitable type that has been registered by specializing the <a href="#quat_traits"><code>quat_traits</code></a>, <a href="#vec_traits"><code>vec_traits</code></a> and <a href="#mat_traits"><code>mat_traits</code></a> templates.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>For example, a user-defined 3D vector type <code>float3</code> can be introduced to Boost QVM as follows:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">struct</span> float3 { <span class="predefined-type">float</span> a[<span class="integer">3</span>]; };
|
||
|
||
<span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> vec_traits<float3> {
|
||
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> dim=<span class="integer">3</span>;
|
||
<span class="keyword">typedef</span> <span class="predefined-type">float</span> scalar_type;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element( float3 & v ) {
|
||
<span class="keyword">return</span> v.a[I];
|
||
}
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type read_element( float3 <span class="directive">const</span> & v ) {
|
||
<span class="keyword">return</span> v.a[I];
|
||
}
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element_idx( <span class="predefined-type">int</span> i, float3 & v ) {
|
||
<span class="keyword">return</span> v.a[i];
|
||
} <span class="comment">//optional</span>
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type read_element_idx( <span class="predefined-type">int</span> i, float3 <span class="directive">const</span> & v ) {
|
||
<span class="keyword">return</span> v.a[i];
|
||
} <span class="comment">//optional</span>
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Equivalently, using the <a href="#vec_traits_defaults"><code>vec_traits_defaults</code></a> template the above can be shortened to:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> vec_traits<float3>: vec_traits_defaults<float3,<span class="predefined-type">float</span>,<span class="integer">3</span>> {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element( float3 & v ) {
|
||
<span class="keyword">return</span> v.a[I];
|
||
}
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element_idx( <span class="predefined-type">int</span> i, float3 & v ) {
|
||
<span class="keyword">return</span> v.a[i];
|
||
} <span class="comment">//optional</span>
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>After a similar specialization of the <a href="#mat_traits"><code>mat_traits</code></a> template for a user-defined 3x3 matrix type <code>float33</code>, the full range of vector and matrix operations defined by Boost QVM headers becomes available automatically:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">float3 v;
|
||
X(v) = <span class="integer">0</span>;
|
||
Y(v) = <span class="integer">0</span>;
|
||
Z(v) = <span class="integer">7</span>;
|
||
<span class="predefined-type">float</span> vmag = mag(v);
|
||
float33 m = rotx_mat<<span class="integer">3</span>>(<span class="float">3</span><span class="float">.14159f</span>);
|
||
float3 vrot = m * v;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>User-defined quaternion types are similarly introduced to Boost QVM by specializing the <a href="#quat_traits"><code>quat_traits</code></a> template.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_c_arrays">C Arrays</h3>
|
||
<div class="paragraph">
|
||
<p>In <a href="#boost/qvm/quat_traits_array.hpp"><code>boost/qvm/quat_traits_array.hpp</code></a>, <a href="#boost/qvm/vec_traits_array.hpp"><code>boost/qvm/vec_traits_array.hpp</code></a> and <a href="#boost/qvm/mat_traits_array.hpp"><code>boost/qvm/mat_traits_array.hpp</code></a> Boost QVM defines appropriate <a href="#quat_traits"><code>quat_traits</code></a>, <a href="#vec_traits"><code>vec_traits</code></a> and <a href="#mat_traits"><code>mat_traits</code></a> specializations that allow Boost QVM functions to operate directly on plain old C arrays:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> v[<span class="integer">3</span>] = {<span class="integer">0</span>,<span class="integer">0</span>,<span class="integer">7</span>};
|
||
float3 vrot = rotx_mat<<span class="integer">3</span>>(<span class="float">3</span><span class="float">.14159f</span>) * v;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Naturally, operator overloads cannot kick in if all elements of an expression are of built-in types. The following is still illegal:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> v[<span class="integer">3</span>] = {<span class="integer">0</span>,<span class="integer">0</span>,<span class="integer">7</span>};
|
||
v *= <span class="integer">42</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The <a href="#vref"><code>vref</code></a> and <a href="#mref"><code>mref</code></a> function templates can be used to work around this issue:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> v[<span class="integer">3</span>] = {<span class="integer">0</span>,<span class="integer">0</span>,<span class="integer">7</span>};
|
||
vref(v) *= <span class="integer">42</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="view_proxy">View proxies</h3>
|
||
<div class="paragraph">
|
||
<p>Boost QVM defines various function templates that provide static mapping between (possibly user-defined) quaternion, vector and matrix types. The example below multiplies column 1 (Boost QVM indexes are always zero-based) of the matrix <code>m</code> by a scalar:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> multiply_column1( float33 & m, <span class="predefined-type">float</span> scalar ) {
|
||
col<<span class="integer">1</span>>(m) *= scalar;
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <a href="#col"><code>col<1>(m)</code></a> is an lvalue of an unspecified 3D vector type that refers to column 1 of <code>m</code>. Note however that this does not create any temporary objects; instead <code>operator*=</code> above works directly with a reference to <code>m</code>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Here is another example, multiplying a transposed view of a matrix by a vector of some user-defined type <code>float3</code>:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">float3 v = {<span class="integer">0</span>,<span class="integer">0</span>,<span class="integer">7</span>};
|
||
float3 vrot = transposed(rotx_mat<<span class="integer">3</span>>(<span class="float">3</span><span class="float">.14159f</span>)) * v;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In general, the various view proxy functions return references of unspecified, non-copyable types that refer to the original object. They can be assigned from or converted to any compatible vector or matrix type.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_swizzling">Swizzling</h3>
|
||
<div class="paragraph">
|
||
<p>Boost QVM allows accessing vector elements by swizzling, exposing vector views of different dimensions, and/or views with reordered elements. The example below rotates <code>v</code> around the X axis, and stores the resulting vector back in <code>v</code> but with the X and Y elements swapped:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">float3 v = {<span class="integer">0</span>,<span class="integer">0</span>,<span class="integer">7</span>};
|
||
YXZ(v) = rotx_mat<<span class="integer">3</span>>(<span class="float">3</span><span class="float">.14159f</span>) * v;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>A special case of swizzling provides next-dimension-view of a vector object, adding either 0 or 1 as its last component. Assuming <code>float3</code> is a 3D vector type, and <code>float4</code> is a 4D vector type, the following statements are valid:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">float3 v = {<span class="integer">0</span>,<span class="integer">0</span>,<span class="integer">7</span>};
|
||
float4 point = XYZ1(v); <span class="comment">//{0,0,7,1}</span>
|
||
float4 vector = XYZ0(v); <span class="comment">//{0,0,7,0}</span></code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>It is also valid for swizzling to address vector elements more than once:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">float3 v = {<span class="integer">0</span>,<span class="integer">0</span>,<span class="integer">7</span>};
|
||
float4 v1 = ZZZZ(v); <span class="comment">//{7,7,7,7}</span></code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Boost QVM defines all permutations of <code>X</code>, <code>Y</code>, <code>Z</code>, <code>W</code> for 1D, 2D, 3D and 4D swizzling, plus each dimension defines variants with 0 or 1 used at any position (if 0 or 1 appear at the first position, the swizzling function name begins with underscore, e.g. <code>_1XY</code>).</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The swizzling syntax can also be used to bind scalars as vectors. For example:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">float3 v = _00X(<span class="integer">4</span><span class="float">2</span><span class="float">.0f</span>); <span class="comment">//{0,0,42}</span></code></pre>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="enable_if">SFINAE/enable_if</h3>
|
||
<div class="paragraph">
|
||
<p>SFINAE stands for Substitution Failure Is Not An Error. This refers to a situation in C++ where an invalid substitution of template parameters (including when those parameters are deduced implicitly as a result of an unqualified call) is not in itself an error.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In absence of concepts support, SFINAE can be used to disable function template overloads that would otherwise present a signature that is too generic. More formally, this is supported by the Boost <code>enable_if</code> library.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>For example, Boost QVM defines <code>operator*</code> overload which works with any user-defined matrix and vector types. The naive approach would be to declare this overload as follows:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Matrix</span>,<span class="keyword">class</span> <span class="class">Vector</span>>
|
||
Vector <span class="directive">operator</span>*( Matrix <span class="directive">const</span> & m, Vector <span class="directive">const</span> & v );</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Even if the function definition might contain code that would compile only for <code>Matrix</code> and <code>Vector</code> types, because the function declaration itself is valid, it will participate in overload rezolutions when multiplying objects of any two types whatsoever. This typically renders overload resolutions ambiguous and the compiler (correctly) issues an error.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Using <code>enable_if</code>, Boost QVM declares such overloads in a way that preserves their generic signature but only participate in overload resolutions if the passed parameters make sense depending on the semantics of the operation being defined:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> enable_if_c<
|
||
is_mat<A>::value && is_vec<B>::value && mat_traits<A>::cols==vec_traits<B>::dim, <span class="comment">//Condition</span>
|
||
B>::type <span class="comment">//Return type</span>
|
||
<span class="directive">operator</span>*( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>For brevity, function declarations throughout this documentation specify the condition which controls whether they are enabled or not without specifying exactly what <code>enable_if</code> construct is used to achieve this effect.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_interoperability">Interoperability</h3>
|
||
<div class="paragraph">
|
||
<p>An important design goal of Boost QVM is that it works seamlessly with 3rd-party quaternion, vector and matrix types and libraries. Even when such libraries overload the same C++ operators as Boost QVM, it is safe to bring the entire <code>boost::qvm</code> namespace in scope by specifying:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">using</span> <span class="keyword">namespace</span> boost::qvm;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The above using directive does not introduce ambiguities with function and operator overloads defined by a 3rd-party library because:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>Most <code>boost::qvm</code> function overloads and all operator overloads use SFINAE/<code>enable_if</code>, which makes them "disappear" unless an expression uses types that have the appropriate Boost QVM-specific type traits defined;</p>
|
||
</li>
|
||
<li>
|
||
<p>Whenever such overloads are compatible with a given expression, their signature is extremely generic, which means that any other (user-defined) compatible overload will be a better match in any overload resolution.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
Bringing the entire boost::qvm namespace in scope may introduce ambiguities when accessing types (as opposed to functions) defined by 3rd-party libraries. In that case, you can safely bring namespace <code>boost::qvm::sfinae</code> in scope instead, which contains only function and operator overloads that use SFINAE/<code>enable_if</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="_specifying_return_types_for_binary_operations">Specifying return types for binary operations</h4>
|
||
<div class="paragraph">
|
||
<p>Bringing the <code>boost::qvm</code> namespace in scope lets you mix vector and matrix types that come from different APIs into a common, type-safe framework. In this case however, it should be considered what types should be returned by binary operations that return an object by value. For example, if you multiply a 3x3 matrix <code>m1</code> of type <code>user_matrix1</code> by a 3x3 matrix <code>m2</code> of type <code>user_matrix2</code>, what type should that operation return?</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The answer is that by default, Boost QVM returns some kind of compatible matrix type, so it is always safe to write:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">auto</span> & m = m1 * m2;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>However, the type deduced by default converts implicitly to any compatible matrix type, so the following is also valid, at the cost of a temporary:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">user_matrix1 m = m1 * m2;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>While the temporary object can be optimized away by many compilers, it can be avoided altogether by specializing the <a href="#deduce_mat2"><code>deduce_mat2</code></a> template. For example, to specify that multiplying a <code>user_matrix1</code> by a <code>user_matrix2</code> should always produce a <code>user_matrix1</code> object, you could write:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> deduce_mat2<user_matrix1,user_matrix2,<span class="integer">3</span>,<span class="integer">3</span>> {
|
||
<span class="keyword">typedef</span> user_matrix1 type;
|
||
};
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> deduce_mat2<user_matrix2,user_matrix1,<span class="integer">3</span>,<span class="integer">3</span>> {
|
||
<span class="keyword">typedef</span> user_matrix1 type;
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="admonitionblock warning">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-warning" title="Warning"></i>
|
||
</td>
|
||
<td class="content">
|
||
<div class="paragraph">
|
||
<p>Be mindful of potential ODR violation when using <a href="#deduce_quat2"><code>deduce_quat2</code></a>, <a href="#deduce_vec2"><code>deduce_vec2</code></a> and <a href="#deduce_mat2"><code>deduce_mat2</code></a> in independent libraries. For example, this could happen if <code>lib1</code> defines <code>deduce_vec2<lib1::vec,lib2::vec>::type</code> as <code>lib1::vec</code> and in the same program <code>lib2</code> defines <code>deduce_vec2<lib1::vec,lib2::vec>::type</code> as <code>lib2::vec</code>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>It is best to keep such specializations out of <code>lib1</code> and <code>lib2</code>. Of course, it is always safe for <code>lib1</code> and <code>lib2</code> to use <a href="#convert_to"><code>convert_to</code></a> to convert between the <code>lib1::vec</code> and <code>lib2::vec</code> types as needed.</p>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="_specifying_return_types_for_unary_operations">Specifying return types for unary operations</h4>
|
||
<div class="paragraph">
|
||
<p>Perhaps surprisingly, unary operations that return an object by value have a similar, though simpler issue. That’s because the argument they’re called with may not be copyable, as in:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> m[<span class="integer">3</span>][<span class="integer">3</span>];
|
||
<span class="directive">auto</span> & inv = inverse(m);</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Above, the object returned by <a href="#mat_inverse"><code>inverse</code></a> and captured by <code>inv</code> can not be of type <code>float[3][3]</code>, because that type isn’t copyable. By default, Boost QVM "just works", returning an object of suitable matrix type that is copyable. This deduction process can be controlled, by specializing the <a href="#deduce_mat"><code>deduce_mat</code></a> template.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="_converting_between_different_quaternion_vector_and_matrix_types">Converting between different quaternion, vector and matrix types</h4>
|
||
<div class="paragraph">
|
||
<p>Any time you need to create a matrix of a particular C++ type from any other compatible matrix type, you can use the <a href="#convert_to"><code>convert_to</code></a> function:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">user_matrix2 m=convert_to<user_matrix2>(m1 * m2);</code></pre>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_header_files">Header files</h3>
|
||
<div class="paragraph">
|
||
<p>Boost QVM is split into multiple headers to allow different compilation units to <code>#include</code> only the components they need. Each function in this document specifies the exact header that must be <code>#included</code> in order to use it.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The tables below list commonly used components and the headers they’re found in. Header names containing a number define functions that only work with objects of that dimension; e.g. <code>vec_operations2.hpp</code> contains only functions for working with 2D vectors.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The header <code>boost/qvm/all.hpp</code> is provided for convenience. It includes all other QVM headers.</p>
|
||
</div>
|
||
<table class="tableblock frame-all grid-all spread">
|
||
<caption class="title">Table 1. Quaternion header files</caption>
|
||
<colgroup>
|
||
<col style="width: 33.3333%;">
|
||
<col style="width: 66.6667%;">
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Quaternion traits</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/quat_traits.hpp>
|
||
#include <boost/qvm/quat_traits_array.hpp>
|
||
#include <boost/qvm/deduce_quat.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Quaternion element access</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/quat_access.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Quaternion operations</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/quat_operations.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#quat"><code>quat</code></a> class template</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/quat.hpp></pre></div></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="tableblock frame-all grid-all spread">
|
||
<caption class="title">Table 2. Vector header files</caption>
|
||
<colgroup>
|
||
<col style="width: 33.3333%;">
|
||
<col style="width: 66.6667%;">
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vector traits</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/vec_traits.hpp>
|
||
#include <boost/qvm/vec_traits_array.hpp>
|
||
#include <boost/qvm/deduce_vec.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vector element access</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/vec_access.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vector <a href="#swizzling">swizzling</a></p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/swizzle.hpp>
|
||
#include <boost/qvm/swizzle2.hpp>
|
||
#include <boost/qvm/swizzle3.hpp>
|
||
#include <boost/qvm/swizzle4.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vector operations</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/vec_operations.hpp>
|
||
#include <boost/qvm/vec_operations2.hpp>
|
||
#include <boost/qvm/vec_operations3.hpp>
|
||
#include <boost/qvm/vec_operations4.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Quaternion-vector operations</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/quat_vec_operations.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vector-matrix operations</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/vec_mat_operations.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vector-matrix <a href="#view_proxy">view proxies</a></p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/map_vec_mat.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#vec"><code>vec</code></a> class template</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/vec.hpp></pre></div></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="tableblock frame-all grid-all spread">
|
||
<caption class="title">Table 3. Matrix header files</caption>
|
||
<colgroup>
|
||
<col style="width: 33.3333%;">
|
||
<col style="width: 66.6667%;">
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix traits</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/mat_traits.hpp>
|
||
#include <boost/qvm/mat_traits_array.hpp>
|
||
#include <boost/qvm/deduce_mat.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix element access</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/mat_access.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix operations</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/mat_operations.hpp>
|
||
#include <boost/qvm/mat_operations2.hpp>
|
||
#include <boost/qvm/mat_operations3.hpp>
|
||
#include <boost/qvm/mat_operations4.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix-matrix <a href="#view_proxy">view proxies</a></p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/map_mat_mat.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix-vector <a href="#view_proxy">view proxies</a></p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/map_mat_vec.hpp></pre></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#mat"><code>mat</code></a> class template</p></td>
|
||
<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include <boost/qvm/mat.hpp></pre></div></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_reference">Reference</h2>
|
||
<div class="sectionbody">
|
||
<div class="sect2">
|
||
<h3 id="type_traits">Type traits system</h3>
|
||
<div class="paragraph">
|
||
<p>Boost QVM is designed to work with user-defined quaternion, vector and matrix types, as well as user-defined scalar types. This section formally defines the way such types can be integrated.</p>
|
||
</div>
|
||
<hr>
|
||
<div class="sect3">
|
||
<h4 id="scalar_requirements">Scalar requirements</h4>
|
||
<div class="paragraph">
|
||
<p>A valid scalar type <code>S</code> must have accessible destructor, default constructor, copy constructor and assignment operator, and must support the following operations:</p>
|
||
</div>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">S <span class="directive">operator</span>*( S, S );
|
||
S <span class="directive">operator</span>/( S, S );
|
||
S <span class="directive">operator</span>+( S, S );
|
||
S <span class="directive">operator</span>-( S, S );
|
||
|
||
S & <span class="directive">operator</span>*=( S &, S );
|
||
S & <span class="directive">operator</span>/=( S &, S );
|
||
S & <span class="directive">operator</span>+=( S &, S );
|
||
S & <span class="directive">operator</span>-=( S &, S );
|
||
|
||
<span class="predefined-type">bool</span> <span class="directive">operator</span>==( S, S );
|
||
<span class="predefined-type">bool</span> <span class="directive">operator</span>!=( S, S );</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In addition, the expression <code>S(0)</code> should construct a scalar of value zero, and <code>S(1)</code> should construct a scalar of value one, or else the <a href="#scalar_traits"><code>scalar_traits</code></a> template must be specialized appropriately.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="is_scalar"><code>is_scalar</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/scalar_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
<span class="keyword">struct</span> is_scalar {
|
||
<span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">false</span>;
|
||
};
|
||
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">char</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">signed</span> <span class="predefined-type">char</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">unsigned</span> <span class="predefined-type">char</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">signed</span> <span class="predefined-type">short</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">unsigned</span> <span class="predefined-type">short</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">signed</span> <span class="predefined-type">int</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">unsigned</span> <span class="predefined-type">int</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">signed</span> <span class="predefined-type">long</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">unsigned</span> <span class="predefined-type">long</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">float</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">double</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
<span class="keyword">template</span> <> <span class="keyword">struct</span> is_scalar<<span class="predefined-type">long</span> <span class="predefined-type">double</span>> { <span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value=<span class="predefined-constant">true</span>; };
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This template defines a compile-time boolean constant value which can be used to determine whether a type <code>T</code> is a valid scalar type. It must be specialized together with the <a href="#scalar_traits"><code>scalar_traits</code></a> template in order to introduce a user-defined scalar type to Boost QVM. Such types must satisfy the <a href="#scalar_requirements">scalar requirements</a>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="scalar_traits"><code>scalar_traits</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/scalar_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Scalar</span>>
|
||
<span class="keyword">struct</span> scalar_traits {
|
||
|
||
BOOST_QVM_INLINE_CRITICAL
|
||
<span class="directive">static</span> Scalar value( <span class="predefined-type">int</span> v ) {
|
||
<span class="keyword">return</span> Scalar(v);
|
||
}
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This template may be specialized for user-defined scalar types to define the appropriate conversion from <code>int</code>; this is primarily used whenever Boost QVM needs to deduce a zero or one value.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="deduce_scalar"><code>deduce_scalar</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/deduce_scalar.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">struct</span> deduce_scalar
|
||
{
|
||
<span class="keyword">typedef</span> <span class="keyword">typename</span> impl<A,B>::type type;
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<p><code>A</code> and <code>B</code> satisfy the <a href="#scalar_requirements">scalar requirements</a>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>If <code>A</code> and <code>B</code> are the same type, <code>impl<A,B>::type</code> returns that type. Otherwise, <code>impl<A,B>::type</code> is well defined for the following types only: <code>signed</code>/<code>unsigned char</code>, <code>signed</code>/<code>unsigned short</code>, <code>signed</code>/<code>unsigned int</code>, <code>signed</code>/<code>unsigned long</code>, <code>float</code> and <code>double</code>. The deduction logic is as follows:</p>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>if either of <code>A</code> and <code>B</code> is <code>double</code>, the result is <code>double</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p>else, if one of <code>A</code> or <code>B</code> is an integer type and the other is <code>float</code>, the result is <code>float</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p>else, if one of <code>A</code> or <code>B</code> is a signed integer and the other type is unsigned integer, the signed type is changed to unsigned, and then the lesser of the two integers is promoted to the other.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
This template is used by generic binary operations that return a scalar, to deduce the return type based on the (possibly different) scalars of their arguments.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="scalar"><code>scalar</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/scalar_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
<span class="keyword">struct</span> scalar {
|
||
<span class="keyword">typedef</span> <span class="comment">/*exact definition unspecified*/</span> type;
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <a href="#quat_traits"><code>quat_traits<T>::scalar_type</code></a> evaluates to the scalar type of the quaternion type <code>T</code> (if <a href="#is_quat"><code>is_quat<T>::value</code></a> is <code>true</code>).</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <a href="#vec_traits"><code>vec_traits<T>::scalar_type</code></a> evaluates to the scalar type of the vector type <code>T</code> (if <a href="#is_vec"><code>is_vec<T>::value</code></a> is <code>true</code>).</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <a href="#mat_traits"><code>mat_traits<T>::scalar_type</code></a> evaluates to the scalar type of the matrix type <code>T</code> (if <a href="#is_mat"><code>is_mat<T>::value</code></a> is <code>true</code>).</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>scalar<T>::type</code> is similar, except that it automatically detects whether <code>T</code> is a vector or a matrix or a quaternion type.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="is_quat"><code>is_quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
<span class="keyword">struct</span> is_quat {
|
||
|
||
<span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value = <span class="predefined-constant">false</span>;
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This type template defines a compile-time boolean constant value which can be used to determine whether a type <code>T</code> is a quaternion type. For quaternion types, the <a href="#quat_traits"><code>quat_traits</code></a> template can be used to access their elements generically, or to obtain their <code>scalar type</code>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_traits"><code>quat_traits</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Q</span>>
|
||
<span class="keyword">struct</span> quat_traits {
|
||
|
||
<span class="comment">/*main template members unspecified*/</span>
|
||
|
||
};
|
||
|
||
<span class="comment">/*
|
||
User-defined (possibly partial) specializations:
|
||
|
||
template <>
|
||
struct quat_traits<Q> {
|
||
|
||
typedef <<user-defined>> scalar_type;
|
||
|
||
template <int I>
|
||
static inline scalar_type read_element( Quaternion const & q );
|
||
|
||
template <int I>
|
||
static inline scalar_type & write_element( Quaternion & q );
|
||
|
||
};
|
||
*/</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The <code>quat_traits</code> template must be specialized for (user-defined) quaternion types in order to enable quaternion operations defined in Boost QVM headers for objects of those types.</p>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
QVM quaternion operations do not require that quaternion types are copyable.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main <code>quat_traits</code> template members are not specified. Valid specializations are required to define the following members:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>scalar_type</code>: the expression <code>quat_traits<Quaternion>::scalar_type</code> must be a value type which satisfies the <a href="#scalar_requirements"><code>scalar requirements</code></a>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In addition, valid specializations of the <code>quat_traits</code> template must define at least one of the following access functions as static members, where <code>q</code> is an object of type <code>Quaternion</code>, and <code>I</code> is compile-time integer constant:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>read_element</code>: the expression <code>quat_traits<Quaternion>::read_element<I>(q)</code> returns either a copy of or a <code>const</code> reference to the <code>I</code>-th element of <code>q</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>write_element</code>: the expression <code>quat_traits<Quaternion>::write_element<I>(q)</code> returns mutable reference to the <code>I</code>-th element of <code>q</code>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
For the quaternion <code>a + bi + cj + dk</code>, the elements are assumed to be in the following order: <code>a</code>, <code>b</code>, <code>c</code>, <code>d</code>; that is, <code>I</code>=<code>0</code>/<code>1</code>/<code>2</code>/<code>3</code> would access <code>a</code>/<code>b</code>/<code>c</code>/<code>d</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>It is illegal to call any of the above functions unless <code>is_quat<Quaternion>::value</code> is true. Even then, quaternion types are allowed to define only a subset of the access functions.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Below is an example of a user-defined quaternion type, and its corresponding specialization of the quat_traits template:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#include</span> <span class="include"><boost/qvm/quat_traits.hpp></span>
|
||
|
||
<span class="keyword">struct</span> fquat { <span class="predefined-type">float</span> a[<span class="integer">4</span>]; };
|
||
|
||
<span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> quat_traits<fquat> {
|
||
|
||
<span class="keyword">typedef</span> <span class="predefined-type">float</span> scalar_type;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element( fquat & q ) {
|
||
<span class="keyword">return</span> q.a[I];
|
||
}
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type read_element( fquat <span class="directive">const</span> & q ) {
|
||
<span class="keyword">return</span> q.a[I];
|
||
}
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Equivalently, using the <a href="#quat_traits_defaults"><code>quat_traits_defaults</code></a> template the above can be shortened to:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> quat_traits<fquat>: quat_traits_defaults<fquat,<span class="predefined-type">float</span>> {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element( fquat & q ) {
|
||
<span class="keyword">return</span> q.a[I];
|
||
}
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_traits_defaults"><code>quat_traits_defaults</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_traits_defaults.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">QuatType</span>,<span class="keyword">class</span> <span class="class">ScalarType</span>>
|
||
<span class="keyword">struct</span> quat_traits_defaults {
|
||
|
||
<span class="keyword">typedef</span> QuatType quat_type;
|
||
|
||
<span class="keyword">typedef</span> ScalarType scalar_type;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> BOOST_QVM_INLINE_CRITICAL
|
||
scalar_type read_element( quat_type <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> quat_traits<quat_type>::<span class="keyword">template</span>
|
||
write_element<I>(<span class="keyword">const_cast</span><quat_type &>(x));
|
||
}
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The <code>quat_traits_defaults</code> template is designed to be used as a public base for user-defined specializations of the <a href="#quat_traits"><code>quat_traits</code></a> template, to easily define the required members. If it is used, the only member that must be defined by the user in a <code>quat_traits</code> specialization is <code>write_element</code>; the <code>quat_traits_defaults</code> base will define <code>read_element</code>, as well as <code>scalar_type</code> automatically.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="deduce_quat"><code>deduce_quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/deduce_quat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Q</span>>
|
||
<span class="keyword">struct</span> deduce_quat {
|
||
<span class="keyword">typedef</span> Q type;
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code><a href="#is_quat">is_quat</a><Q>::value</code> is <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code><a href="#is_quat">is_quat</a><deduce_quat<Q>::type>::value</code> must be <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>deduce_quat<Q>::type</code> must be copyable.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This template is used by Boost QVM whenever it needs to deduce a copyable quaternion type from a single user-supplied function parameter of quaternion type. Note that <code>Q</code> itself may be non-copyable.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main template definition returns <code>Q</code>, which means that it is suitable only for copyable quaternion types. Boost QVM also defines (partial) specializations for the non-copyable quaternion types it produces. Users can define other (partial) specializations for their own types.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>A typical use of the <code>deduce_quat</code> template is for specifying the preferred quaternion type to be returned by the generic function template overloads in Boost QVM depending on the type of their arguments.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="deduce_quat2"><code>deduce_quat2</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/deduce_quat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">struct</span> deduce_quat2 {
|
||
<span class="keyword">typedef</span> <span class="comment">/*unspecified*/</span> type;
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>Both <code><a href="#scalar">scalar</a><A>::type</code> and <code>scalar<B>::type</code> are well defined;</p>
|
||
</li>
|
||
<li>
|
||
<p><code><a href="#is_quat">is_quat</a><A>::value</code> || <code>is_quat<B>::value</code> is <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>is_quat<deduce_quat2<A,B>::type>::value</code> must be <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>deduce_quat2<A,B>::type</code> must be copyable.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This template is used by Boost QVM whenever it needs to deduce a quaternion type from the types of two user-supplied function parameters. The returned type must have accessible copy constructor (the <code>A</code> and <code>B</code> types themselves could be non-copyable, and either one of them may not be a quaternion type.)</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main template definition returns an unspecified quaternion type with <a href="#quat_traits"><code>scalar_type</code></a> obtained by <code><a href="#deduce_scalar">deduce_scalar</a><A,B>::type</code>, except if <code>A</code> and <code>B</code> are the same quaternion type <code>Q</code>, in which case <code>Q</code> is returned, which is only suitable for copyable types. Boost QVM also defines (partial) specializations for the non-copyable quaternion types it produces. Users can define other (partial) specializations for their own types.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>A typical use of the <code>deduce_quat2</code> template is for specifying the preferred quaternion type to be returned by the generic function template overloads in Boost QVM depending on the type of their arguments.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="is_vec"><code>is_vec</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
<span class="keyword">struct</span> is_vec {
|
||
|
||
<span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value = <span class="predefined-constant">false</span>;
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This type template defines a compile-time boolean constant value which can be used to determine whether a type <code>T</code> is a vector type. For vector types, the <a href="#vec_traits"><code>vec_traits</code></a> template can be used to access their elements generically, or to obtain their dimension and <code>scalar type</code>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_traits"><code>vec_traits</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>>
|
||
<span class="keyword">struct</span> vec_traits {
|
||
|
||
<span class="comment">/*main template members unspecified*/</span>
|
||
|
||
};
|
||
|
||
<span class="comment">/*
|
||
User-defined (possibly partial) specializations:
|
||
|
||
template <>
|
||
struct vec_traits<V> {
|
||
|
||
static int const dim = <<user-defined>>;
|
||
|
||
typedef <<user-defined>> scalar_type;
|
||
|
||
template <int I>
|
||
static inline scalar_type read_element( Vector const & v );
|
||
|
||
template <int I>
|
||
static inline scalar_type & write_element( Vector & v );
|
||
|
||
static inline scalar_type read_element_idx( int i, Vector const & v );
|
||
static inline scalar_type & write_element_idx( int i, Vector & v );
|
||
|
||
};
|
||
*/</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The <code>vec_traits</code> template must be specialized for (user-defined) vector types in order to enable vector and matrix operations defined in Boost QVM headers for objects of those types.</p>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
QVM vector operations do not require that vector types are copyable.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main <code>vec_traits</code> template members are not specified. Valid specializations are required to define the following members:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>dim</code>: the expression <code>vec_traits<Vector>::dim</code> must evaluate to a compile-time integer constant greater than 0 that specifies the vector size.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>scalar_type</code>: the expression <code>vec_traits<Vector>::scalar_type</code> must be a value type which satisfies the <a href="#scalar_requirements"><code>scalar requirements</code></a>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In addition, valid specializations of the <code>vec_traits</code> template may define the following access functions as static members, where <code>v</code> is an object of type <code>Vector</code>, <code>I</code> is a compile-time integer constant, and <code>i</code> is a variable of type <code>int</code>:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>read_element</code>: the expression <code>vec_traits<Vector>::read_element<I>(v)</code> returns either a copy of or a const reference to the <code>I</code>-th element of <code>v</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>write_element</code>: the expression <code>vec_traits<Vector>::write_element<I>(v)</code> returns mutable reference to the <code>I</code>-th element of <code>v</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>read_element_idx</code>: the expression <code>vec_traits<Vector>::read_element_idx(i,v)</code> returns either a copy of or a <code>const</code> reference to the <code>i</code>-th element of <code>v</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>write_element_idx</code>: the expression <code>vec_traits<Vector>::write_element_idx(i,v)</code> returns mutable reference to the <code>i</code>-th element of <code>v</code>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>It is illegal to call any of the above functions unless <code>is_vec<Vector>::value</code> is true. Even then, vector types are allowed to define only a subset of the access functions. The general requirements are:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>At least one of <code>read_element</code> or <code>write_element</code> must be defined;</p>
|
||
</li>
|
||
<li>
|
||
<p>If <code>read_element_idx</code> is defined, <code>read_element</code> must also be defined;</p>
|
||
</li>
|
||
<li>
|
||
<p>If <code>write_element_idx</code> is defined, <code>write_element</code> must also be defined.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Below is an example of a user-defined 3D vector type, and its corresponding specialization of the <code>vec_traits</code> template:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#include</span> <span class="include"><boost/qvm/vec_traits.hpp></span>
|
||
|
||
<span class="keyword">struct</span> float3 { <span class="predefined-type">float</span> a[<span class="integer">3</span>]; };
|
||
|
||
<span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> vec_traits<float3> {
|
||
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> dim=<span class="integer">3</span>;
|
||
|
||
<span class="keyword">typedef</span> <span class="predefined-type">float</span> scalar_type;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element( float3 & v ) {
|
||
<span class="keyword">return</span> v.a[I];
|
||
}
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type read_element( float3 <span class="directive">const</span> & v ) {
|
||
<span class="keyword">return</span> v.a[I];
|
||
}
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element_idx( <span class="predefined-type">int</span> i, float3 & v ) {
|
||
<span class="keyword">return</span> v.a[i];
|
||
} <span class="comment">//optional</span>
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type read_element_idx( <span class="predefined-type">int</span> i, float3 <span class="directive">const</span> & v ) {
|
||
<span class="keyword">return</span> v.a[i];
|
||
} <span class="comment">//optional</span>
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Equivalently, using the <a href="#vec_traits_defaults"><code>vec_traits_defaults</code></a> template the above can be shortened to:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> vec_traits<float3>: vec_traits_defaults<float3,<span class="predefined-type">float</span>,<span class="integer">3</span>>
|
||
{
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element( float3 & v ) {
|
||
<span class="keyword">return</span> v.a[I];
|
||
}
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element_idx( <span class="predefined-type">int</span> i, float3 & v ) {
|
||
<span class="keyword">return</span> v.a[i];
|
||
} <span class="comment">//optional</span>
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_traits_defaults"><code>vec_traits_defaults</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_traits_defaults.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">VecType</span>,<span class="keyword">class</span> <span class="class">ScalarType</span>,<span class="predefined-type">int</span> Dim>
|
||
<span class="keyword">struct</span> vec_traits_defaults {
|
||
|
||
<span class="keyword">typedef</span> VecType vec_type;
|
||
<span class="keyword">typedef</span> ScalarType scalar_type;
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> dim=Dim;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> BOOST_QVM_INLINE_CRITICAL
|
||
scalar_type write_element( vec_type <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> vec_traits<vec_type>::<span class="keyword">template</span> write_element<I>(<span class="keyword">const_cast</span><vec_type &>(x));
|
||
}
|
||
|
||
<span class="directive">static</span> BOOST_QVM_INLINE_CRITICAL
|
||
scalar_type read_element_idx( <span class="predefined-type">int</span> i, vec_type <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> vec_traits<vec_type>::write_element_idx(i,<span class="keyword">const_cast</span><vec_type &>(x));
|
||
}
|
||
|
||
<span class="directive">protected</span>:
|
||
|
||
<span class="directive">static</span> BOOST_QVM_INLINE_TRIVIAL
|
||
scalar_type & write_element_idx( <span class="predefined-type">int</span> i, vec_type & m ) {
|
||
<span class="comment">/* unspecified */</span>
|
||
}
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The <code>vec_traits_defaults</code> template is designed to be used as a public base for user-defined specializations of the <a href="#vec_traits"><code>vec_traits</code></a> template, to easily define the required members. If it is used, the only member that must be defined by the user in a <code>vec_traits</code> specialization is <code>write_element</code>; the <code>vec_traits_defaults</code> base will define <code>read_element</code>, as well as <code>scalar_type</code> and <code>dim</code> automatically.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Optionally, the user may also define <code>write_element_idx</code>, in which case the <code>vec_traits_defaults</code> base will provide a suitable <code>read_element_idx</code> definition automatically. If not, <code>vec_traits_defaults</code> defines a protected implementation of <code>write_element_idx</code> which may be made publicly available by the deriving <code>vec_traits</code> specialization in case the vector type for which it is being specialized can not be indexed efficiently. This <code>write_element_idx</code> function is less efficient (using meta-programming), implemented in terms of the required user-defined <code>write_element</code>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="deduce_vec"><code>deduce_vec</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/deduce_vec.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>, <span class="predefined-type">int</span> Dim=vec_traits<Vector>::dim>
|
||
<span class="keyword">struct</span> deduce_vec {
|
||
|
||
<span class="keyword">typedef</span> <span class="comment">/*unspecified*/</span> type;
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code><a href="#is_vec">is_vec</a><V>::value</code> is <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>is_vec<deduce_vec<V>::type>::value</code> must be <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>deduce_vec<V>::type</code> must be copyable;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>vec_traits<deduce_vec<V>::type>::dim==Dim</code>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This template is used by Boost QVM whenever it needs to deduce a copyable vector type of certain dimension from a single user-supplied function parameter of vector type. The returned type must have accessible copy constructor. Note that <code>V</code> may be non-copyable.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main template definition returns an unspecified copyable vector type of size <code>Dim</code>, except if <code><a href="#vec_traits">vec_traits</a><V>::dim==Dim</code>, in which case it returns <code>V</code>, which is suitable only if <code>V</code> is a copyable type. Boost QVM also defines (partial) specializations for the non-copyable vector types it produces. Users can define other (partial) specializations for their own types.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>A typical use of the <code>deduce_vec</code> template is for specifying the preferred vector type to be returned by the generic function template overloads in Boost QVM depending on the type of their arguments.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="deduce_vec2"><code>deduce_vec2</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/deduce_vec.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>,<span class="predefined-type">int</span> Dim>
|
||
<span class="keyword">struct</span> deduce_vec2 {
|
||
<span class="keyword">typedef</span> <span class="comment">/*unspecified*/</span> type;
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>Both <code><a href="#scalar">scalar</a><A>::type</code> and <code>scalar<B>::type</code> are well defined;</p>
|
||
</li>
|
||
<li>
|
||
<p><code><a href="#is_vec">is_vec</a><A>::value || is_vec<B>::value</code> is <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>is_vec<deduce_vec2<A,B>::type>::value</code> must be <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>deduce_vec2<A,B>::type</code> must be copyable;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>vec_traits<deduce_vec2<A,B>::type>::dim==Dim</code>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This template is used by Boost QVM whenever it needs to deduce a vector type of certain dimension from the types of two user-supplied function parameters. The returned type must have accessible copy constructor (the <code>A</code> and <code>B</code> types themselves could be non-copyable, and either one of them may not be a vector type.)</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main template definition returns an unspecified vector type of the requested dimension with <a href="#vec_traits"><code>scalar_type</code></a> obtained by <code><a href="#deduce_scalar">deduce_scalar</a><A,B>::type</code>, except if <code>A</code> and <code>B</code> are the same vector type <code>V</code> of dimension <code>Dim</code>, in which case <code>V</code> is returned, which is only suitable for copyable types. Boost QVM also defines (partial) specializations for the non-copyable vector types it produces. Users can define other (partial) specializations for their own types.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>A typical use of the <code>deduce_vec2</code> template is for specifying the preferred vector type to be returned by the generic function template overloads in Boost QVM depending on the type of their arguments.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="is_mat"><code>is_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
<span class="keyword">struct</span> is_mat {
|
||
|
||
<span class="directive">static</span> <span class="predefined-type">bool</span> <span class="directive">const</span> value = <span class="predefined-constant">false</span>;
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This type template defines a compile-time boolean constant value which can be used to determine whether a type <code>T</code> is a matrix type. For matrix types, the <a href="#mat_traits"><code>mat_traits</code></a> template can be used to access their elements generically, or to obtain their dimensions and scalar type.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_traits"><code>mat_traits</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_traits.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">M</span>>
|
||
<span class="keyword">struct</span> mat_traits {
|
||
|
||
<span class="comment">/*main template members unspecified*/</span>
|
||
|
||
};
|
||
|
||
<span class="comment">/*
|
||
User-defined (possibly partial) specializations:
|
||
|
||
template <>
|
||
struct mat_traits<M> {
|
||
|
||
static int const rows = <<user-defined>>;
|
||
static int const cols = <<user-defined>>;
|
||
typedef <<user-defined>> scalar_type;
|
||
|
||
template <int R,int C>
|
||
static inline scalar_type read_element( Matrix const & m );
|
||
|
||
template <int R,int C>
|
||
static inline scalar_type & write_element( Matrix & m );
|
||
|
||
static inline scalar_typeread_element_idx( int r, int c, Matrix const & m );
|
||
static inline scalar_type & write_element_idx( int r, int c, Matrix & m );
|
||
|
||
};
|
||
*/</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The <code>mat_traits</code> template must be specialized for (user-defined) matrix types in order to enable vector and matrix operations defined in Boost QVM headers for objects of those types.</p>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The matrix operations defined by Boost QVM do not require matrix types to be copyable.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main <code>mat_traits</code> template members are not specified. Valid specializations are required to define the following members:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>rows</code>: the expression <code>mat_traits<Matrix>::rows</code> must evaluate to a compile-time integer constant greater than 0 that specifies the number of rows in a matrix.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>cols</code> must evaluate to a compile-time integer constant greater than 0 that specifies the number of columns in a matrix.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>scalar_type</code>: the expression <code>mat_traits<Matrix>::scalar_type</code> must be a value type which satisfies the scalar requirements.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In addition, valid specializations of the <code>mat_traits</code> template may define the following access functions as static members, where <code>m</code> is an object of type <code>Matrix</code>, <code>R</code> and <code>C</code> are compile-time integer constants, and <code>r</code> and <code>c</code> are variables of type <code>int</code>:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>read_element</code>: the expression <code>mat_traits<Matrix>::read_element<R,C>(m)</code> returns either a copy of or a const reference to the element at row <code>R</code> and column <code>C</code> of <code>m</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>write_element</code>: the expression <code>mat_traits<Matrix>::write_element<R,C>(m)</code> returns mutable reference to the element at row <code>R</code> and column <code>C</code> of <code>m</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>read_element_idx</code>: the expression <code>mat_traits<Matrix>::read_element_idx(r,c,m)</code> returns either a copy of or a const reference to the element at row <code>r</code> and column <code>c</code> of <code>m</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>write_element_idx</code>: the expression <code>mat_traits<Matrix>::write_element_idx(r,c,m)</code> returns mutable reference to the element at row <code>r</code> and column <code>c</code> of <code>m</code>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>It is illegal to call any of the above functions unless <code>is_mat<Matrix>::value</code> is true. Even then, matrix types are allowed to define only a subset of the access functions. The general requirements are:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>At least one of <code>read_element</code> or <code>write_element</code> must be defined;</p>
|
||
</li>
|
||
<li>
|
||
<p>If <code>read_element_idx</code> is defined, <code>read_element</code> must also be defined;</p>
|
||
</li>
|
||
<li>
|
||
<p>If <code>write_element_idx</code> is defined, <code>write_element</code> must also be defined.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Below is an example of a user-defined 3x3 matrix type, and its corresponding specialization of the <code>mat_traits</code> template:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#include</span> <span class="include"><boost/qvm/mat_traits.hpp></span>
|
||
|
||
<span class="keyword">struct</span> float33 { <span class="predefined-type">float</span> a[<span class="integer">3</span>][<span class="integer">3</span>]; };
|
||
|
||
<span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> mat_traits<float33> {
|
||
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> rows=<span class="integer">3</span>;
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> cols=<span class="integer">3</span>;
|
||
<span class="keyword">typedef</span> <span class="predefined-type">float</span> scalar_type;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> R,<span class="predefined-type">int</span> C>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element( float33 & m ) {
|
||
<span class="keyword">return</span> m.a[R][C];
|
||
}
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> R,<span class="predefined-type">int</span> C>
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type read_element( float33 <span class="directive">const</span> & m ) {
|
||
<span class="keyword">return</span> m.a[R][C];
|
||
}
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element_idx( <span class="predefined-type">int</span> r, <span class="predefined-type">int</span> c, float33 & m ) {
|
||
<span class="keyword">return</span> m.a[r][c];
|
||
}
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type read_element_idx( <span class="predefined-type">int</span> r, <span class="predefined-type">int</span> c, float33 <span class="directive">const</span> & m ) {
|
||
<span class="keyword">return</span> m.a[r][c];
|
||
}
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Equivalently, we could use the <<mat_traits_defaults,<code>mat_traits_defaults</code> template to shorten the above to:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <>
|
||
<span class="keyword">struct</span> mat_traits<float33>: mat_traits_defaults<float33,<span class="predefined-type">float</span>,<span class="integer">3</span>,<span class="integer">3</span>> {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> R,<span class="predefined-type">int</span> C> <span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element( float33 & m ) { <span class="keyword">return</span> m.a[R][C]; }
|
||
|
||
<span class="directive">static</span> <span class="directive">inline</span> scalar_type & write_element_idx( <span class="predefined-type">int</span> r, <span class="predefined-type">int</span> c, float33 & m ) {
|
||
<span class="keyword">return</span> m.a[r][c];
|
||
}
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_traits_defaults"><code>mat_traits_defaults</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_traits_defaults.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">MatType</span>,<span class="keyword">class</span> <span class="class">ScalarType</span>,<span class="predefined-type">int</span> Rows,<span class="predefined-type">int</span> Cols>
|
||
<span class="keyword">struct</span> mat_traits_defaults
|
||
{
|
||
<span class="keyword">typedef</span> MatType mat_type;
|
||
<span class="keyword">typedef</span> ScalarType scalar_type;
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> rows=Rows;
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> cols=Cols;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Row,<span class="predefined-type">int</span> Col>
|
||
<span class="directive">static</span> BOOST_QVM_INLINE_CRITICAL
|
||
scalar_type write_element( mat_type <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> mat_traits<mat_type>::<span class="keyword">template</span> write_element<Row,Col>(<span class="keyword">const_cast</span><mat_type &>(x));
|
||
}
|
||
|
||
<span class="directive">static</span> BOOST_QVM_INLINE_CRITICAL
|
||
scalar_type read_element_idx( <span class="predefined-type">int</span> r, <span class="predefined-type">int</span> c, mat_type <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> mat_traits<mat_type>::write_element_idx(r,c,<span class="keyword">const_cast</span><mat_type &>(x));
|
||
}
|
||
|
||
<span class="directive">protected</span>:
|
||
|
||
<span class="directive">static</span> BOOST_QVM_INLINE_TRIVIAL
|
||
scalar_type & write_element_idx( <span class="predefined-type">int</span> r, <span class="predefined-type">int</span> c, mat_type & m ) {
|
||
<span class="comment">/* unspecified */</span>
|
||
}
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The <code>mat_traits_defaults</code> template is designed to be used as a public base for user-defined specializations of the <a href="#mat_traits"><code>mat_traits</code></a> template, to easily define the required members. If it is used, the only member that must be defined by the user in a <code>mat_traits</code> specialization is <code>write_element</code>; the <code>mat_traits_defaults</code> base will define <code>read_element</code>, as well as <code>scalar_type</code>, <code>rows</code> and <code>cols</code> automatically.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Optionally, the user may also define <code>write_element_idx</code>, in which case the <code>mat_traits_defaults</code> base will provide a suitable <code>read_element_idx</code> definition automatically. Otherwise, <code>mat_traits_defaults</code> defines a protected implementation of <code>write_element_idx</code> which may be made publicly available by the deriving <code>mat_traits</code> specialization in case the matrix type for which it is being specialized can not be indexed efficiently. This <code>write_element_idx</code> function is less efficient (using meta-programming), implemented in terms of the required user-defined <code>write_element</code>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="deduce_mat"><code>deduce_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/deduce_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <
|
||
<span class="keyword">class</span> <span class="class">M</span>,
|
||
<span class="predefined-type">int</span> Rows=mat_traits<Matrix>::rows,
|
||
<span class="predefined-type">int</span> Cols=mat_traits<Matrix>::cols>
|
||
<span class="keyword">struct</span> deduce_mat {
|
||
|
||
<span class="keyword">typedef</span> <span class="comment">/*unspecified*/</span> type;
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code><a href="#is_mat">is_mat</a><M>::value</code> is <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>is_mat<deduce_mat<M>::type>::value</code> must be <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>deduce_mat<M>::type</code> must be copyable;</p>
|
||
</li>
|
||
<li>
|
||
<p><code><a href="#mat_traits">mat_traits</a><deduce_mat<M>::type>::rows==Rows</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>mat_traits<deduce_mat<M>::type>::cols==Cols</code>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This template is used by Boost QVM whenever it needs to deduce a copyable matrix type of certain dimensions from a single user-supplied function parameter of matrix type. The returned type must have accessible copy constructor. Note that M itself may be non-copyable.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main template definition returns an unspecified copyable matrix type of size <code>Rows</code> x <code>Cols</code>, except if <code><a href="#mat_traits">mat_traits</a><M>::rows==Rows && mat_traits<M>::cols==Cols</code>, in which case it returns <code>M</code>, which is suitable only if <code>M</code> is a copyable type. Boost QVM also defines (partial) specializations for the non-copyable matrix types it produces. Users can define other (partial) specializations for their own types.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>A typical use of the deduce_mat template is for specifying the preferred matrix type to be returned by the generic function template overloads in Boost QVM depending on the type of their arguments.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="deduce_mat2"><code>deduce_mat2</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/deduce_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>,<span class="predefined-type">int</span> Rows,<span class="predefined-type">int</span> Cols>
|
||
<span class="keyword">struct</span> deduce_mat2 {
|
||
|
||
<span class="keyword">typedef</span> <span class="comment">/*unspecified*/</span> type;
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>Both <code><a href="#scalar">scalar</a><A>::type</code> and <code>scalar<B>::type</code> are well defined;</p>
|
||
</li>
|
||
<li>
|
||
<p><code><a href="#is_mat">is_mat</a><A>::value || is_mat<B>::value</code> is <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>is_mat<deduce_mat2<A,B>::type>::value</code> must be <code>true</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>deduce_mat2<A,B>::type</code> must be copyable;</p>
|
||
</li>
|
||
<li>
|
||
<p><code><a href="#mat_traits">mat_traits</a><deduce_mat2<A,B>::type>::rows==Rows</code>;</p>
|
||
</li>
|
||
<li>
|
||
<p><code>mat_traits<deduce_mat2<A,B>::type>::cols==Cols</code>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This template is used by Boost QVM whenever it needs to deduce a matrix type of certain dimensions from the types of two user-supplied function parameters. The returned type must have accessible copy constructor (the <code>A</code> and <code>B</code> types themselves could be non-copyable, and either one of them may be a non-matrix type.)</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The main template definition returns an unspecified matrix type of the requested dimensions with <a href="#mat_traits"><code>scalar_type</code></a> obtained by <code><a href="#deduce_scalar">deduce_scalar</a><A,B>::type</code>, except if <code>A</code> and <code>B</code> are the same matrix type <code>M</code> of dimensions <code>Rows</code> x <code>Cols</code>, in which case <code>M</code> is returned, which is only suitable for copyable types. Boost QVM also defines (partial) specializations for the non-copyable matrix types it produces. Users can define other (partial) specializations for their own types.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>A typical use of the <code>deduce_mat2</code> template is for specifying the preferred matrix type to be returned by the generic function template overloads in Boost QVM depending on the type of their arguments.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_built_in_quaternion_vector_and_matrix_types">Built-in quaternion, vector and matrix types</h3>
|
||
<div class="paragraph">
|
||
<p>Boost QVM defines several class templates (together with appropriate specializations of <a href="#quat_traits"><code>quat_traits</code></a>, <a href="#vec_traits"><code>vec_traits</code></a> and <a href="#mat_traits"><code>mat_traits</code></a> templates) which can be used as generic quaternion, vector and matrix types. Using these types directly wouldn’t be typical though, the main design goal of Boost QVM is to allow users to plug in their own quaternion, vector and matrix types.</p>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat"><code>quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
<span class="keyword">struct</span> quat {
|
||
|
||
T a[<span class="integer">4</span>];
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">R</span>>
|
||
<span class="directive">operator</span> R() <span class="directive">const</span> {
|
||
R r;
|
||
assign(r,*<span class="local-variable">this</span>);
|
||
<span class="keyword">return</span> r;
|
||
}
|
||
|
||
};
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Quaternion</span>>
|
||
<span class="keyword">struct</span> quat_traits;
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
<span class="keyword">struct</span> quat_traits< quat<T> > {
|
||
|
||
<span class="keyword">typedef</span> T scalar_type;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> scalar_type read_element( quat<T> <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> x.a[I];
|
||
}
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> scalar_type & write_element( quat<T> & x ) {
|
||
<span class="keyword">return</span> x.a[I];
|
||
}
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This is a simple quaternion type. It converts to any other quaternion type.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The partial specialization of the <a href="#quat_traits"><code>quat_traits</code></a> template makes the <code>quat</code> template compatible with the generic operations defined by Boost QVM.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec"><code>vec</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>,<span class="predefined-type">int</span> Dim>
|
||
<span class="keyword">struct</span> vec {
|
||
|
||
T a[Dim];
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">R</span>>
|
||
<span class="directive">operator</span> R() <span class="directive">const</span> {
|
||
R r;
|
||
assign(r,*<span class="local-variable">this</span>);
|
||
<span class="keyword">return</span> r;
|
||
}
|
||
|
||
};
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Vector</span>>
|
||
<span class="keyword">struct</span> vec_traits;
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>,<span class="predefined-type">int</span> Dim>
|
||
<span class="keyword">struct</span> vec_traits< vec<T,Dim> > {
|
||
|
||
<span class="keyword">typedef</span> T scalar_type;
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> dim=Dim;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> scalar_type read_element( vec<T,Dim> <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> x.a[I];
|
||
}
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I>
|
||
<span class="directive">static</span> scalar_type & write_element( vec<T,Dim> & x ) {
|
||
<span class="keyword">return</span> x.a[I];
|
||
}
|
||
|
||
<span class="directive">static</span> scalar_type read_element_idx( <span class="predefined-type">int</span> i, vec<T,Dim> <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> x.a[i];
|
||
}
|
||
|
||
<span class="directive">static</span> scalar_type & write_element_idx( <span class="predefined-type">int</span> i, vec<T,Dim> & x ) {
|
||
<span class="keyword">return</span> x.a[i];
|
||
}
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This is a simple vector type. It converts to any other vector type of compatible size.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The partial specialization of the <a href="#vec_traits"><code>vec_traits</code></a> template makes the <code>vec</code> template compatible with the generic operations defined by Boost QVM.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat"><code>mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>,<span class="predefined-type">int</span> Rows,<span class="predefined-type">int</span> Cols>
|
||
<span class="keyword">struct</span> mat {
|
||
|
||
T a[Rows][Cols];
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">R</span>>
|
||
<span class="directive">operator</span> R() <span class="directive">const</span> {
|
||
R r;
|
||
assign(r,*<span class="local-variable">this</span>);
|
||
<span class="keyword">return</span> r;
|
||
}
|
||
|
||
};
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Matrix</span>>
|
||
<span class="keyword">struct</span> mat_traits;
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>,<span class="predefined-type">int</span> Rows,<span class="predefined-type">int</span> Cols>
|
||
<span class="keyword">struct</span> mat_traits< mat<T,Rows,Cols> > {
|
||
|
||
<span class="keyword">typedef</span> T scalar_type;
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> rows=Rows;
|
||
<span class="directive">static</span> <span class="predefined-type">int</span> <span class="directive">const</span> cols=Cols;
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Row,<span class="predefined-type">int</span> Col>
|
||
<span class="directive">static</span> scalar_type read_element( mat<T,Rows,Cols> <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> x.a[Row][Col];
|
||
}
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Row,<span class="predefined-type">int</span> Col>
|
||
<span class="directive">static</span> scalar_type & write_element( mat<T,Rows,Cols> & x ) {
|
||
<span class="keyword">return</span> x.a[Row][Col];
|
||
}
|
||
|
||
<span class="directive">static</span> scalar_type read_element_idx( <span class="predefined-type">int</span> row, <span class="predefined-type">int</span> col, mat<T,Rows,Cols> <span class="directive">const</span> & x ) {
|
||
<span class="keyword">return</span> x.a[row][col];
|
||
}
|
||
|
||
<span class="directive">static</span> scalar_type & write_element_idx( <span class="predefined-type">int</span> row, <span class="predefined-type">int</span> col, mat<T,Rows,Cols> & x ) {
|
||
<span class="keyword">return</span> x.a[row][col];
|
||
}
|
||
|
||
};
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This is a simple matrix type. It converts to any other matrix type of compatible size.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The partial specialization of the <a href="#mat_traits"><code>mat_traits</code></a> template makes the <code>mat</code> template compatible with the generic operations defined by Boost QVM.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_element_access">Generic element access</h3>
|
||
<div class="sect3">
|
||
<h4 id="quat_access">Quaternions</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_access.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<Q>::value</span>
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Q</span>> -unspecified-<span class="keyword">return</span>-type- S( Q & q );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Q</span>> -unspecified-<span class="keyword">return</span>-type- V( Q & q );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Q</span>> -unspecified-<span class="keyword">return</span>-type- X( Q & q );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Q</span>> -unspecified-<span class="keyword">return</span>-type- Y( Q & q );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Q</span>> -unspecified-<span class="keyword">return</span>-type- Z( Q & q );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>An expression of the form <code>S(q)</code> can be used to access the scalar component of the quaternion <code>q</code>. For example,</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">S(q) *= <span class="integer">42</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>multiplies the scalar component of <code>q</code> by the scalar 42.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>An expression of the form <code>V(q)</code> can be used to access the vector component of the quaternion <code>q</code>. For example,</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">V(q) *= <span class="integer">42</span></code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>multiplies the vector component of <code>q</code> by the scalar 42.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The <code>X</code>, <code>Y</code> and <code>Z</code> elements of the vector component can also be accessed directly using <code>X(q)</code>, <code>Y(q)</code> and <code>Z(q)</code>.</p>
|
||
</div>
|
||
<div class="admonitionblock tip">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-tip" title="Tip"></i>
|
||
</td>
|
||
<td class="content">
|
||
The return types are lvalues.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_access">Vectors</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_access.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<V>::value</span>
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> I,<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="keyword">return</span>-type- A( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="keyword">return</span>-type- A0( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="keyword">return</span>-type- A1( V & v );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="keyword">return</span>-type- A9( V & v );
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="keyword">return</span>-type- X( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="keyword">return</span>-type- Y( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="keyword">return</span>-type- Z( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="keyword">return</span>-type- W( V & v );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>An expression of the form of <code>A<I>(v)</code> can be used to access the <code>I</code>-th element a vector object <code>v</code>. For example, the expression:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">A<<span class="integer">1</span>>(v) *= <span class="integer">42</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>can be used to multiply the element at index 1 (indexing in Boost QVM is always zero-based) of a vector <code>v</code> by 42.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>For convenience, there are also non-template overloads for <code>I</code> from 0 to 9; an alternative way to write the above expression is:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">A1(v) *= <span class="integer">42</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p><code>X</code>, <code>Y</code>, <code>Z</code> and <code>W</code> act the same as <code>A0</code>/<code>A1</code>/<code>A2</code>/<code>A3</code>; yet another alternative way to write the above expression is:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">Y(v) *= <span class="integer">42</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="admonitionblock tip">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-tip" title="Tip"></i>
|
||
</td>
|
||
<td class="content">
|
||
The return types are lvalues.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="swizzling">Vector element swizzling</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/swizzle.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//*** Accessing vector elements by swizzling ***</span>
|
||
|
||
<span class="comment">//2D view proxies, only enabled if:</span>
|
||
<span class="comment">// is_vec<V>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- XX( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- XY( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- XZ( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- XW( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- X0( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- X1( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- YX( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- YY( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- YZ( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- YW( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- Y0( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- Y1( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- ZX( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- ZY( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- ZZ( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- ZW( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- Z0( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- Z1( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- WX( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- WY( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- WZ( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- WW( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- W0( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">2</span>D-vector-type- W1( V & v );
|
||
...
|
||
<span class="comment">//2D view proxies, only enabled if:</span>
|
||
<span class="comment">// is_scalar<S>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">2</span>D-vector-type- X0( S & s );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">2</span>D-vector-type- X1( S & s );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">2</span>D-vector-type- XX( S & s );
|
||
...
|
||
-unspecified-<span class="integer">2</span>D-vector-type- _00();
|
||
-unspecified-<span class="integer">2</span>D-vector-type- _01();
|
||
-unspecified-<span class="integer">2</span>D-vector-type- _10();
|
||
-unspecified-<span class="integer">2</span>D-vector-type- _11();
|
||
|
||
<span class="comment">//3D view proxies, only enabled if:</span>
|
||
<span class="comment">// is_vec<V>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">3</span>D-vector-type- XXX( V & v );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">3</span>D-vector-type- XXW( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">3</span>D-vector-type- XX0( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">3</span>D-vector-type- XX1( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">3</span>D-vector-type- XYX( V & v );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">3</span>D-vector-type- XY1( V & v );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">3</span>D-vector-type- WW1( V & v );
|
||
...
|
||
<span class="comment">//3D view proxies, only enabled if:</span>
|
||
<span class="comment">// is_scalar<S>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">3</span>D-vector-type- X00( S & s );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">3</span>D-vector-type- X01( S & s );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">3</span>D-vector-type- XXX( S & s );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">3</span>D-vector-type- XX0( S & s );
|
||
...
|
||
-unspecified-<span class="integer">3</span>D-vector-type- _000();
|
||
-unspecified-<span class="integer">3</span>D-vector-type- _001();
|
||
-unspecified-<span class="integer">3</span>D-vector-type- _010();
|
||
...
|
||
-unspecified-<span class="integer">3</span>D-vector-type- _111();
|
||
|
||
<span class="comment">//4D view proxies, only enabled if:</span>
|
||
<span class="comment">// is_vec<V>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">4</span>D-vector-type- XXXX( V & v );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">4</span>D-vector-type- XXXW( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">4</span>D-vector-type- XXX0( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">4</span>D-vector-type- XXX1( V & v );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">4</span>D-vector-type- XXYX( V & v );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">4</span>D-vector-type- XXY1( V & v );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">V</span>> -unspecified-<span class="integer">4</span>D-vector-type- WWW1( V & v );
|
||
...
|
||
<span class="comment">//4D view proxies, only enabled if:</span>
|
||
<span class="comment">// is_scalar<S>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">4</span>D-vector-type- X000( S & s );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">4</span>D-vector-type- X001( S & s );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">4</span>D-vector-type- XXXX( S & s );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>> -unspecified-<span class="integer">4</span>D-vector-type- XX00( S & s );
|
||
...
|
||
-unspecified-<span class="integer">4</span>D-vector-type- _0000();
|
||
-unspecified-<span class="integer">4</span>D-vector-type- _0001();
|
||
-unspecified-<span class="integer">4</span>D-vector-type- _0010();
|
||
...
|
||
-unspecified-<span class="integer">4</span>D-vector-type- _1111();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Swizzling allows zero-overhead direct access to a (possibly rearranged) subset of the elements of 2D, 3D and 4D vectors. For example, if <code>v</code> is a 4D vector, the expression <code>YX(v) is a 2D view proxy whose `X</code> element refers to the <code>Y</code> element of <code>v</code>, and whose <code>Y</code> element refers to the <code>X</code> element of <code>v</code>. Like other view proxies <code>YX</code> is an lvalue, that is, if <code>v2</code> is a 2D vector, one could write:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">YX(v) = v2;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The above will leave the <code>Z</code> and <code>W</code> elements of <code>v</code> unchanged but assign the <code>Y</code> element of <code>v2</code> to the <code>X</code> element of <code>v</code> and the <code>X</code> element of <code>v2</code> to the <code>Y</code> element of <code>v</code>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>All permutations of <code>X</code>, <code>Y</code>, <code>Z</code>, <code>W</code>, <code>0</code>, <code>1</code> for 2D, 3D and 4D swizzling are available (if the first character of the swizzle identifier is <code>0</code> or <code>1</code>, it is preceded by a <code>_</code>, for example <code>_11XY</code>).</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>It is valid to use the same vector element more than once: the expression <code>ZZZ(v)</code> is a 3D vector whose <code>X</code>, <code>Y</code> and <code>Z</code> elements all refer to the <code>Z</code> element of <code>v</code>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Finally, scalars can be "swizzled" to access them as vectors: the expression <code>_0X01(42.0f)</code> is a 4D vector with <code>X</code>=0, <code>Y</code>=42.0, <code>Z</code>=0, <code>W</code>=1.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_access">Matrices</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_access.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<Q>::value</span>
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> R,<span class="predefined-type">int</span> C,<span class="keyword">class</span> <span class="class">M</span>> -unspecified-<span class="keyword">return</span>-type- A( M & m );
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">M</span>> -unspecified-<span class="keyword">return</span>-type- A00( M & m );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">M</span>> -unspecified-<span class="keyword">return</span>-type- A01( M & m );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">M</span>> -unspecified-<span class="keyword">return</span>-type- A09( M & m );
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">M</span>> -unspecified-<span class="keyword">return</span>-type- A10( M & m );
|
||
...
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">M</span>> -unspecified-<span class="keyword">return</span>-type- A99( M & m );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>An expression of the form <code>A<R,C>(m)</code> can be used to access the element at row <code>R</code> and column <code>C</code> of a matrix object <code>m</code>. For example, the expression:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">A<<span class="integer">4</span>,<span class="integer">2</span>>(m) *= <span class="integer">42</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>can be used to multiply the element at row 4 and column 2 of a matrix <code>m</code> by 42.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>For convenience, there are also non-template overloads for <code>R</code> from <code>0</code> to <code>9</code> and <code>C</code> from <code>0</code> to <code>9</code>; an alternative way to write the above expression is:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">A42(m) *= <span class="integer">42</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="admonitionblock tip">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-tip" title="Tip"></i>
|
||
</td>
|
||
<td class="content">
|
||
The return types are lvalues.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_quaternion_operations">Generic quaternion operations</h3>
|
||
<div class="sect3">
|
||
<h4 id="quat_assign"><code>assign</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & assign( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Copies all elements of the quaternion <code>b</code> to the quaternion <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_convert_to"><code>convert_to</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<R>::value && is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">R</span>,<span class="keyword">class</span> <span class="class">A</span>>
|
||
R convert_to( A <span class="directive">const</span> & a );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<R>::value && is_mat<A>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==3 && mat_traits<A>::cols==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">R</span>,<span class="keyword">class</span> <span class="class">A</span>>
|
||
R convert_to( A <span class="directive">const</span> & m );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<p><code>R</code> must be copyable.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>The first overload is equivalent to: <code>R r; assign(r,a); return r;</code></p>
|
||
</li>
|
||
<li>
|
||
<p>The second overload assumes that <code>m</code> is an orthonormal rotation matrix and converts it to a quaternion that performs the same rotation.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_minus_eq"><code>operator-=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>-=( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Subtracts the elements of <code>b</code> from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_minus_unary"><code>operator-</code> (unary)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_quat<A>::type
|
||
<span class="directive">operator</span>-( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A quaternion of the negated elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_minus"><code>operator-</code> (binary)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_quat2<A,B>::type
|
||
<span class="directive">operator</span>-( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A quaternion with elements equal to the elements of <code>b</code> subtracted from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat2"><code>deduce_quat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_plus_eq"><code>operator+=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>+=( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Adds the elements of <code>b</code> to the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_plus"><code>operator+</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value &&</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_quat2<A,B>::type
|
||
<span class="directive">operator</span>+( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A quaternion with elements equal to the elements of <code>a</code> added to the corresponding elements of <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat2"><code>deduce_quat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_div_eq_scalar"><code>operator/=</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>/=( A & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>This operation divides a quaternion by a scalar.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_div_scalar"><code>operator/</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_quat<A>::type
|
||
<span class="directive">operator</span>/( A <span class="directive">const</span> & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A quaternion that is the result of dividing the quaternion <code>a</code> by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_mul_eq_scalar"><code>operator*=</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>*=( A & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>This operation multiplies the quaternion <code>a</code> by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_mul_eq"><code>operator*=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>*=( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">A tmp(a);
|
||
a = tmp * b;
|
||
<span class="keyword">return</span> a;</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_mul_scalar"><code>operator*</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_quat<A>::type
|
||
<span class="directive">operator</span>*( A <span class="directive">const</span> & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A quaternion that is the result of multiplying the quaternion <code>a</code> by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_mul"><code>operator*</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_quat2<A,B>::type
|
||
<span class="directive">operator</span>*( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The result of multiplying the quaternions <code>a</code> and <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat2"><code>deduce_quat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_eq"><code>operator==</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="predefined-type">bool</span> <span class="directive">operator</span>==( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>true</code> if each element of <code>a</code> compares equal to its corresponding element of <code>b</code>, <code>false</code> otherwise.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_neq"><code>operator!=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="predefined-type">bool</span> <span class="directive">operator</span>!=( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>!(a == b)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_cmp"><code>cmp</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>,<span class="keyword">class</span> <span class="class">Cmp</span>>
|
||
<span class="predefined-type">bool</span> cmp( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b, Cmp pred );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>Similar to <a href="#quat_eq"><code>operator==</code></a>, except that it uses the binary predicate <code>pred</code> to compare the individual quaternion elements.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_mag_sqr"><code>mag_sqr</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> quat_traits<A>::scalar_type
|
||
mag_sqr( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The squared magnitude of the quaternion <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_mag"><code>mag</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> quat_traits<A>::scalar_type
|
||
mag( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The magnitude of the quaternion <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_normalized"><code>normalized</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_quat<A>::type
|
||
normalized( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typename</span> deduce_quat<A>::type tmp;
|
||
assign(tmp,a);
|
||
normalize(tmp);
|
||
<span class="keyword">return</span> tmp;</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_normalize"><code>normalize</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> normalize( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Normalizes <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Postcondition: </dt>
|
||
<dd>
|
||
<p><code>mag(a)==scalar_traits<typename quat_traits<A>::scalar_type>::value(1).</code></p>
|
||
</dd>
|
||
<dt class="hdlist1">Throws: </dt>
|
||
<dd>
|
||
<p>If the magnitude of <code>a</code> is zero, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_dot"><code>dot</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_scalar<A,B>::type
|
||
dot( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The dot product of the quaternions <code>a</code> and <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_scalar"><code>deduce_scalar</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="conjugate"><code>conjugate</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_quat<A>::type
|
||
conjugate( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>Computes the conjugate of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_inverse"><code>inverse</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_quat<A>::type
|
||
inverse( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>Computes the multiplicative inverse of <code>a</code>, or the conjugate-to-norm ratio.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Throws: </dt>
|
||
<dd>
|
||
<p>If the magnitude of <code>a</code> is zero, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock tip">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-tip" title="Tip"></i>
|
||
</td>
|
||
<td class="content">
|
||
If <code>a</code> is known to be unit length, <code>conjugate</code> is equivalent to <a href="#quat_inverse"><code>inverse</code></a>, yet it is faster to compute.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="slerp"><code>slerp</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value && is_quat<B>::value && is_scalar<C></span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>,<span class="keyword">class</span> <span class="class">C</span>>
|
||
<span class="keyword">typename</span> deduce_quat2<A,B> >::type
|
||
slerp( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b, C c );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Preconditions: </dt>
|
||
<dd>
|
||
<p><code>t>=0 && t<=1</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A quaternion that is the result of Spherical Linear Interpolation of the quaternions <code>a</code> and <code>b</code> and the interpolation parameter <code>c</code>. When <code>slerp</code> is applied to unit quaternions, the quaternion path maps to a path through 3D rotations in a standard way. The effect is a rotation with uniform angular velocity around a fixed rotation axis.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_quat2"><code>deduce_quat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="zero_quat"><code>zero_quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- zero_quat();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A read-only quaternion of unspecified type with <a href="#scalar_traits"><code>scalar_type</code></a> <code>T</code>, with all elements equal to <a href="#scalar_traits"><code>scalar_traits<T>::value(0)</code></a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_set_zero"><code>set_zero</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_zero( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(a,
|
||
zero_quat<<span class="keyword">typename</span> quat_traits<A>::scalar_type>());</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="identity_quat"><code>identity_quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">S</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- identity_quat();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>An identity quaternion with scalar type <code>S</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_set_identity"><code>set_identity</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_identity( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
identity_quat<<span class="keyword">typename</span> quat_traits<A>::scalar_type>());</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="rot_quat"><code>rot_quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && vec_traits<A>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- rot_quat( A <span class="directive">const</span> & axis, <span class="keyword">typename</span> vec_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A quaternion of unspecified type which performs a rotation around the <code>axis</code> at <code>angle</code> radians.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Throws: </dt>
|
||
<dd>
|
||
<p>In case the axis vector has zero magnitude, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <code>rot_quat</code> function is not a <a href="#view_proxy">view proxy</a>; it returns a temp object.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_set_rot"><code>set_rot</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value &&</span>
|
||
<span class="comment">// is_vec<B>::value && vec_traits<B>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_rot( A & a, B <span class="directive">const</span> & axis, <span class="keyword">typename</span> vec_traits<B>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
rot_quat(axis,angle));</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_rotate"><code>rotate</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_quat<A>::value &&</span>
|
||
<span class="comment">// is_vec<B>::value && vec_traits<B>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="directive">void</span> rotate( A & a, B <span class="directive">const</span> & axis, <span class="keyword">typename</span> quat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>a *= <a href="#rot_quat">rot_quat</a>(axis,angle)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="rotx_quat"><code>rotx_quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- rotx_quat( Angle <span class="directive">const</span> & angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A <a href="#view_proxy">view proxy</a> quaternion of unspecified type and scalar type <code>Angle</code>, which performs a rotation around the X axis at <code>angle</code> radians.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_set_rotx"><code>set_rotx</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_rotx( A & a, <span class="keyword">typename</span> quat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
rotx_quat(angle));</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_rotate_x"><code>rotate_x</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> rotate_x( A & a, <span class="keyword">typename</span> quat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>a *= <a href="#rotx_quat">rotx_quat</a>(angle)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="roty_quat"><code>roty_quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- roty_quat( Angle <span class="directive">const</span> & angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A <a href="#view_proxy">view proxy</a> quaternion of unspecified type and scalar type <code>Angle</code>, which performs a rotation around the Y axis at <code>angle</code> radians.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_set_roty"><code>set_roty</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_rotz( A & a, <span class="keyword">typename</span> quat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
roty_quat(angle));</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_rotate_y"><code>rotate_y</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> rotate_y( A & a, <span class="keyword">typename</span> quat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>a *= <a href="#roty_quat">roty_quat</a>(angle)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="rotz_quat"><code>rotz_quat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- rotz_quat( Angle <span class="directive">const</span> & angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A <a href="#view_proxy">view proxy</a> quaternion of unspecified type and scalar type <code>Angle</code>, which performs a rotation around the Z axis at <code>angle</code> radians.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_set_rotz"><code>set_rotz</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_rotz( A & a, <span class="keyword">typename</span> quat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
rotz_quat(angle));</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_rotate_z"><code>rotate_z</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> rotate_z( A & a, <span class="keyword">typename</span> quat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>a *= <a href="#rotz_quat">rotz_quat</a>(angle)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="quat_scalar_cast"><code>scalar_cast</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Scalar</span>,<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-return_type- scalar_cast( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A read-only <a href="#view_proxy">view proxy</a> of <code>a</code> that looks like a quaternion of the same dimensions as <code>a</code>, but with <a href="#quat_traits"><code>scalar_type</code></a> <code>Scalar</code> and elements constructed from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="qref"><code>qref</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_quat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- qref( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>An identity view proxy of <code>a</code>; that is, it simply accesses the elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock tip">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-tip" title="Tip"></i>
|
||
</td>
|
||
<td class="content">
|
||
<code>qref</code> allows calling Boost QVM operations when <code>a</code> is of built-in type, for example a plain old C array.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_vector_operations">Generic vector operations</h3>
|
||
<div class="sect3">
|
||
<h4 id="vec_assign"><code>assign</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & assign( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Copies all elements of the vector <code>b</code> to the vector <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_convert_to"><code>convert_to</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<R>::value && is_vec<A>::value &&</span>
|
||
<span class="comment">// vec_traits<R>::dim==vec_traits<A>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">R</span>,<span class="keyword">class</span> <span class="class">A</span>>
|
||
R convert_to( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<p><code>R</code> must be copyable.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>R r; assign(r,a); return r;</code></p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_minus_eq"><code>operator-=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>-=( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Subtracts the elements of <code>b</code> from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_minus_unary"><code>operator-</code> (unary)</h4>
|
||
<div class="paragraph">
|
||
<p>operator-(vec)</p>
|
||
</div>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_vec<A>::type
|
||
<span class="directive">operator</span>-( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A vector of the negated elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec"><code>deduce_vec</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_minus"><code>operator-</code> (binary)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_vec2<A,B,vec_traits<A>::dim>::type
|
||
<span class="directive">operator</span>-( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A vector of the same size as <code>a</code> and <code>b</code>, with elements the elements of <code>b</code> subtracted from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_plus_eq"><code>operator+=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>+=( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Adds the elements of <code>b</code> to the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_plus"><code>operator+</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_vec2<A,B,vec_traits<A>::dim>::type
|
||
<span class="directive">operator</span>+( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A vector of the same size as <code>a</code> and <code>b</code>, with elements the elements of <code>b</code> added to the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_div_eq_scalar"><code>operator/=</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>/=( A & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>This operation divides a vector by a scalar.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_div_scalar"><code>operator/</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_vec<A>::type
|
||
<span class="directive">operator</span>/( A <span class="directive">const</span> & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A vector that is the result of dividing the vector <code>a</code> by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec"><code>deduce_vec</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_mul_eq_scalar"><code>operator*=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>*=( A & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>This operation multiplies the vector <code>a</code> by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_mul_scalar"><code>operator*</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_vec<A>::type
|
||
<span class="directive">operator</span>*( A <span class="directive">const</span> & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A vector that is the result of multiplying the vector <code>a</code> by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec"><code>deduce_vec</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_eq"><code>operator==</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="predefined-type">bool</span> <span class="directive">operator</span>==( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>true</code> if each element of <code>a</code> compares equal to its corresponding element of <code>b</code>, <code>false</code> otherwise.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_neq"><code>operator!=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="predefined-type">bool</span> <span class="directive">operator</span>!=( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>!(a == b)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_cmp"><code>cmp</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre>.#include <boost/qvm/mat_operations.hpp>
|
||
|
||
namespace boost
|
||
{
|
||
namespace qvm
|
||
{
|
||
//Only enabled if:
|
||
// is_mat<A>::value && is_mat<B>::value &&
|
||
// mat_traits<A>::rows==mat_traits<B>::rows &&
|
||
// mat_traits<A>::cols==mat_traits<B>::cols
|
||
template <class A,class B,class Cmp>
|
||
bool cmp( A const & a, B const & b, Cmp pred );
|
||
|
||
} }</pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>Similar to <a href="#vec_eq"><code>operator==</code></a>, except that the individual elements of <code>a</code> and <code>b</code> are passed to the binary predicate <code>pred</code> for comparison.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_mag_sqr"><code>mag_sqr</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> vec_traits<A>::scalar_type
|
||
mag_sqr( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The squared magnitude of the vector <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_mag"><code>mag</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> vec_traits<A>::scalar_type
|
||
mag( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The magnitude of the vector <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_normalized"><code>normalized</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_vec<A>::type
|
||
normalized( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typename</span> deduce_vec<A>::type tmp;
|
||
assign(tmp,a);
|
||
normalize(tmp);
|
||
<span class="keyword">return</span> tmp;</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec"><code>deduce_vec</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_normalize"><code>normalize</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> normalize( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Normalizes <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Postcondition:</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p><code>mag(a)==<a href="#scalar_traits">scalar_traits</a><typename <a href="#vec_traits">vec_traits<A>::scalar_type</a>>::value(1)</code>.</p>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Throws: </dt>
|
||
<dd>
|
||
<p>If the magnitude of <code>a</code> is zero, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_dot"><code>dot</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_scalar<A,B>::type
|
||
dot( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The dot product of the vectors <code>a</code> and <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_scalar"><code>deduce_scalar</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_cross"><code>cross</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// vec_traits<A>::dim==3 && vec_traits<B>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_vec2<A,B,<span class="integer">3</span>>::type
|
||
cross( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The cross product of the vectors <code>a</code> and <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="zero_vec"><code>zero_vec</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>,<span class="predefined-type">int</span> S>
|
||
-unspecified-<span class="keyword">return</span>-type- zero_vec();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A read-only vector of unspecified type with <a href="#vec_traits"><code>scalar_type</code></a> <code>T</code> and size <code>S</code>, with all elements equal to <a href="#scalar_traits"><code>scalar_traits<T>::value(0)</code></a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_set_zero"><code>set_zero</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_zero( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(a,
|
||
zero_vec<
|
||
<span class="keyword">typename</span> vec_traits<A>::scalar_type,
|
||
vec_traits<A>::dim>());</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vec_scalar_cast"><code>scalar_cast</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Scalar</span>,<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-return_type- scalar_cast( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A read-only <a href="#view_proxy">view proxy</a> of <code>a</code> that looks like a vector of the same dimensions as <code>a</code>, but with <a href="#vec_traits"><code>scalar_type</code></a> <code>Scalar</code> and elements constructed from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="vref"><code>vref</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- vref( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>An identity <a href="#view_proxy">view proxy</a> of <code>a</code>; that is, it simply accesses the elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock tip">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-tip" title="Tip"></i>
|
||
</td>
|
||
<td class="content">
|
||
<code>vref</code> allows calling Boost QVM operations when <code>a</code> is of built-in type, for example a plain old C array.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_matrix_operations">Generic matrix operations</h3>
|
||
<div class="sect3">
|
||
<h4 id="mat_assign"><code>assign</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & assign( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Copies all elements of the matrix <code>b</code> to the matrix <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_convert_to"><code>convert_to</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<R>::value && is_mat<A>::value &&</span>
|
||
<span class="comment">// mat_traits<R>::rows==mat_traits<A>::rows &&</span>
|
||
<span class="comment">// mat_traits<R>::cols==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">R</span>,<span class="keyword">class</span> <span class="class">A</span>>
|
||
R convert_to( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Requirements: </dt>
|
||
<dd>
|
||
<p><code>R</code> must be copyable.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Effects:</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>As if: <code>R r; <a href="#mat_assign">assign</a>(r,a); return r;</code></p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_minus_eq_scalar"><code>operator-=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>-=( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Subtracts the elements of <code>b</code> from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_minus_unary"><code>operator-</code> (unary)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_mat<A>::type
|
||
<span class="directive">operator</span>-( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A matrix of the negated elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_mat"><code>deduce_mat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_minus"><code>operator-</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type
|
||
<span class="directive">operator</span>-( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A matrix of the same size as <code>a</code> and <code>b</code>, with elements the elements of <code>b</code> subtracted from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_mat2"><code>deduce_mat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_plus_eq_scalar"><code>operator+=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>+=( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Adds the elements of <code>b</code> to the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_plus"><code>operator+</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type
|
||
<span class="directive">operator</span>+( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A matrix of the same size as <code>a</code> and <code>b</code>, with elements the elements of <code>b</code> added to the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_mat2"><code>deduce_mat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_div_eq_scalar"><code>operator/=</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>/=( A & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>This operation divides a matrix by a scalar.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_div_scalar"><code>operator/</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_mat<A>::type
|
||
<span class="directive">operator</span>/( A <span class="directive">const</span> & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A matrix that is the result of dividing the matrix <code>a</code> by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_mat"><code>deduce_mat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_mul_eq"><code>operator*=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>*=( A & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">A tmp(a);
|
||
a = tmp * b;
|
||
<span class="keyword">return</span> a;</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_mul_eq_scalar"><code>operator*=</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
A & <span class="directive">operator</span>*=( A & a, B b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>This operation multiplies the matrix <code>a</code> matrix by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_mul"><code>operator*</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::rows</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<B>::cols>::type
|
||
<span class="directive">operator</span>*( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The result of <a href="https://en.wikipedia.org/wiki/Matrix_multiplication">multiplying</a> the matrices <code>a</code> and <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_mat2"><code>deduce_mat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_mul_scalar"><code>operator*</code> (scalar)</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value && is_scalar<B>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_mat<A>::type
|
||
<span class="directive">operator</span>*( A <span class="directive">const</span> & a, B b );
|
||
|
||
<span class="comment">//Only enabled if: is_scalar<B>::value && is_mat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">B</span>,<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_mat<A>::type
|
||
<span class="directive">operator</span>*( B b, A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A matrix that is the result of multiplying the matrix <code>a</code> by the scalar <code>b</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_mat"><code>deduce_mat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_eq"><code>operator==</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="predefined-type">bool</span> <span class="directive">operator</span>==( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>true</code> if each element of <code>a</code> compares equal to its corresponding element of <code>b</code>, <code>false</code> otherwise.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_neq"><code>operator!=</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="predefined-type">bool</span> <span class="directive">operator</span>!=( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p><code>!( a <a href="#mat_eq">==</a> b )</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_cmp"><code>cmp</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_mat<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<B>::rows &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<B>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>,<span class="keyword">class</span> <span class="class">Cmp</span>>
|
||
<span class="predefined-type">bool</span> cmp( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b, Cmp pred );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>Similar to <a href="#mat_eq"><code>operator==</code></a>, except that the individual elements of <code>a</code> and <code>b</code> are passed to the binary predicate <code>pred</code> for comparison.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_inverse"><code>inverse</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_scalar<B>::value</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_mat<A>::type
|
||
inverse( A <span class="directive">const</span> & a, B det );
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="keyword">typename</span> deduce_mat<A>::type
|
||
inverse( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Preconditions: </dt>
|
||
<dd>
|
||
<p><code>det!=<a href="#scalar_traits">scalar_traits</a><typename <a href="#mat_traits">mat_traits<A>::scalar_type</a>>::value(0)</code></p>
|
||
</dd>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>Both overloads compute the inverse of <code>a</code>. The first overload takes the pre-computed determinant of <code>a</code>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Throws: </dt>
|
||
<dd>
|
||
<p>The second overload computes the determinant automatically and throws <a href="#zero_determinant_error"><code>zero_determinant_error</code></a> if the computed determinant is zero.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_mat"><code>deduce_mat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="zero_mat"><code>zero_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>,<span class="predefined-type">int</span> D>
|
||
-unspecified-<span class="keyword">return</span>-type- zero_mat();
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>,<span class="predefined-type">int</span> R,<span class="predefined-type">int</span> C>
|
||
-unspecified-<span class="keyword">return</span>-type- zero_mat();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A read-only matrix of unspecified type with <a href="#mat_traits"><code>scalar_type</code></a> <code>T</code>, <code>R</code> rows and <code>C</code> columns (or <code>D</code> rows and <code>D</code> columns), with all elements equal to <a href="#scalar_traits"><code>scalar_traits<T>::value(0)</code></a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_set_zero"><code>set_zero</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_zero( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(a,
|
||
zero_mat<
|
||
<span class="keyword">typename</span> mat_traits<A>::scalar_type,
|
||
mat_traits<A>::rows,
|
||
mat_traits<A>::cols>());</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="identity_mat"><code>identity_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre>namespace boost { namespace qvm {
|
||
|
||
template <class S,int D>
|
||
-unspecified-return-type- identity_mat();
|
||
|
||
} }</pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>An identity matrix of size <code>D</code> x <code>D</code> and scalar type <code>S</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_set_identity"><code>set_identity</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==mat_traits<A>::rows</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_identity( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
identity_mat<
|
||
<span class="keyword">typename</span> mat_traits<A>::scalar_type,
|
||
mat_traits<A>::rows,
|
||
mat_traits<A>::cols>());</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="rot_mat"><code>rot_mat</code> / Euler angles</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_vec<A>::value && vec_traits<A>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat( A <span class="directive">const</span> & axis, Angle angle );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_xzy( Angle x1, Angle z2, Angle y3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_xyz( Angle x1, Angle y2, Angle z3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_yxz( Angle y1, Angle x2, Angle z3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_yzx( Angle y1, Angle z2, Angle x3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_zyx( Angle z1, Angle y2, Angle x3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_zxy( Angle z1, Angle x2, Angle y3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_xzx( Angle x1, Angle z2, Angle x3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_xyx( Angle x1, Angle y2, Angle x3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_yxy( Angle y1, Angle x2, Angle y3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_yzy( Angle y1, Angle z2, Angle y3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_zyz( Angle z1, Angle y2, Angle z3 );
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
rot_mat_zxz( Angle z1, Angle y2, Angle z3 );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A matrix of unspecified type, of <code>Dim</code> rows and <code>Dim</code> columns parameter, which performs a rotation around the <code>axis</code> at <code>angle</code> radians, or Tait–Bryan angles (x-y-z, y-z-x, z-x-y, x-z-y, z-y-x, y-x-z), or proper Euler angles (z-x-z, x-y-x, y-z-y, z-y-z, x-z-x, y-x-y). See <a href="https://en.wikipedia.org/wiki/Euler_angles">Euler angles</a>.</p>
|
||
</dd>
|
||
<dt class="hdlist1">Throws: </dt>
|
||
<dd>
|
||
<p>In case the axis vector has zero magnitude, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
These functions are not view proxies; they return a temp object.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_set_rot"><code>set_rot</code> / Euler angles</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols &&</span>
|
||
<span class="comment">// is_vec<B>::value && vec_traits<B>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_rot( A & a, B <span class="directive">const</span> & axis, <span class="keyword">typename</span> vec_traits<B>::scalar_type angle );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_xzy( A & a, Angle x1, Angle z2, Angle y3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_xyz( A & a, Angle x1, Angle y2, Angle z3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_yxz( A & a, Angle y1, Angle x2, Angle z3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_yzx( A & a, Angle y1, Angle z2, Angle x3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_zyx( A & a, Angle z1, Angle y2, Angle x3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_zxy( A & a, Angle z1, Angle x2, Angle y3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_xzx( A & a, Angle x1, Angle z2, Angle x3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_xyx( A & a, Angle x1, Angle y2, Angle x3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_yxy( A & a, Angle y1, Angle x2, Angle y3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_yzy( A & a, Angle y1, Angle z2, Angle y3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_zyz( A & a, Angle z1, Angle y2, Angle z3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_zxz( A & a, Angle z1, Angle x2, Angle z3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> set_rot_xzy( A & a, Angle x1, Angle z2, Angle y3 );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Assigns the return value of the corresponding <a href="#rot_mat"><code>rot_mat</code></a> function to <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_rotate"><code>rotate</code> / Euler angles</h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols &&</span>
|
||
<span class="comment">// is_vec<B>::value && vec_traits<B>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="directive">void</span> rotate( A & a, B <span class="directive">const</span> & axis, <span class="keyword">typename</span> mat_traits<A>::scalar_type angle );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_xzy( A & a, Angle x1, Angle z2, Angle y3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_xyz( A & a, Angle x1, Angle y2, Angle z3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_yxz( A & a, Angle y1, Angle x2, Angle z3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_yzx( A & a, Angle y1, Angle z2, Angle x3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_zyx( A & a, Angle z1, Angle y2, Angle x3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_zxy( A & a, Angle z1, Angle x2, Angle y3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_xzx( A & a, Angle x1, Angle z2, Angle x3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_xyx( A & a, Angle x1, Angle y2, Angle x3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_yxy( A & a, Angle y1, Angle x2, Angle y3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_yzy( A & a, Angle y1, Angle z2, Angle y3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_zyz( A & a, Angle z1, Angle y2, Angle z3 );
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
<span class="directive">void</span> rotate_zxz( A & a, Angle z1, Angle x2, Angle z3 );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>Multiplies the matrix <code>a</code> in-place by the return value of the corresponding <a href="#rot_mat"><code>rot_mat</code></a> function.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="rotx_mat"><code>rotx_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- rotx_mat( Angle <span class="directive">const</span> & angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A <a href="#view_proxy">view proxy</a> matrix of unspecified type, of <code>Dim</code> rows and <code>Dim</code> columns and scalar type <code>Angle</code>, which performs a rotation around the <code>X</code> axis at <code>angle</code> radians.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_set_rotx"><code>set_rotx</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_rotx( A & a, <span class="keyword">typename</span> mat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
rotx_mat<mat_traits<A>::rows>(angle));</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_rotate_x"><code>rotate_x</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> rotate_x( A & a, <span class="keyword">typename</span> mat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>a <a href="#mat_mul_eq">*=</a> <a href="#rotx_mat">rotx_mat</a><<a href="#mat_traits">mat_traits<A>::rows</a>>(angle)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="roty_mat"><code>roty_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- roty_mat( Angle <span class="directive">const</span> & angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A <a href="#view_proxy">view proxy</a> matrix of unspecified type, of <code>Dim</code> rows and <code>Dim</code> columns and scalar type <code>Angle</code>, which performs a rotation around the <code>Y</code> axis at <code>angle</code> radians.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_set_roty"><code>set_roty</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_roty( A & a, <span class="keyword">typename</span> mat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
roty_mat<mat_traits<A>::rows>(angle));</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_rotate_y"><code>rotate_y</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> rotate_y( A & a, <span class="keyword">typename</span> mat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>a <a href="#mat_mul_eq">*=</a> <a href="#roty_mat">roty_mat</a><<a href="#mat_traits">mat_traits<A>::rows</a>>(angle)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="rotz_mat"><code>rotz_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> Dim,<span class="keyword">class</span> <span class="class">Angle</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- rotz_mat( Angle <span class="directive">const</span> & angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A <a href="#view_proxy">view proxy</a> matrix of unspecified type, of <code>Dim</code> rows and <code>Dim</code> columns and scalar type <code>Angle</code>, which performs a rotation around the <code>Z</code> axis at <code>angle</code> radians.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_set_rotz"><code>set_rotz</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> set_rotz( A & a, <span class="keyword">typename</span> mat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if:</p>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++">assign(
|
||
a,
|
||
rotz_mat<mat_traits<A>::rows>(angle));</code></pre>
|
||
</div>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_rotate_z"><code>rotate_z</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows>=3 &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
<span class="directive">void</span> rotate_z( A & a, <span class="keyword">typename</span> mat_traits<A>::scalar_type angle );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>a <a href="#mat_mul_eq">*=</a> <a href="#rotz_mat">rotz_mat</a><<a href="#mat_traits">mat_traits<A>::rows</a>>(angle)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="determinant"><code>determinant</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && mat_traits<A>::rows==mat_traits<A>::cols</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
mat_traits<A>::scalar_type
|
||
determinant( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This function computes the <a href="https://en.wikipedia.org/wiki/Determinant">determinant</a> of the square matrix <code>a</code>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="perspective_lh"><code>perspective_lh</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
perspective_lh( T fov_y, T aspect, T zn, T zf );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A 4x4 projection matrix of unspecified type of the following form:</p>
|
||
<table class="tableblock frame-all grid-all" style="width: 50%;">
|
||
<colgroup>
|
||
<col style="width: 25%;">
|
||
<col style="width: 25%;">
|
||
<col style="width: 25%;">
|
||
<col style="width: 25%;">
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td class="tableblock halign-center valign-top"><div class="verse"><code>xs</code></div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse"><code>ys</code></div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse"><code>zf</code>/(<code>zf</code>-<code>zn</code>)</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">-<code>zn</code>*<code>zf</code>/(<code>zf</code>-<code>zn</code>)</div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">1</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="paragraph">
|
||
<p>where <code>ys</code> = cot(<code>fov_y</code>/2) and <code>xs</code> = <code>ys</code>/<code>aspect</code>.</p>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="perspective_rh"><code>perspective_rh</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">T</span>>
|
||
-unspecified-<span class="keyword">return</span>-type-
|
||
perspective_rh( T fov_y, T aspect, T zn, T zf );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A 4x4 projection matrix of unspecified type of the following form:</p>
|
||
<table class="tableblock frame-all grid-all" style="width: 50%;">
|
||
<colgroup>
|
||
<col style="width: 25%;">
|
||
<col style="width: 25%;">
|
||
<col style="width: 25%;">
|
||
<col style="width: 25%;">
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td class="tableblock halign-center valign-top"><div class="verse"><code>xs</code></div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse"><code>ys</code></div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse"><code>zf</code>/(<code>zn</code>-<code>zf</code>)</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse"><code>zn</code>*<code>zf</code>/(<code>zn</code>-<code>zf</code>)</div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">-1</div></td>
|
||
<td class="tableblock halign-center valign-top"><div class="verse">0</div></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="paragraph">
|
||
<p>where <code>ys</code> = cot(<code>fov_y</code>/2), and <code>xs</code> = <code>ys</code>/<code>aspect</code>.</p>
|
||
</div>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mat_scalar_cast"><code>scalar_cast</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">Scalar</span>,<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-return_type- scalar_cast( A <span class="directive">const</span> & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>A read-only <a href="#view_proxy">view proxy</a> of <code>a</code> that looks like a matrix of the same dimensions as <code>a</code>, but with <a href="#mat_traits"><code>scalar_type</code></a> <code>Scalar</code> and elements constructed from the corresponding elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="mref"><code>mref</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- mref( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>An identity view proxy of <code>a</code>; that is, it simply accesses the elements of <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock tip">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-tip" title="Tip"></i>
|
||
</td>
|
||
<td class="content">
|
||
<code>mref</code> allows calling Boost QVM operations when <code>a</code> is of built-in type, for example a plain old C array.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_quaternion_vector_operations">Generic quaternion-vector operations</h3>
|
||
<div class="sect3">
|
||
<h4 id="quat_vec_mul"><code>operator*</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/quat_vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_vec2<A,B,mat_traits<A>::rows>::type
|
||
<span class="directive">operator</span>*( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The result of transforming the vector <code>b</code> by the quaternion <code>a</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_matrix_vector_operations">Generic matrix-vector operations</h3>
|
||
<div class="sect3">
|
||
<h4 id="mat_vec_mul"><code>operator*</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::cols==vec_traits<B>::dim</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
<span class="keyword">typename</span> deduce_vec2<A,B,mat_traits<A>::rows>::type
|
||
<span class="directive">operator</span>*( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Returns: </dt>
|
||
<dd>
|
||
<p>The result of multiplying the matrix <code>a</code> and the vector <code>b</code>, where <code>b</code> is interpreted as a matrix-column. The resulting matrix-row is returned as a vector type.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="transform_vector"><code>transform_vector</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==4 && mat_traits<A>::cols==4 &&</span>
|
||
<span class="comment">// vec_traits<B>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
deduce_vec2<A,B,<span class="integer">3</span>> >::type
|
||
transform_vector( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>return a <a href="#mat_vec_mul">*</a> <a href="#swizzling">XYZ0</a>(b)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="transform_point"><code>transform_pointt</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/mat_vec_operations.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value && is_vec<B>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==4 && mat_traits<A>::cols==4 &&</span>
|
||
<span class="comment">// vec_traits<B>::dim==3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>,<span class="keyword">class</span> <span class="class">B</span>>
|
||
deduce_vec2<A,B,<span class="integer">3</span>> >::type
|
||
transform_point( A <span class="directive">const</span> & a, B <span class="directive">const</span> & b );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dlist">
|
||
<dl>
|
||
<dt class="hdlist1">Effects: </dt>
|
||
<dd>
|
||
<p>As if: <code>return a <a href="#mat_vec_mul">*</a> <a href="#swizzling">XYZ1</a>(b)</code>.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_matrix_to_matrix_view_proxies">Generic matrix-to-matrix view proxies</h3>
|
||
<div class="sect3">
|
||
<h4 id="del_row"><code>del_row</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> R>
|
||
-unspecified-<span class="keyword">return</span>-type- del_row();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>del_row<R>(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with row <code>R</code> deleted.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="del_col"><code>del_col</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> C>
|
||
-unspecified-<span class="keyword">return</span>-type- del_col();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>del_col<C>(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with column <code>C</code> deleted.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="del_row_col"><code>del_row_col</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> R,<span class="predefined-type">int</span> C>
|
||
-unspecified-<span class="keyword">return</span>-type- del_row_col();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>del_row_col<R,C>(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with row <code>R</code> and column <code>C</code> deleted.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="neg_row"><code>neg_row</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> R>
|
||
-unspecified-<span class="keyword">return</span>-type- neg_row();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>neg_row<R>(m)</code> returns a read-only <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with row <code>R</code> negated.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="neg_col"><code>neg_col</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> C>
|
||
-unspecified-<span class="keyword">return</span>-type- neg_col();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="literalblock">
|
||
<div class="content">
|
||
<pre>The expression `neg_col<C>(m)` returns a read-only <<view_proxy,`view proxy`>> that looks like the matrix `m` with column `C` negated.</pre>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="swap_rows"><code>swap_rows</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> R1,<span class="predefined-type">int</span> R2>
|
||
-unspecified-<span class="keyword">return</span>-type- swap_rows();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>swap_rows<R1,R2>(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with rows <code>R1</code> and <code>R2</code> swapped.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="swap_cols"><code>swap_cols</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> C1,<span class="predefined-type">int</span> C2>
|
||
-unspecified-<span class="keyword">return</span>-type- swap_cols();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>swap_cols<C1,C2>(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with columns <code>C1</code> and <code>C2</code> swapped.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="transposed"><code>transposed</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
-unspecified-<span class="keyword">return</span>-type- transposed();
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>transposed(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that transposes the matrix <code>m</code>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_vector_to_matrix_view_proxies">Generic vector-to-matrix view proxies</h3>
|
||
<div class="sect3">
|
||
<h4 id="col_mat"><code>col_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_vec_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <iclass A>
|
||
-unspecified-<span class="keyword">return</span>-type- col_mat( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>col_mat(v)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the vector <code>v</code> as a matrix-column.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="row_mat"><code>row_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_vec_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <iclass A>
|
||
-unspecified-<span class="keyword">return</span>-type- row_mat( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>row_mat(v)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the vector <code>v</code> as a matrix-row.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="translation_mat"><code>translation_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_vec_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <iclass A>
|
||
-unspecified-<span class="keyword">return</span>-type- translation_mat( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>translation_mat(v)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the vector <code>v</code> as translation matrix of size 1 + <a href="#vec_traits"><code>vec_traits<A>::dim</code></a>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="diag_mat"><code>diag_mat</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_vec_mat.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_vec<A>::value</span>
|
||
<span class="keyword">template</span> <iclass A>
|
||
-unspecified-<span class="keyword">return</span>-type- diag_mat( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>diag_mat(v)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the vector <code>v</code> as a square matrix of the same dimensions in which the elements of <code>v</code> appear as the main diagonal and all other elements are zero.</p>
|
||
</div>
|
||
<div class="admonitionblock tip">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-tip" title="Tip"></i>
|
||
</td>
|
||
<td class="content">
|
||
If <code>v</code> is a 3D vector, the expression <code>diag_mat(XYZ1(v))</code> can be used as a scaling 4D matrix.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_generic_matrix_to_vector_view_proxies">Generic matrix-to-vector view proxies</h3>
|
||
<div class="sect3">
|
||
<h4 id="col"><code>col</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_vec.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> C,<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- col( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>col<C>(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses column <code>C</code> of the matrix <code>m</code> as a vector.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="row"><code>row</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_vec.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="predefined-type">int</span> C,<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- row( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>row<R>(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses row <code>R</code> of the matrix <code>m</code> as a vector.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="diag"><code>diag</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_vec.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if: is_mat<A>::value</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- diag( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>diag(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the main diagonal of the matrix <code>m</code> as a vector.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="translation"><code>translation</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/map_mat_vec.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="comment">//Only enabled if:</span>
|
||
<span class="comment">// is_mat<A>::value &&</span>
|
||
<span class="comment">// mat_traits<A>::rows==mat_traits<A>::cols && mat_traits<A>::rows>=3</span>
|
||
<span class="keyword">template</span> <<span class="keyword">class</span> <span class="class">A</span>>
|
||
-unspecified-<span class="keyword">return</span>-type- translation( A & a );
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The expression <code>translation(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the translation component of the square matrix <code>m</code>, which is a vector of size <code>D</code>-1, where <code>D</code> is the size of <code>m</code>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_exceptions">Exceptions</h3>
|
||
<div class="sect3">
|
||
<h4 id="error"><code>error</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/error.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">struct</span> error: <span class="directive">virtual</span> boost::exception, <span class="directive">virtual</span> std::exception { };
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This is the base for all exceptions thorwn by Boost QVM.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="zero_magnitude_error"><code>zero_magnitude_error</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/error.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">struct</span> zero_magnitude_error: <span class="directive">virtual</span> error { };
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This exception indicates that an operation requires a vector or a quaternion with non-zero magnitude, but the computed magnitude is zero.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="zero_determinant_error"><code>zero_determinant_error</code></h4>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/error.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="keyword">struct</span> zero_determinant_error: <span class="directive">virtual</span> error { };
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This exception indicates that an operation requires a matrix with non-zero determinant, but the computed determinant is zero.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_macros_and_configuration_boost_qvm">Macros and configuration: BOOST_QVM_</h3>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_INLINE"><code>INLINE</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_inline_code"><code>BOOST_QVM_INLINE</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/inline.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_INLINE
|
||
<span class="preprocessor">#define</span> BOOST_QVM_INLINE <span class="directive">inline</span>
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This macro is not used directly by Boost QVM, except as the default value of other macros from <code><boost/qvm/inline.hpp></code>. A user-defined <code>BOOST_QVM_INLINE</code> should expand to a value that is valid substitution of the <code>inline</code> keyword in function definitions.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_FORCE_INLINE"><code>FORCE_INLINE</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_force_inline_code"><code>BOOST_QVM_FORCE_INLINE</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/inline.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_FORCE_INLINE
|
||
<span class="preprocessor">#define</span> BOOST_QVM_FORCE_INLINE <span class="comment">/*platform-specific*/</span>
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This macro is not used directly by Boost QVM, except as the default value of other macros from <code><boost/qvm/inline.hpp></code>. A user-defined <code>BOOST_QVM_FORCE_INLINE</code> should expand to a value that is valid substitution of the <code>inline</code> keyword in function definitions, to indicate that the compiler must inline the function. Of course, actual inlining may or may not occur.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_INLINE_TRIVIAL"><code>INLINE_TRIVIAL</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_inline_trivial_code"><code>BOOST_QVM_INLINE_TRIVIAL</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/inline.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_INLINE_TRIVIAL
|
||
<span class="preprocessor">#define</span> BOOST_QVM_INLINE_TRIVIAL BOOST_QVM_FORCE_INLINE
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Boost QVM uses <code>BOOST_QVM_INLINE_TRIVIAL</code> in definitions of functions that are not critical for the overall performance of the library but are extremely simple (such as one-liners) and therefore should always be inlined.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_INLINE_CRITICAL"><code>INLINE_CRITICAL</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_inline_critical_code"><code>BOOST_QVM_INLINE_CRITICAL</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/inline.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_INLINE_CRITICAL
|
||
<span class="preprocessor">#define</span> BOOST_QVM_INLINE_CRITICAL BOOST_QVM_FORCE_INLINE
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Boost QVM uses <code>BOOST_QVM_INLINE_CRITICAL</code> in definitions of functions that are critical for the overall performance of the library, such as functions that access individual vector and matrix elements.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_INLINE_OPERATIONS"><code>INLINE_OPERATIONS</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_inline_operations_code"><code>BOOST_QVM_INLINE_OPERATIONS</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/inline.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_INLINE_OPERATIONS
|
||
<span class="preprocessor">#define</span> BOOST_QVM_INLINE_OPERATIONS BOOST_QVM_INLINE
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Boost QVM uses <code>BOOST_QVM_INLINE_OPERATIONS</code> in definitions of functions that implement various high-level operations, such as matrix multiplication, computing the magnitude of a vector, etc.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_INLINE_RECURSION"><code>INLINE_RECURSION</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_inline_recursion_code"><code>BOOST_QVM_INLINE_RECURSION</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/inline.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_INLINE_RECURSION
|
||
<span class="preprocessor">#define</span> BOOST_QVM_INLINE_RECURSION BOOST_QVM_INLINE_OPERATIONS
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Boost QVM uses <code>BOOST_QVM_INLINE_RECURSION</code> in definitions of recursive functions that are not critical for the overall performance of the library (definitions of all critical functions, including critical recursive functions, use <a href="#BOOST_QVM_INLINE_CRITICAL"><code>BOOST_QVM_INLINE_CRITICAL</code></a>).</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_ASSERT"><code>ASSERT</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_assert_code"><code>BOOST_QVM_ASSERT</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/assert.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_ASSERT
|
||
<span class="preprocessor">#include</span> <span class="include"><boost/assert.hpp></span>
|
||
<span class="preprocessor">#define</span> BOOST_QVM_ASSERT BOOST_ASSERT
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This is the macro Boost QVM uses to assert on precondition violations and logic errors. A user-defined <code>BOOST_QVM_ASSERT</code> should have the semantics of the standard <code>assert</code>.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_STATIC_ASSERT"><code>STATIC_ASSERT</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_static_assert_code"><code>BOOST_QVM_STATIC_ASSERT</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/static_assert.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_STATIC_ASSERT
|
||
<span class="preprocessor">#include</span> <span class="include"><boost/static_assert.hpp></span>
|
||
<span class="preprocessor">#define</span> BOOST_QVM_STATIC_ASSERT BOOST_STATIC_ASSERT
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>All static assertions in Boost QVM use the <code>BOOST_QVM_STATIC_ASSERT</code> macro.</p>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="BOOST_QVM_THROW_EXCEPTION"><code>THROW_EXCEPTION</code></h4>
|
||
<div class="sect4">
|
||
<h5 id="__code_boost_qvm_throw_exception_code"><code>BOOST_QVM_THROW_EXCEPTION</code></h5>
|
||
<div class="exampleblock">
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="title">#include <boost/qvm/throw_exception.hpp></div>
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> boost { <span class="keyword">namespace</span> qvm {
|
||
|
||
<span class="preprocessor">#ifndef</span> BOOST_QVM_THROW_EXCEPTION
|
||
<span class="preprocessor">#include</span> <span class="include"><boost/throw_exception.hpp></span>
|
||
<span class="preprocessor">#define</span> BOOST_QVM_THROW_EXCEPTION BOOST_THROW_EXCEPTION
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
} }</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This macro is used whenever Boost QVM throws an exception. Users who override the standard <code>BOOST_QVM_THROW_EXCEPTION</code> behavior must ensure that when invoked, the substituted implementation does not return control to the caller. Below is a list of all QVM functions that invoke <code>BOOST_QVM_THROW_EXCEPTION</code>:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>Quaternion operations:</p>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><a href="#quat_inverse"><code>inverse</code></a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="#rot_quat"><code>rot_quat</code></a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="#quat_normalize"><code>normalize</code></a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="#quat_normalized"><code>normalized</code></a></p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<p>Vector operations:</p>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><a href="#vec_normalize"><code>normalize</code></a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="#vec_normalized"><code>normalized</code></a></p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<p>Matrix operations:</p>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><a href="#mat_inverse"><code>inverse</code></a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="#rot_mat"><code>rot_mat</code></a></p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_design_rationale">Design rationale</h2>
|
||
<div class="sectionbody">
|
||
<div class="paragraph">
|
||
<p>In graphics and simulation applications, there is a need for a library that makes it easy to perform 2D and 3D transformations efficiently. C++ makes it possible to define vector and matrix types and to overload various operators to implement the standard algebraic operations. Because this is a relatively straightforward process, there are many such libraries in existence, each with its own types and operator overrloads. Such libraries are typically part of a higher level system, such as a graphics engine or a 3D modeling API. As a result, it is typical for programmers to have to integrate and to translate between several different quaternion, vector and matrix types that come with the various APIs they use.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>On the other hand, performance considerations often lead to matrix and vector types becoming coupled with a particular platform, or to (over time) acquire various <code>#ifdefs</code> needed to enable optimizations through platform-specific compiler features that control the physical format or layout of their elements. But such optimizations may interfere with ease of use and portability; for example on some platforms requiring 16-byte alignment for matrix types makes them incompatible with standard containers.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Boost QVM solves both of these issues by decoupling the standard algebraic functions from the types they operate on — without compromising type safety.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Key design features of Boost QVM:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>Emphasis on 2, 3 and 4-dimensional operations (including quaternions and zero-overhead <a href="#swizzling">swizzling</a>) as needed in graphics and simulation applications.</p>
|
||
</li>
|
||
<li>
|
||
<p>Zero-overhead <a href="#view_proxy">view proxies</a> that can be used to access any object with quaternion, vector or matrix semantics through a read-only or lvalue reference of a different type. For example, <code><a href="#col">col</a><C>(m)</code> binds the <code>C</code>-th column of a matrix <code>m</code> as a mutable vector type without the overhead of a temporary.</p>
|
||
</li>
|
||
<li>
|
||
<p>Integration of various user-defined or 3rd-party quaternion, vector or matrix types into a coherent type-safe system. This enables the user to build algebraic expressions using objects of diverse types that would otherwise be incompatible.</p>
|
||
</li>
|
||
<li>
|
||
<p>When users need to implement platform-specific or even project-specific optimizations in a given subsystem, Boost QVM makes it simple to define custom new types that automatically aquire the full set of algebraic operations so they can interface seamlessly with the rest of the program. At the same time, the user can define a limited number of overloads for the new types as needed to implement specific optimizations.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_code_generator">Code generator</h2>
|
||
<div class="sectionbody">
|
||
<div class="paragraph">
|
||
<p>While Boost QVM defines generic functions that operate on matrix and vector types of arbitrary static dimensions, it also provides a code generator that can be used to create compatible header files that define much simpler specializations of these functions for specific dimensions. This is useful during debugging since the generated code is much easier to read than the template metaprogramming-heavy generic implementations. It is also potentially friendlier to the optimizer.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The code generator is a command-line utility program. Its source code can be found in the <code>boost/libs/qvm/gen</code> directory. It was used to generate the following headers that ship with Boost QVM:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>2D, 3D and 4D matrix operations:</p>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>boost/qvm/gen/mat_operations2.hpp</code> (matrices of size 2x2, 2x1 and 1x2, included by <code>boost/qvm/mat_operations2.hpp</code>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>boost/qvm/gen/mat_operations3.hpp</code> (matrices of size 3x3, 3x1 and 1x3, included by <code>boost/qvm/mat_operations3.hpp</code>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>boost/qvm/gen/mat_operations4.hpp</code> (matrices of size 4x4, 4x1 and 1x4, included by <code>boost/qvm/mat_operations4.hpp</code>)</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<p>2D, 3D and 4D vector operations:</p>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>boost/qvm/gen/v2.hpp</code> (included by <code>boost/qvm/vec_operations2.hpp</code>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>boost/qvm/gen/v3.hpp</code> (included by <code>boost/qvm/vec_operations3.hpp</code>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>boost/qvm/gen/v4.hpp</code> (included by <code>boost/qvm/vec_operations4.hpp</code>)</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<p>2D, 3D and 4D vector-matrix operations:</p>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>boost/qvm/gen/vm2.hpp</code> (included by <code>boost/qvm/vec_mat_operations2.hpp</code>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>boost/qvm/gen/vm3.hpp</code> (included by <code>boost/qvm/vec_mat_operations3.hpp</code>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>boost/qvm/gen/vm4.hpp</code> (included by <code>boost/qvm/vec_mat_operations4.hpp</code>)</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<p>2D, 3D and 4D vector swizzling operations:</p>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>boost/qvm/gen/sw2.hpp</code> (included by <code>boost/qvm/swizzle2.hpp</code>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>boost/qvm/gen/sw3.hpp</code> (included by <code>boost/qvm/swizzle3.hpp</code>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>boost/qvm/gen/sw4.hpp</code> (included by <code>boost/qvm/swizzle4.hpp</code>)</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Any such generated headers must be included before the corresponding generic header file is included. For example, if one creates a header <code>boost/qvm/gen/m5.hpp</code>, it must be included before <code>boost/qvm/mat_operations.hpp</code> in included. However, the generic headers (<code>boost/qvm/mat_operations.hpp</code>, <code>boost/qvm/vec_operations.hpp</code>, <code>boost/qvm/vec_mat_operations.hpp</code> and <code>boost/qvm/swizzle.hpp</code>) already include the generated headers from the list above, so the generated headers don’t need to be included manually.</p>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
headers under <code>boost/qvm/gen</code> are not part of the public interface of Boost QVM. For example, <code>boost/qvm/gen/mat_operations2.hpp</code> should not be included directly; <code>#include <boost/qvm/mat_operations2.hpp></code> instead.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_known_quirks_and_issues">Known quirks and issues</h2>
|
||
<div class="sectionbody">
|
||
<div class="sect2">
|
||
<h3 id="_capturing_view_proxies_with_code_auto_code">Capturing view proxies with <code>auto</code></h3>
|
||
<div class="paragraph">
|
||
<p>By design, <a href="#view_proxy">view proxies</a> must not return temporary objects. They return reference to an argument they take by (<code>const</code>) reference, cast to reference of unspecified type that is not copyable. Because of this, the return value of a view proxy can not be captured by value with <code>auto</code>:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">auto</span> tr = transposed(m); <span class="comment">//Error: the return type of transposed can not be copied.</span></code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The correct use of auto with view proxies is:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">auto</span> & tr = transposed(m);</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="admonitionblock note">
|
||
<table>
|
||
<tr>
|
||
<td class="icon">
|
||
<i class="fa icon-note" title="Note"></i>
|
||
</td>
|
||
<td class="content">
|
||
Many view proxies are not read-only, that is, they’re lvalues; changes made on the view proxy operate on the original object. This is another reason why they can not be captured by value with <code>auto</code>.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_binding_qvm_overloads_from_an_unrelated_namespace">Binding QVM overloads from an unrelated namespace</h3>
|
||
<div class="paragraph">
|
||
<p>The operator overloads in namespace <code>boost::qvm</code> are designed to work with user-defined types. Typically it is sufficient to make these operators available in the namespace where the operator is used, by <code>using namespace boost::qvm</code>. A problem arises if the scope that uses the operator is not controlled by the user. For example:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> ns1 {
|
||
|
||
<span class="keyword">struct</span> float2 { <span class="predefined-type">float</span> x, y; };
|
||
|
||
}
|
||
|
||
<span class="keyword">namespace</span> ns2 {
|
||
|
||
<span class="directive">using</span> <span class="keyword">namespace</span> boost::qvm;
|
||
|
||
<span class="directive">void</span> f() {
|
||
ns1::float2 a, b;
|
||
a==b; <span class="comment">//OK</span>
|
||
ns1::float2 arr1[<span class="integer">2</span>], arr2[<span class="integer">2</span>];
|
||
std::equal(arr1,arr1+<span class="integer">2</span>,arr2); <span class="comment">//Error: operator== is inaccessible from namespace std</span>
|
||
}
|
||
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In the <code>std::equal</code> expression above, even though <code>boost::qvm::operator==</code> is made visible in namespace <code>ns2</code> by <code>using namespace boost::qvm</code>, the call originates from namespace <code>std</code>. In this case the compiler can’t bind <code>boost::qvm::operator==</code> because only namespace <code>ns1</code> is visible through ADL, and it does not contain a suitable declaration. The solution is to declare <code>operator==</code> in namespace ns1, which can be done like this:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">namespace</span> ns1 {
|
||
|
||
<span class="directive">using</span> boost::qvm::<span class="directive">operator</span>==;
|
||
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="_link_errors_when_calling_math_functions_with_int_arguments">Link errors when calling math functions with int arguments</h3>
|
||
<div class="paragraph">
|
||
<p>Boost QVM does not call standard math functions (e.g. sin, cos, etc.) directly. Instead, it calls function templates declared in <code>boost/qvm/math.hpp</code> in namespace <code>boost::qvm</code>. This allows the user to specialize these templates for user-defined scalar types.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Boost QVM itself defines specializations of the math function templates only for <code>float</code> and <code>double</code>, but it does not provide generic definitions. This is done to protect the user from unintentionally writing code that binds standard math functions that take <code>double</code> when passing arguments of lesser types, which would be suboptimal.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Because of this, a call to e.g. <code><a href="#rot_mat">rot_mat</a>(axis,1)</code> will compile successfully but fail to link, since it calls e.g. <code>boost::qvm::sin<int></code>, which is undefined. Because rotations by integer number of radians are rarely needed, in QVM there is no protection against such errors. In such cases the solution is to use <code>rot_mat(axis,1.0f)</code> instead.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="_q_a">Q&A</h2>
|
||
<div class="sectionbody">
|
||
<div class="qlist qanda">
|
||
<ol>
|
||
<li>
|
||
<p><em>What is the motivation behind Boost QVM? Why not just use uBLAS/Eigen/CML/GLM/etc?</em></p>
|
||
<p>The primary domain of Boost QVM is realtime graphics and simulation applications, so it is not a complete linear algebra library. While (naturally) there is some overlap with such libraries, QVM puts the emphasis on 2, 3 and 4 dimensional zero-overhead operations (hence domain-specific features like Swizzling).</p>
|
||
</li>
|
||
<li>
|
||
<p><em>How does the <code>qvm::<a href="#vec">vec</a></code> (or <code>qvm::<a href="#mat">mat</a></code>, or <code>qvm::<a href="#quat">quat</a></code>) template compare to vector types from other libraries?</em></p>
|
||
<p>The <code>qvm::vec</code> template is not in any way central to the vector operations defined by QVM. The operations are designed to work with any user-defined vector type or with 3rd-party vector types (e.g. <code>D3DVECTOR</code>), while the <code>qvm::vec</code> template is simply a default return type for expressions that use arguments of different types that would be incompatible outside of QVM. For example, if the <a href="#deduce_mat2"><code>deduce_mat2</code></a> hasn’t been specialized, calling <a href="#cross"><code>cross</code></a> with a user-defined type <code>vec3</code> and a user-defined type <code>float3</code> returns a <code>qvm::vec</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p><em>Why doesn’t QVM use [] or () to access vector and matrix elements?</em></p>
|
||
<p>Because it’s designed to work with user-defined types, and the C++ standard requires these operators to be members. Of course if a user-defined type defines <code>operator[]</code> or <code>operator()</code> they are available for use with other QVM functions, but QVM defines its own mechanisms for <a href="#quat_access">accessing quaternion elements</a>, <a href="#vec_access">accessing vector elements</a> (as well as <a href="#swizzling">swizzling</a>), and <a href="#mat_access">accessing matrix elements</a>.</p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
<hr>
|
||
<div class="paragraph text-right">
|
||
<p>© 2008-2018 Emil Dotchevski and Reverge Studios, Inc.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="footer">
|
||
<div id="footer-text">
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html> |