From e202258bdb4dfae9d228a44daf9265ae3cb77ecb Mon Sep 17 00:00:00 2001 From: dlegland Date: Tue, 23 Jul 2024 13:32:13 +0200 Subject: [PATCH] manual: update 3D coordinate systems and angles --- .../images/geom3d/cylinder_angles.odg | Bin 0 -> 13385 bytes .../images/geom3d/cylinder_angles.png | Bin 0 -> 25208 bytes .../images/geom3d/cylindrical_coordinates.odg | Bin 0 -> 11730 bytes .../images/geom3d/cylindrical_coordinates.png | Bin 0 -> 11400 bytes .../images/geom3d/ellipse3d_angles.odg | Bin 0 -> 12841 bytes .../images/geom3d/ellipse3d_angles.png | Bin 0 -> 23406 bytes .../images/geom3d/spherical-angles.odg | Bin 11902 -> 12124 bytes .../images/geom3d/spherical-angles.png | Bin 12808 -> 13385 bytes docs/matGeom-manual/matGeom-manual.lyx | 3279 +++++++++-------- docs/matGeom-manual/matGeom.bib | 9 + 10 files changed, 1750 insertions(+), 1538 deletions(-) create mode 100644 docs/matGeom-manual/images/geom3d/cylinder_angles.odg create mode 100644 docs/matGeom-manual/images/geom3d/cylinder_angles.png create mode 100644 docs/matGeom-manual/images/geom3d/cylindrical_coordinates.odg create mode 100644 docs/matGeom-manual/images/geom3d/cylindrical_coordinates.png create mode 100644 docs/matGeom-manual/images/geom3d/ellipse3d_angles.odg create mode 100644 docs/matGeom-manual/images/geom3d/ellipse3d_angles.png diff --git a/docs/matGeom-manual/images/geom3d/cylinder_angles.odg b/docs/matGeom-manual/images/geom3d/cylinder_angles.odg new file mode 100644 index 0000000000000000000000000000000000000000..76a6c854487ac858339fb03c8f788f6aa7789582 GIT binary patch literal 13385 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 literal 0 HcmV?d00001 diff --git a/docs/matGeom-manual/images/geom3d/cylinder_angles.png b/docs/matGeom-manual/images/geom3d/cylinder_angles.png new file mode 100644 index 0000000000000000000000000000000000000000..d689da216407a2196c3bf4a6d589ab535d10c6f9 GIT binary patch literal 25208 zcmeGE^;?wR_db9EqKEqgoK1CEhP>^LPF6+LPG9+jskqs zQB-6A{DE#SrRj)-gw_4{gPg#CMS_H6NG~n^LB&mPKLgzhZ+h{*g7N1?(B8YiKyi?` zgMZf3;>0r5g}U%|tEWrF^0jBLR2YubK4#a87URbj`*~}(V~$yhmmo7BtDH0WBN z-y$ef|2``;BD%i^|KC5Cv9p-}+Pp=^`R}tsvHZWk;k>47zef<_=~4dog*`p;4nmo7 z)FloHJq8Iq6c`1Eu5$ewRe+Pl%+K}Ln&rw1$QzO@Utg#T$g{&i&p^M(t#phvCxAh#`JS)tN|RzCIrRBM5fINp=q85?`Zlh^qD zBXc=OF0*R{;S}SZ^xt?9Zsfr&glqUf?{EC<3MtjoXI&5f)P5<}j%d{2-dHovky9-# zD(W8?_=|>{`EO$T=g15@6wj1cir2PY{bBr8R9c$OVK#CyDts6dTAlLG`tDy>eq~l8 zh&Cq@38GKL_%iv|oj`aB!dIFc{NKCVEgK6}@N~tuSR~c2 z&S|`5&NQvL74b5l@Diy50SPY*pQu1NjQ!6p{rnP~pg#@M!dH8q7r!>e%KPg~``@l( z#M=2A3q|o*un;dmyz%s#Hu}W>jJITKjatZZN~dDE=cT?*3(JBQ2K>c zB})d;=Kq}=`F8roOPdx38CmVaTeYz_ja!TC(H~S+@k3zRlxukZrei@-8}E5XO~CB7 z|76ybaWSA!R0b=rUOEE(-(f68gu^NSaD~#pAI(zyMF3CzF6u1ee1WX zR9sCESoA2eb_3MCqHqMT1Y^GVol2hc;r}#cf@)nDjuTLbLV}e??Pf6sCQ6V2NjGyk)>^S2_pwUVSiU;KO42AHUB^@q+see8YkYc!AMt;VBzErMcV z#7v^KLwvUy6#EXj^l3N^awPCD7fQeNzlW_K9}Z`&#{M@kG2jI)QDc9`_=!D#9+3ZZ z@*5Mw(DBdTJ8M1-5Ij3_cbr}yL(B3Ao}NfKXW7^ab%X8T=qaok0oJgFN+X}j>HgPv zRZmAp$Hj#k0!;^1Tmv!TbU4@*SO+5nX;It>KZsroYj9wIQPo>*h7k~_X&CA*pqH#v zq`)8HyAUDoYY~ufKOv3+0ujCvz5!xV^y zMe4_CsZHwWhyvISE@Fr~)-M?K(~C{7?|iQ27TaSBF!c`~Iug_yx$BMFj(@TleO>%s zg+Sz$Y|#_mWlu>sEKj3NaM>+27Z=kzU9$dd@VfeR<=jL08gfbyB)OtSD(usI+m{lH zDvqv10I52nKsT4rS5?*R$-n!kK26y-Ebyvsghz;;5iGO^FTG3-&01QF^)RMIb+%sS zPYEmkjR9_`v~fFrIokRY@%b}WeMDKJDE7PfoI~&Hegm;jxi|1+>_F1Q`1n$ds?J5u zp_c=8`M+{QC0Q-uwrfAWPzsVCPM4?~7-ZjK0IPTuRx3JH)=Ph1)jbWBDx>wNfUqj; zj_hpc7i_u>w5QT#F9p1>)8Yz7N|)SE_Zl1@w5oPjzN~A4$DdRvgh-r^;7Tv^hluF( z6Tvjtf5&do3Hf4siQCj zm1F%x{2G7o_@mZR*>9vd+9lZC-Sj13V`oFhvAxTO?Pd?yw^2R^2&^f}Iem}8kX22M z%D8pgM>aP$n(R;W$Y1u*?e)_mnn=;uI*11=>$8dbVz+dK;nLR6)Nub=vw+DdDD+M! zJ7H=I2VFt-Tmy*uX1=)vp;7@xPrY)4k4{Hf>9u}epjRRl8a>c2A2J2@oTGGBp}J1W z{%(K1*PtsIh1b@!`pQuaYb!zMHlH-2x_E?p<&`0Y{g0S;TQr7q%4a(IR&f*_=?HnT z3a9(qt0@SSx0wz&=yb>--=sv4{VnXu^r~Cy`|x!6oyM$PUTac2!yTOAe2yD?iStGb z4{F#8tJP4k@=J#g^`BEyD8c-puihUaiDNHzYu1<+%>@V3Kpe#(cf_gf`soo~FA2jA?3SU6=Y=c?(37}RhDL0Zj!pnF>3h@-FJd;`tc1E95#kh2#<6s_5EK!<5|Hn zpztEed2Xu9qeK?Kx;`4aWuVT}R9bAVO6DiI?#Eh2&^0my9vFFO8CuG8s!vM}_&ij2 zKHG>QoLa0sz$*3a5GDEXPJDb;CkxeTng$Zl#H?8@-qT1HHgJ@P3+OH5wMjjc0Oe!p z^2MpuAO}0nx}o-a!d~CX2`*}CAvU&+nlooRmY?Ty87)J6hrG@^DpD#?=$EZxsD-Uf zDu|k_PlpDc&n)wHjR^`Y5X#srg<|vC?c!u7<|Q*0oJN({ zHdU3-{Jf6qA4p(0z6`~t1es7Q=hA&)n#nOFCk;bwhM*vT2@x7@Ur@!L>$9YNlxGoM z7AiDSI%;^?hr5Ol$4Oa%iHbVO$#pLamwdg^oIc618Or^jm4ZK1p6>!){V)4Sk!^I_e)7tP!Q3h6;vKtX)ZEA{h9(OZ+I@){x zT@pzkN{I%;bl^ROMi8*c7a9?8=gLZ1ncP(-9CLZU#<^7ViWom0|M{+AqmQ?o)OEPe z=&R1;CXaC!PnaqVzzdYvi~Kq3m-p}tWwHYT^2O?J>0iisIo~?7EA}gy!8oh=7zf`0 z8^l8AOe^}@J|l>!czbqITB>3&IC+PLRY22MGCDFxyZT3@uPS@>vapC;@p9YQyF!ku z+UpA62QaX(jVz}tyqF&$-_j+37*rct(=zb9J@>NDy`<4a-j$`QNO;a^Ize;b6S~vR z+}!h1r-Gr6le;Clig&jjT`oxNM_{2&P!8%7UpY9=PekT`GY^iJ+aLiDKv>wD6;POy zLCcq}s3fjJ+MnJC1F8 zW)XMfgCDZP32E>IUFLk_5U7M8xHHe3mjVT*-4_unl&PK>Il%qte3oVtr0fsx8PCTZ zhvLsbIMKo#L_bgZJY2(X&^DHQ9ltJh94xmzG`pX`!^5?A5j23Du5;qx(c&me6v+QO zH(NR=wsD39R9||y=9FlJxF>d;So7zp1#CM0>T0`?k9#&c{QmJ}tCmUU`|B2-i~B<2 zR8SQhFLMTAbw*fqk4z<^i}BVA--aLMD-C3PAcOx*-aOPK>OIKjvpqIP{`Pi8;C64D z(7o6lcO^;T8gaF*k7 z*^0S5%Dlf@tMD0P5=)Zz8Z$}fvYLr`CsrwIsiZV^yxteoD4)iSc@s8RS`ag&jO_rq zPR1%^+2Df05fsVEfbDvrNwrVU=hD6SbGmIO`gxxM1A4ap{FP44V=*-5$3B5Cfy!o9*9Ko24X*d~>EeaYgh~qj0 zCk8;S@qS&}QE$iQbGJfGecQflp?2k84Rl7Lktpm`N#W5zLJ>-)0B~ewDURJ z1`AW-#4U30t&P^pGP zfUgn8`R&!oB^rOYO*vN&r3Pv^pVY6wU`#e3=@=&*VeAn{o#zCn7M3Fy!{0{YnlWX* zFRo~$cS`|{vviA+Tx{bjN!}9V6gh4T`SXiDprXgqy<~7j-47golJf1RrnuTx@<^s| zW+UB)gm3?Yg9sb+A8cS5PO@ES75y~)CRmnJ<`h2{yWAIpOOa?&k<-5$!iajt3GR$| zXPGE6dvp~}j!`H|P*Pkx*3~7+>nk?b`7EO|H<#)My+?{@7_S*&3GCM%ql`*407X)P zWGVI4;XK?=E)F4{CML@N^}Ta1dgJrw_II=77BKoqJzDSp8yLY78jb2Qs;wk`%JqjT zINs1zjSrj>jQSoB@Rbm6(Bp7Utn4^jXnE2kb445|Arc^j<3h#v&}Xq3?nMI1Vu}elq?~1ACY=jXud%rE@w-Uo^ZoUw!iW zvu^2%5JaUk{QzXWv}r#lxThH_^I z=_$nmZ1++&6b=V->1f4TCfhM79EIPsSasf(L4Y)=%&n^a6Z)1JEF$cMowcPxXn3qP zUQ@0WUo{)YRrHCPGaM6FVF|F%XU&V9=lsYO&lvRifO9q&6oF@(=9ftW*+%K?3P?*+ ze>yS8$KdR>U9Ap(_EpG5DM}hjoWJC{8XUhQrh52-)t3RF&a~JpOKU*L5AtwW zLzB)pbhYV%EMCEAz3Ib;H~iGJ5nk74ESrMsLMx(C(&KJ48m=4$ov7taY+swFWpkOe z1V5KPTs${7gvFZ@;}N+uUxBz~Ae++sdAf&W3su*X>b{-_r2}yw%&yN3id_SSA6zJa zd{~(?V=2)+Q*BsVE7B3wS(VW^3fxN>*_X~2-?$xqf#2q`{Wd(N@<;WnrI)4B(6u~Q zyFU6a!QZ5^xB$FlMbm63jpF;YZD-IXq{-Cxn+mMWw7U;N#`kH#zwx`*>d>EX8PrNB zdXe{m_jP*%=#KX$g@g3YadYI116Sxk1dtfovqf9^V28DoS@k`e_mMSEA}vUq96X2p zZOc`R;2hH6EgD1(oeB*b$KiROUPP#D%7eSJt%uxUGgX|*LB&Q=4ON&;DbFS44Ci9Jka8^s)bWK@)wlW|+C z$Q(^!{b81l;v~jfM=ugoqwx|T0knACuqr%;{qvV^&m3=ISg&5Okv$EDUF-=M->4SJ zhn$Onj=zaqrjp-Tw?An+LqxKm)zK=pH0$r@xSp~Ly=MG^%1JAtJ4FiS;QZVk{3gWb zVg8eK8%|-)>v6?SrQ#O#JVf+!sJJgQln#X5NJqRF|NC-uX0NT;abbAY7*6y22c)#A zBfAe7oEoGBxR&vWRY&tb!n!Rtd9Jgr2eEMXRwN23Y51b&N~NxPo*_53BRp9X)gU6( za1TUTh*MkTxl{XX#_5nW6UQ!*PyLe9?MJ-$kN-nXwlEY{aBG8;XVM<0t~~q`F*ylI zm5t>7_T(~Z@hE*k?9PN6fG1j?l~`BKNboawNlHuapFWu0Z`M7yS}FC3_7YeHO?@}x`vP{mLEc1Xt$Ma5F^~3+zxo|)jmH4F@$$%>&VQeJ3N-{1FD^@!d>y;5YOMo)$VB2rn^H|a)4?armsOE~=4vqMta``&HK z99BTcw>_LL(V0uvHh<|86Fak=GMhA-$;-KtQ*?E8b+PE0c{{*CjsE-*E#M9*y!E4j z@R?7**62$vG<6Ap(5AlN_G|c+&>wE_!0L)ZKu%g$4n^iepE|DOIrKDZBdqG@@LZJ< z*JvWq{8wNh=kMxWo;1o%1XLM~mL=w^ht6A@E!xE@W9HknuPW_yzf zw+@Bo<_NgWx5eu(Gg;kQ2m7)`&bVaI9})4S zD(|L2Ajj|iEC&cAu6Hn(*J&?4-RhYotR*pJc5X`@zntV@a+k9|CMCwt0FXv-w&{l# z&y)Ld>1rmnEzmtL-t2tMe8I`mpgh%Xo9EY*C<$waBvW&Ou2 zAt3?aL0GP~|BnU9r_|?;Ly(FPikDRgTV`uYu*6Y_voTZ4D#+sHZKtQa&pr)zy+6W* zC|V>CHuBocbC!KF5*m3YqU)qk$}|RZOa+;It{G#@Ns`7!5R$!NsY!vy8U$WR*&hiD zE&Z(_*Dc@rP=;d!|Dr2Vrq54HzJqWyv^h^qoyn!cO{d1s_ecTNcz`fS1R%W9P*aWs z8d+KS^t zZn%pC=zl3HmnSl%6IZk{_Ni6NCACk^!(o}7%M8PO8DNXh<7ek@FFici3(vEnN<)M0@t zcbc=yd1}q_T;oSB9fw{_*HrFzUC&)ddB?2~A7I&XF&HBwVrV3ZrHdR{N!e}$Amw-hF75tu6O6Tk`_B(g z?C+;q??U9OkqQovs%CGu%o?xRe#c15zEV1Upy*hI;2SxPe;7Nx_g)5 z(a|aDdL|Lf2O2=ip5;v|S(0nw zL;M4{j$d!?A+>e{IXu=l9+X3sg-(oNCFt>E#HJ$w}oJT=zitBsTiDs(dL9gq+m)vN%&t2LzaTbHQ z=fvT5q`#ed#Ef1Gae zMs`gyLK1mkwl-eR^F1IBWblsJexm?j+9LvyqzwVUWs#F}KaY%#Txe)2w^FOVEuezE zpy^33LEBhlm7++ouyd9P)x5mI(sjlTx5a1Clhftg7to)FLkZ+bh)dLlpfnK3ht4G) z?fQf1?t0|7HBT17s)E0}`z3?pA2`#9#IO=qR-!(1yirq~J{ysZjr(dL)y@har!FM{ z#9Opf5MB=#3oRyYyID5InI_u8LD_Im3@N9Sm3XWYmbu~3R!DBV;o5TWEM7dw1s ztb0^y6@KN>(9$}-R#kYL+#CLQ3QwKB91fi{FN-7LnBNy?BWky!&x` z{n49QsC()B_MNdwikrCP{8z}KPj0o*G>B5)p6w9)e`n%x#*fK?{GNJ^oXjYDLP`%&q;)6c9pjSimHm3*HDpwH`| zpb+myk7%+I*gLq-oBUN-!nTB-Rk7c-(H5nWK+@5YoRZzk3AV&}>ULRO1Ec@8kGF`{ z_Y6=$ydk1X-L^a-4hBh0O(hnN(kK1<`}Fe!0*)XUcp=+5DKdb7i)id(?;z^dOyKhq zxrGLVm9G?JVAiTuh0<0Ep4b9#>L`wQ*0 z2%wZ9mQ()ym^)*DOS=Be=g&vpvW~hDVPPF#i0|vz3XZnNA!4$Ng1xfUZilRg)W!FB zT?O)wd0DZ2aw9t@c!!vbm#1Fsu%g6HZU+=MQ5T{Q>vo5$E!?Pp=`d(~byX`)i?}B* zcBZX5K0mdgv7+>^yxxdqh2j6oGKv26SbT(DsEy?o3K%9a&m_+FEMrYQ&sDzuLV zct7QWT@Ah*+xbD&t%2X}&3-L^9IOD1F_`)%|`Mx=f6RE90`uM9ug`p|7&%^D4(;iMzX50p; z1;&dV4bMwA0L4B@W?)&HsGfQ;fcWI1=JolpB1i-^O9f$O?U}$zuRpOlVgE6_Nh>M; zAzFbQ?m$Wrxi3(=>|3a*z47E3MtiJ^{NLtU#)KA#ym_h+?hayG3>5leBG(+r*#fAa zL@u7Nr&C7m|N2&8_r8eFg;9E%W^|{F_O`*?8^YFQIp| z773(<;c8*=*k`%Yp&V&dDptNHAd z*SwB=Av1%I!RkgNuhomQ$NFI3(&|PromCDS;6Zvtm{Q-!!~I{R*V4VH!|{rY>76WS zm6lDw85gPReE1|#Yq#tqx_$+bW5&nFzlMG*v-2qlo7{{)DuoD3Y3)IG5IrdQlFk;e zseoejuK8TZJ10Y69hVMrP1TR= znHY>f8m@nZ*6IXkFceu1e%N{`wSSKJOFii&4a7M}6uau%<;H;E96p*%5i_o%kn=`b zO@>idZP_pXCusQ0I=ldnYExrkTMuNBwceq5#8Pnx(3{AEj@;+a_b}~%+c7JrG|;q3 zw8PX&Occqtz0cuKl%sdp*;bVcM$_e^qG#$20Th0+IaT8Q8sCfg$|5?s1_mt zkS9hc%U-8P4R*{-H6SigguhZI8 z;uI8Zi%0K?JJWdyKGjXc(RI9U+A!N(yM0AO^?XJnUa!13aJ=FWp5 zGuoyWMJ{I1qlLA+l^B)4yUR1J;n8@!_tVjAgKar%RR_qizm|>s!8_H+!Pb=y=$-ce*EStpKvyAZEdXCsK)4XT>T|*4O zTFd8?Q<}i(5^<|s0Npg6k=pYFD`L`(=%TtP;^mX98|JW2;zlrP#Z@bCW)i#Eq|#_w zB=-Xq0y4K1WIiGo=#Nsh67dcq=yP6cF%V+SXm6w$`Fkdm8AZx|R_^&1EK3ay#oZM? zLuXr@E0J^=K4`2XanV^~dh#&+Ryn8IoZrK%eVQmWDbedVhhKXS-LH>Lf-i>!uUORxg0##`Xt>@8G*o?Z^^oxb5^7a> zw(IQR;PsS#sAm7X-Cb&Crm*XQ&h)M3!B#cdpIg}YcMh#UTftJ-d;MBoU=oG{i#1X;%ex3L z8%ej}cQF)U*++vy9ZQ>1SPevh)NV&j1e=3{1LFJzQJ7kMMV`x?Dl9>7b=kW%{4#0U zsb8Vyr$j2f!`4+YfTDdZBORtLzyHW!;)uf3D28*D-2cv>tns{hGlqM=lA%Tz#vIjkd!tZuz)sBvi zwwuMng)1dc0!5vU#}49;=!`^=0gUux>J+O&4OB<#U@RIT_VV?trmkJ6pEdTeK*o}`-i2|oE|cs zsXk6W3RnXUSo17Ux@zlB-X=e)>yGgfm|ByG%>f~j0=g4N`Dpa1AX)I{Rhgc8#+O9G zqv_%%7jn0q&DlQ5-6m{g6?rV4k8ry8FPT92`GDoN*M0yj7xS}Q5qe!n8c=mPiTP1@ zX&!koS^bK#O?yp9+ClNpEGxJ-&-f}M&w)tahTa7xn1Rz~HQFI~gJtTh&^b=pi+2c} zSQ2!8wG``Wr0CspJD2>-F>u1OMw$W9G@y~JrK9uSs2AhF95;rbcSW=){MnP)lJ8}n z#9w{9-E~CM`I6MPrmc-m&fZI7qiELs&1voGBi4S3DHHIAyhK$o{k?KciEZCVV?-_L z>6=JW&Bcb@_N)@+!`ly0&mzAJp?KD>t}}$mK|o}ZiVnl6T95TF*haRy;BN^2T;<%*gTG)ne_&^>CX7IynDAlDeHbZ=JNq0;Dph5)lu+>+`8a16>q)1bbg*@PT4#sH`iz~Ff%qb z7uCsCK;t+3m}Vnj6{5H7-Z@$^TLJmXXS6u{*a7Gc$)F%s)=o4e13djnx2U|lKFrJR z>Y#L_NFpkrsHpHPv%kUgEf)U$=r3O)ZWnmRug|-fua*ld>1hSI$a=%XB%^G8LDQ07 zC&Uw$OmCAaiI-mRoecA|wdQOJK8gIrjUSMCF!{PD)T0gJGLYG5zG@C6VrbF(U!NQvcnph7UbEebf38s507M_Ez$ojsJL`<*FAuA$KeNiYbuI7buI`hP19of))twe-D}M1C?;|{>zD6 z!otd*svtpk#7$_~`Vrcszhqjf1MgbvyqMW&Mqg}sVdz-Q%G-!m2}p1q8A9Y5msT-T z(6v1K_;NgFcyqML9!YJpwmWXPFY~UVb&);d9Ls?Gdu%LDD20|J1Y;^X0&g&nS&PMz z6HNS?BN-&@z0Q}On>?Xf!BmE69+U~uCyE*i5EmM2-q=ugy;=jTP-@Fk7T7@w3 zK7orYzm9mtG@9pqp9BI@ZRHlo2je@tQlhgw{Fz@YGorQi9b5BVe4h{DR8@ckO1I(k+Z8)q{opA5sV zoHGE-ux0=xUTj-|FxKtwX0D4i-W=qlQ;U9|yuk=1&U61X4l}Ho9AYJ0d;?m*`d*61 z(LlOB8yf*H!Z0|RYuRky%3cIYNsz;}Ts-LEL`qu=5c-G7J_2HhifNIDUv~s*J3O>D z7WlekECER~Joz8{c$YeqzApple&rKjEdtre5 z{)-1Sf8*pZUu!X6AK$>|4{%A%PzgnB#E&@8S@>%?I6xt7TxaLta76w}muuTVr8j#b z2baNviuj)dvh{2&y%e1sadYl|m%jCd4^coPG7%Kz#_tAJYMx&#QTbV zxaD^XCVH3zd0$R#EVq;|z>8n;V617881B6evY>Ic2*Y=8w#*&d+y#PBY?FLj)ISdRh`bu2VtIv8N%b zVt~oQ={Rwt?i(C8i>=r*Kd}R8g(f2U!_<$X6_9GcP+(h#z@^Wy0n7IFxe>k~VQ5CE9 zW2+E##BM!#^EJH!vn4*(W8~j%lV+=gZz=w|Vg!ze{4tjP`0&%&rw0x>Hmv3_mA*+J zvvUVw@7e;4T>%!#zdeBwzTdZ1H0&jnReJOiR!~&(j!*k?&B-7jEzHc`m5zV}9DNS} z!KSXgY1dorn1Tq4euzVmAGLa_)Jcz9142TtOBM7y&y|kj^zV{O2Re$);Tp4Kwpcqq z?hykT-{s)|Yq}tCV7EtEyk0nxYpwus+FhH-lbs%4QC0vbKc`Qp`(rMEDDQO}KC$KF z?T@h<{mSahH8+KD;*-hNkN}cjq}VAue=H#><(#yb$eH>g zmo9pJldcl$%St2ng42TOF$-XE2vrbt#c$ZQH|kAEJo;oDpcv4hh`2_d9<|q)VlqB*9dLU{@Usj7 z*Ab9vl?rtw#u-or#Mt>!$1Sr?vz%)Vfq=|Qb(`wHe@|{KJYCcW;2LKkYcBBl8=?Ab`~7^Dr4l{e11*)$J2{7hNwEpBi4abJlEkM2oJ7B93lfWzGy7RcD^$` zs3(kR9eDugt&uWOQ{&_J5#5ogOD^>1T=Ngbi^zCk-?xwMo&VTK$DfhaugDnnZ7(^^_@_W^1+ zBq}5Ji*H#@WR|+U2EA+ntPuJTq#$E|vT2pjWJ&A=XBidmYN!;`kqXI#+1*X2- z(1gMmi6O3YQn%4F;rj{(+eYtWt5JQ-5p8AiUVMiiea1|a-}n(U5L!BfAJCHh5}$F5 zfX(q6<$q2o6^DE&+gsq4V%=XE@$L&HyfXl->$z~;&A`gO*2ZcfLbJNo?zfXfKGfOj zu;s*WELR5{T|PM7^^0Q)^dCT{SUmbbsBz0ltP2+>tuver!CI3DFy65ZEIPtY@m}w& z7eN*8l&wRbu&e_tcvKW6&099iZN-hUaG)cIB@V%XhYfI+a>+_+YNnk?RWhc)spf<_ zUF&_(IXhOvRsC^P{9O?i=yzxM_dTY73*kram2DoOWIi%JBNUtrDGlCJi{-DWKNVR% zHnyG{9)RyM_XJK0G&4@Y1Cr$c`C>+oKzeqQ^OfIu0F6qI200Uuq|i8_Z_Xhe*w@2R z)l9wm7?PGP4s^#GEwmCRJM#A+Exq-Awh@;_>=Pn?n{9#!kIiPG-S8 z+iF9S*m`s@(etEWq+y=UqO?R{0*vSaV9$5o<*y$VzeYUS9hWE-0W&f(($jYe*V?k5 zP$D-0mkLtp5OZfV)XdG>bNz)slyFrCV~Pn~V%L~n3E?HB2W?BZQB*;r>Lrz@hg#|2 z!rq7e+8n6Xv)=4$XTIeu55I()-k(hp-bo)UYWsTI-s#&=e5vwC|r0Fj9^n#T0nQzNjUikY1?I8*jBD#h^l zqZ0Xg()W@NRjWSQ`pyRD?J~^nH_VH%a9IQi;3k7y_vT1++HSuH%k@C$5hD53)i|4S z4&f>`AGv9NOXzZ{$JfN>eCDqgaF_@q>8!Ip^4?X%)CR*HBM#qO@GvR{`94XDHIkbi zRnIn^7GUDbb&k67kzlhB)Ga@&yK!mKNqVM!$M|E{!OfG~X5o4|EiQGpq$u>OJr*f1 zlEqXa_rL1}+lcq2c1fe$Qz3j6gP~G{G;mP>k*LN4@Gr#hj#-Q8ih4b>9Zf;2S$YsK_$cJpjY|29~{VOwmn0&U+;=^MrZAOpVnvHU->wVxblDN_Xo`bI$C*jZ@(2yW zs}f!CZ1nfDn_UGGVWO&REn~qbxXg=a74^f`cPz)QZ7bukHgCHTX+7Zt$^^gKyML7d zfLZ$;TSpKO9PM^es&>bqY5NH~7BJG&u?L`6=Lc$KTgm6Qk-nL3!ilT3hlGJ|kh)8f zCOIH`!IcLpdr_vd`moZU4G;eQ?ib6YlQb@=stH72{G1=b4{;NA01Jzkd(p5HHcih) zewQi(!SeZB_{Mw8@kOg{J%?53v0>ta&o`lI#nZen=@Gm$BhCXWBJnfd40<`Z{eiHH z*=Sk?n^S*@xe=2Co3OC&*jq>Mi)vIJwb(}U3D+!b32OzJ(`-t4bO$I+8KT%S8+T(< zlc*T3dK9C-)c&lv^7h*yVX1!f4A~RU?@K=`Ynx4t+e!~#=+u{);HH1QQol0M1CHn6 z!4qG%LOY-c@HEoFWdgX*g@xe1!BhGPAO{)yXYXBR{nFQ5dFJE@I)?S*5OApv#0GQi z^HVHK_b*2ry0MV{vSZiRyPI9nQdYNS7+T-vf&}s#ucOb+aCwtKuV&t)-fQ?;-@L7$ zk((Ap3b9}WYJEp59o-*L;D7?~R@pg^fm#kt(Ju*VOnGne~dO8F1vH5{4W`Phe+Bi)Sa zQo?|1Q96J_D_TZzB6@i5oA9Sz_OXdG&HqmZZ)fLJmbVJlO&EDmSqHn;DX~c!F-Nt; zNI&s5r6hHdL#&~P+|k3Wx^StY+F#O1Jqq9`c!dU_#si3#p4!yudU;{?mzFNju44F@ zMX7*-q`H2%<+{+;cXsIHaQE5%@C*oy17Ul+_ov7NBF*FgjnnGCpRs)LqXG^k6&dbA z?E+)YuiWQuspPj-ULves@UIkdk%UU}Lq9m$9l`0jZgvmloZxHn1E7FN*0CilQSb+# z{6)IUxCWn(ew6aX4b9Cur_BGCfXg|((d~6jRMGx1=ynpIsLSINUw&<1?^gK|`5BZg{)I)e*+Pls z=z@993@5lAIrN)!`@dxJM)!GR#N2%^y`IF6;0$qSC>h3m6Svx4(Jk>#C}sQ|R*~y7 zPOt~=@y)|K0%0GsE)3GgN@-+Fn#&EzC0pXq9qu)3b^LfnWLuKS!Txw}d9mtx-Pftb z!>|5kZajBOQo~DVzCe+@yy;jvgvSfW@UBgbss-XC&Ki6_Y3j)3x?}zHBR3kCRn$ke zygQ)hy>%ki$8U6NJw;&r?or5&B!DFLdO*Fnj&$~%2Cy?n|9Ot?DMuI!(V z{)D$K#C=)n$4Ce!6$QPEEX246AR3eG4Vy90$78yJ$FuZIa-+cReMk>4duFVZ1kle< zDr{G#+l0Ssix2eFmUgW}%6h#=F|Ggc+6r*Sn9gP13tvkxwr~5mtLg7X;?dbc zYyG96*m4*IM!Qqr^6x+OFAy~9aVRaC)62u*$sBCxgg`yroXQ4spc5tiUOlgD*_(=* zPa$A$%G5uITk_TZa%Em$AG$P@nT?#f!^gnz=`wSyLrE7yaPaw5G`Xw z=e$aag74#tr>UrchGrO7KRku^v6-)UH8|sVWVwx;hzOr_0XoagJDgkioMuDQikmTD z@&WE6+%Z#xGYZtR9xsBms{oqHe-ZL|U`4LAKj&J(XMJ#C0pn>jSZ)XCr}mQ4hu#absH)>B9+88yYNxUqo>zfWDO zrJ>_i{x;nXBJ1kpBRhOYWTQ`cIl=Uuh3;!l(6AVFzT5B3Ri$nYVf;rmI`1T> z`EcFUG}~ryE%QvT0xz+9W{Phx{r&rs5!bX;ps9*HO99Nlz_2-*si-@JUJ+RXu#H0B zHT$7Pz6qN%Gz33dW`FOW!Bx z#wI3bhs(?DD4Ox|fK}Vz{3!78xdSfP|X{s0-(8&dotX0#At=fyE7 zp`@<*z1qyQm@Msr|A`_g7S+md2(v;eCwOIA|0(06<7kKpQzyiY^dT36W3 zXz)+^hOhmk9af@!tL_Fb9?tGPHPBPi)8!cbsVjl%V0xQ|o*vnpWu?;~AVV!?V;ElR zRq9aPFRbz+zSwxGi&{*l*YDs5VmXyQfe5;wxxN-VdARUirSIP9_GE!V#()iF<<|PNHB?;SR(SbbO5tKH#GLE_rM8y{I#PyY*RHpGifoZ-eo4{}zzxr_9`}t;2DkaTBi8hKX6JG8 z5g(zKnZcQSM-FB{fS%_&;5nBov3t+wyM2Bdk;t@G*$TAf$Wa?&?z~ZK7L7wR&JFTO zV=G4_o8NBbL=%&cI1~poe!h&)ME!oyujm)$o!)4EGPZmbkS>T8?XBz0n|o&wy7pzB zn3FJsVjST0j@T7p-FC)O>q99VY~w$2qNcLXAHW#qj*F2Ggm03cIFH|dU}@gn>ASyp z(DN)m`dvjSY6bXV0%r&=z^-(C1V@DRK2*UgqM ztGMrqjc%T`j&In^G`a&SW|w^(3|l=eFc70*vx)1-^^dN1XXl{>Si*U}0p)zT4u0qC zAhcIxx7UMs6<#_ab@9;gRTta(e47&!SiEwmCtX4#9a>VoMONrXuj8luyYr@l3+cdp zBJ*E#IccF+Oxf0Q*OS>A z>bdAVD|ma(IwJV|MY}ZP4tCLKp!cB?)y`UuFt0L@4G&>iCb6;902sv zuaV9_#P8i$gR9vFL)ldMwo@dqk)2*toe~_@vvL9yl~Hd*hiCyJoE)Ob#)keKfcX38 z?D{L_z(wK9HAYU1wxq{KSc~7C%nrWprNVho{-aNF@Cm->t`2(dogB6&@_^rC@%?u} z2kQT)y)*xZ^84eyHDfFdjkSfLFm{nG#4vU-2$5yTlI&|C27_s=g|d}3BuSA_wy}pY z60&aap-jB!qKiogg<(f0+y3V<-^FHtQ>-9t}87)I|*CA!>@hh3eU!*eKfm%&Ov3-Gwt)ARZ3j8sI^`NEAA8}EY zk~;ofi7C1uM{2!2ad-nHfCjTGm;Z)l!DZU;PfAEzH~-Qferudu3AfwtXnLmXD)i>I zNcx_KMA`r!XtS?PK(8qBSas&WCZqIYY6KlroU?tnwv#X7RBOJ%xKA`cemtXNQwn#5 z7X&r>MQuNj?xt{K(c2tj@xesKJ8Qo#+*s_^(D)D{wkLGQR8D{W96^PP&3kj46DpE z!o(~RBu?DV2iEzdt%;#&BQE@^TBu#P#jvg5VCoUP+zaY*9YG9Bgzhlt96kjaHr_~+ zdEELOPYB*kutQfTkvAryRVOmt-pVInhD85NE^^~6wE|enHtde=g@7!O`EX_0_Uhjg zaRtM*-cv2r)mnj>RRWHfAj~?(9o0P%asAA@ivkalFF#V|*hhI#F-54>$6EbC zGsIAP!{htY!4}{0-Kc9t7r5kGRwwPl<{7-jC-*kLkG&1hd;L{Ery+C+S|3d6PFsQ@ z@8~ZGp}5l3+-lZSnnAhKO(g^mBw*1nN95DcESOm=99-l{8Ae0<}(;qQ*+A+ z28O^U0kQDepB#&edNVVKf6^prye*^!B|stZ~j07cd76Q2?z4kxC+AFTAe9@}zuIeT@KM4jqr)OWxY zu|X>?WvbKqz*ytCj3h8Px;?JE@R3}o1DdRfg-tAaq07oWM$+B{1gWjY^dX` znUx07=r&%@aD!?_PeQ0KORS9a4bc!61Ad#HS9;BtKxlioz4%uy{9y~{ugOcybJoDd zxOBBvcM`_2{>IL}+HZ5VPpQtfe83lONaSYG?zAkr5_>I*H~-X(w!IFBIn{7`*>EB=M%I+x1i;c-Gr!<`QdfCd6rsKp35vMOf{N z_#FUUCF=!m%xt~=IF`JB#-!s>cHfX7ft$(8Z6;=OlZ=r9&8QQKTbi#=*=#<}kPAhJg$3yAzoQN`!QfkfKbsdSjQ&v+f6G|4x)apA z3SK#`443^eS_Zx}@cI6U>)0LzRXVFEQSW=W%is;I9C;;IqH)pbGP$AH{+k|gsV6ne z)Q~M6@1-%7k+GHAw4WaHL(RHQkj3U%)(zFm>cHjBABoZYcoFZjv%aWU0z=h0_i)ZL z8`D?!KYvTA=f1nM9l^AZeqp%k%=)|Bv1Z`#y)*-RKQKUGY#twci^b@dABX$3tXu@~ z$BxbBR_;R+tzcB|h-&!93&G=Qw1S;Ao-BIZjKG97YN3htioAfVsgQ1*&1)L5*0nBK z52ROu#0?8lHwrV-GIFC~>&I8R_qV22eq4Q25qd#bP3-`@ML8}6E|^oh7|`s12WP3% z!uNxfKr*Asj7%V?xk;M-q*fv>{Jm!32OpX%FDu*qw09+rRo=n!GZ4%>@|^VT1F~i8 z*R%o+a|j}q#i1gO&haI)KvZie_6f`)#qqsKQZ~wRyp+}sV=kql@~*C~?&fd>9BmsZ z>n{iv{=_1QE1dOr7fwKss|F0=%q_-38wo>OX`%(Le@9NaF3V~@1P+(4hmA=D2&kLN z9#o0~`_Ri|UUiMnMXfQ6s4#wcE2o&ndH@NTZk}Wl)SgDVi4J0ReCJjQ-VllTW5l{u zsir-4spO9eHTCsBW7s}Eu=~3XutSoTfnPG%G!4Y8-LFZ9?0hojWbKw|+yr*N|56x( zr-AZgAERY_nKs0E`eT!5P};kuM%%cgHD7XU-^HO}g&d{ZB+B*QAy(c=5EkoYg`x;{ z{NI=mxhA~WFjK|K{!%UzXC<%U{ySR}acXNo14yxC-?t3(Z5l7&S{Ebj{V}Om9@28b-TK9z%kK#Q*U6WnN3<=O?42|)=RXTW zjkiaSnDqIDmesMub89@3#*zTot1aNAM=t<;P*nVg`k2q{g8ak^GN0sIk(gH7hb$5j zr^*bG{alGN75i8j*x(B6gSgJ^0@F_5CoDF0qL&izklvstt&mrZ+MNF<@GGbxsH8%@OW-v=HX79=HnbY6Kiu!eP#J|$lHWSD1Q$nI9Ug9 znL}DP(?J_HRUXGHAN-GVO~3E7|15sszO}S5Hs>Tj5nqoQASFx?kVTe`*i zRxaAAA<(Jk@a^~TY>|?&bVI_k@4)NOp5f(v_leEb$~<7OF6~N3gXy*)dhS*Vk3{8;hJNPuJi#v>h-u;|;H z)Sa)8Go>giq;xgmcroKd_%YSq4eQ2x2VY|zpt#6;D?bYQF9z6t`E_4>N4$u_e|q*@ zOD*>s%m3aUul$$@dNMfT0waBPIkYOdwl>h1cKmei^NF`E69=g!O?r9>?#aeF_kw@# z0a5M8$Ev=whHkpMKmMe8*Nc_}zbV3b(9UVF`#X?$iHNk|b-EDOy`nBj|&39%d-8yEzuNOolTzPF3w!1GW7=EM^^3$jay4I1FfT(v$KvrnTRJC zVkGY+erLMU-+}4qZwCd6&;>`Y;9hZq4`-k!lFn;eUl}AMr{MI#VwgUirse_~wI-Ir zi^CVO*^w|5>r9q<*K~2SkI3Fe6wHx6F&u59>WVc}?*HSa`=K(Fi6|->7R)Ur(d+xd z__Z?K&=iHGrrk!?O%>q4+|bI8;$~}q&z9Gk*|5EzmawC+(AuS+<1NaV(Fpq}B3aq;P^@kNjp36|Pgl)-%iGrLQ zM9jJEXwPZuP5u2KGsTtbdzTn9qQTPlLJ{a?ux_pI4~8!4?3&4QVA9Tb)SGi2G-qd;tM#9PTng=w+ol{1IwTL0Osi5o)H_ZpQmp^!rm^*_utt90Kws z-_v%OyHLJ-UepeJISD5MeH-=nYC z*;KPpDwQWll$ANyr5DiUC?G$cVBo3^w|BbC_DLd~bJ`HywjfdslYO<|UU(?+vsNhJ zt*5_AYOYkQ5+9fLb2h29C9LOC%!5Bde-YHOAO-J!;&kc55JqPo0FwZ9A6Stus4qF2wiO(|6#OB8AOL+P zD{VOX#@k+w2L%zM4}S^bJ?-dH>3DURTVWG7LG+~|yUEeMI5-5zes+|%`<6e}K`)zV zK@hzg)3Mzs>;XrF|L4-Jc;~*uIUTAKOFyNoWkbq0&Vi}eWJk|pM3lGCO1S4p>($HU zIC|szhez8DcdIg0gzb^U@P-(nP;PRYE>%=TH&HhALeghnO4PR_ebd>rI#*yeSRm;X zNht&_s`O_H9vI|1RfTaTI$Vo z2t16PfV@(!GWz-^mwXl*9(L2UKhwhS!SRtOs)v&!0trc8bb*+w+xrSgYfCm64Z`tb zot2dk$z2ehG`FdOgaQoT{`h2{NNDQMY~Hcs`M%deoTeaSP0oX8dYO*o`b$FS9;84q z0sPcAY$I$erQo87$GYe#t5V$QRDh~fB;tI6h&R{cxbzz@2JH->t8zLhUjFTmKt*w;< zdVSuUf6!nu=*PXWP{QPIIHA5&P`+9!kIb@XlQDzPZA--RXn3eX(QP3-;;Ah`H^+UA zhI(4G9O)Js*a~OMZ))nRow9{Ght+I%BP38(wtF5uErW%Z))&;XQXzpaf7O=CQraR5 zw#gxs2|(@ATr1+jLKd7K-KnvM6azkG3VQnfdCmrtSpTOn9}4Kr$zKa3YuM}na_5t% z0G*v;8O#FeaWm~`((*uf>~a(UeEnh8b+=T{TiU7OuP((~Pm^iR+W=Yytpgp?`f zxIM2|m>{88;UYa7Q0tsO5&v*j%N8Di1%wu(0s=QzJA<_dA=gJGHMEc?Lf(s`v+dd0>1e7r zzA&8cz`VQ9RI(>1ssA(9b- z82aGw<~eZTIB6i&tTg5(&K%^@C7k0wrEi!U`*P682B;Q1Ygp_vE>@dcMLLbX54Vw7 zn%zR31=`?BfdY$d+vszJB3!PUBr}3%Ej>b9N=jk>Vh2Af@LpM=sE{Yj6 zC_+Bwz*^?lab__gBdReiern^4`^EG4w-3$9J(VIOJVs4aarF!LrIAbdgnt>2@<)+X zXHGuHCct+q>Pi@A#OIS_FK<7`4$GTz{o=j)`?-UZPOJ-3PL^`XiPx_VxiT{;WrA4qOZ!^zaZiT zyi?SjivO9~#9+>z*b z&YAPYAKSft^DLPKk{0Y zOQN$tFY!JOLFdqnj$n%}{VByu8Y_!whR3yE-TsY#%~fn0y25X}E{CKf;4WOa^SfKP zfC!#8=4Xz@bg3~Q1E3q-ROdcec8O5_1~k*!uApnE=i_RwdCR6278XHbXmUa%euL|l zEC}qxcsK3W>|Rm6{ky0{z%c=?K_c;-RksIk?yAg6hBv#yIR$PrxhMck)Z#f+0BL}s)Uh>o1O8R%W&vhg&6K#XOIDh%_X4rtR7Ih`l+!V-a&EmJw=b3N~0?h{_&^ zmpo>{Ix+H^jF#1U`C0%PI;7jy%>3EqGzH_^JVRIcj~GJ`yPeU*JMmO>!cV zhiy}@y?HEY%4YO?sgjpM`prwjoeK)Dybq40H%0;7_oe{ ziZJ34*7!8_pCu5e+G_oUAEAsd(e;+bn`=b~ymvjKVDBLuByEcXc1{?m8T@N?`Vw{3 zf&d5k(CR$H5#jidkU?0oqD?qdzz&lm9xAsYjnJpTU;t_=0=kAlSL&f=r-bOXeV zQYBLt-J^Md1@nT5A^FM?)x957L@@qEy(vexngoW7ll9EA%m2>Jqp;w<>1HC11}O#% zlEf($i%0*?Rrd!C_1!zKc{IFCU~dA5T;<9~=Y9hXWeGaR9!(5Rkj<&~S+xp0I``jp zMCU#8(c>si;d{?azg#*xH;b~#NlN26!qHo0P!u06PM?p?{U5OF?7vA}DGmA;6Wv+% gA1M9u^dYT?Yl>+rCXopKl?0U@`m$C9$|36i0Q$D)`~Uy| literal 0 HcmV?d00001 diff --git a/docs/matGeom-manual/images/geom3d/cylindrical_coordinates.odg b/docs/matGeom-manual/images/geom3d/cylindrical_coordinates.odg new file mode 100644 index 0000000000000000000000000000000000000000..7c262d78b65087d8aba790834377eed3338c5d2e GIT binary patch literal 11730 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 JP{yaL{{jvuF4O=3 literal 0 HcmV?d00001 diff --git a/docs/matGeom-manual/images/geom3d/cylindrical_coordinates.png b/docs/matGeom-manual/images/geom3d/cylindrical_coordinates.png new file mode 100644 index 0000000000000000000000000000000000000000..db0569d4600e1e98e74e5dfafdfb42ed13ffdffd GIT binary patch literal 11400 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 Xm6Zeo|8?4j_Yd3qH;0$13V0)3^fWLH>m6-s) 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 literal 0 HcmV?d00001 diff --git a/docs/matGeom-manual/images/geom3d/spherical-angles.odg b/docs/matGeom-manual/images/geom3d/spherical-angles.odg index d20e1b32b9901d9ce497d60527f3a7671018456a..4ee2c6736f4d9edb6e86561d02e20e39cf9f3e29 100644 GIT binary patch delta 7479 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]WmZz}OtjX~UL8|ay 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 diff --git a/docs/matGeom-manual/matGeom-manual.lyx b/docs/matGeom-manual/matGeom-manual.lyx index 7b4b505c..a5286a62 100644 --- a/docs/matGeom-manual/matGeom-manual.lyx +++ b/docs/matGeom-manual/matGeom-manual.lyx @@ -12590,197 +12590,243 @@ Add Euler angles convention? \end_layout \begin_layout Section -Points and Vectors +Angles and coordinate systems \end_layout \begin_layout Standard -Both points and vectors are represented by a 1-by-3 array of coordinates: -\begin_inset listings -inline false -status open +\begin_inset Index gen +range none +pageformat default +status collapsed \begin_layout Plain Layout - -point = [x0 y0 z0]; +angle!3D \end_layout -\begin_layout Plain Layout - -vector = [dx dy dz]; -\end_layout +\end_inset +A precise definition of the coordinate systems is necessary to further define 3D transforms (in section +\begin_inset space ~ \end_inset +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:3D-Transforms" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + +). + Several of these coordinate systems are based on angles. + For example the spherical coordinates can be useful for considering positions of dimensionless objects such as points. + \end_layout \begin_layout Standard -Arrays of points or vectors are represented by N-by-3 arrays of coordinates. +Contrary to the planar case, + several angles are often necessary to define a coordinate system or a 3D transform. + Euler angles are a popular solution to represent arbitrary 3D rotations, + but several definitions exist. + They are presented in section +\begin_inset space ~ +\end_inset + + +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Euler-Angles" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + +. \end_layout \begin_layout Subsection -Points +Spherical coordinates \end_layout \begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "subsec:Points-3D" +Spherical coordinates comprise three components: + two angular coordinates on the surface of the sphere, + and the distance to origin. + They can be useful for considering positions of dimensionless objects such as points. + +\end_layout +\begin_layout Standard +The two spherical angles used by MatGeom are 1) the colatitude, + corresponding to the angle with the +\begin_inset Formula $z$ \end_inset +-axis, + and 2) the azimut (See Fig. +\begin_inset space ~ +\end_inset -\end_layout -\begin_layout Standard -The library provides several generic functions for working with points or point sets. -\end_layout +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Coordinates-systems" +plural "false" +caps "false" +noprefix "false" +nolink "false" -\begin_layout Minisec -midPoint3d -\begin_inset Index idx -range none -pageformat default +\end_inset + +). + The last coordinate is the distance to the origin. + Note that a different convention from standard Matlab was used: + a discussion can be found here +\begin_inset Foot status collapsed \begin_layout Plain Layout -midPoint3d +\begin_inset Flex URL +status open + +\begin_layout Plain Layout + +http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf \end_layout \end_inset - + \end_layout -\begin_layout Standard -Middle point of two 3D points or of a 3D edge. +\end_inset + +. \end_layout -\begin_layout Minisec -isCoplanar -\begin_inset Index idx -range none -pageformat default -status collapsed +\begin_layout Standard +\begin_inset Float figure +placement document +alignment document +wide false +sideways false +status open \begin_layout Plain Layout -isCoplanar -\end_layout +\align center +\begin_inset Graphics + filename images/geom3d/spherical-angles.png + width 45text% \end_inset -\end_layout +\begin_inset Graphics + filename images/geom3d/cylindrical_coordinates.png + width 45text% + +\end_inset + -\begin_layout Standard -Tests for coplanarity of points in 3-space. \end_layout -\begin_layout Minisec -transformPoint3d -\begin_inset Index idx -range none -pageformat default -status collapsed +\begin_layout Plain Layout +\begin_inset Caption Standard \begin_layout Plain Layout -transformPoint3d -\end_layout +\begin_inset CommandInset label +LatexCommand label +name "fig:Coordinates-systems" \end_inset - +Definition of spherical and cylindrincal coordinates. \end_layout -\begin_layout Standard -Applies a 3D affine transform to a point or an array of points. - See the section -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:3D-Transforms" -plural "false" -caps "false" -noprefix "false" -nolink "false" - \end_inset - for the creation of 3D transform matrices. -\end_layout - -\begin_layout Minisec -distancePoints3d -\begin_inset Index idx -range none -pageformat default -status collapsed -\begin_layout Plain Layout -distancePoints3d \end_layout \end_inset -\begin_inset Index gen +\end_layout + +\begin_layout Minisec +sph2cart2 +\begin_inset Index idx range none pageformat default -status open +status collapsed \begin_layout Plain Layout -distance!points (3D) +sph2cart2 \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes the Euclidean distance between pairs of 3D Points. +Converts spherical coordinates to cartesian coordinates. \end_layout \begin_layout Minisec -clipPoints3d +cart2sph2 \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -clipPoints3d +cart2sph2 \end_layout \end_inset + +\end_layout -\begin_inset Index gen +\begin_layout Standard +Converts cartesian coordinates to spherical coordinates. +\end_layout + +\begin_layout Minisec +cart2sph2d +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -clipping!points (3D) +cart2sph2d \end_layout \end_inset - + \end_layout \begin_layout Standard -Clips a set of points by a 3D box or by another 3d shape. +Converts cartesian coordinates to spherical coordinates in degrees. \end_layout \begin_layout Minisec -drawPoint3d +sph2cart2d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawPoint3d +sph2cart2d \end_layout \end_inset @@ -12789,37 +12835,48 @@ drawPoint3d \end_layout \begin_layout Standard -Draws 3D point on the current axis. +Converts spherical coordinates to cartesian coordinates in degrees. \end_layout \begin_layout Subsection -3D Vectors +Cylindrical coordinates \end_layout \begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "subsec:Vectors-3D" +Cylindrical coordinates comprise three components: + the azimut angle, + the distance to the +\begin_inset Formula $z$ +\end_inset +-axis, + and the altitude (See Fig. +\begin_inset space ~ \end_inset -\end_layout +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Coordinates-systems" +plural "false" +caps "false" +noprefix "false" +nolink "false" -\begin_layout Standard -Several functions are also provided to compute derived quantities from 3D vectors (products, - angles...). +\end_inset + +). \end_layout \begin_layout Minisec -normalizeVector3d +cart2cyl \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -normalizeVector3d +cart2cyl \end_layout \end_inset @@ -12828,18 +12885,18 @@ normalizeVector3d \end_layout \begin_layout Standard -Normalizes a 3D vector to have norm equal to 1. +Converts cartesian to cylindrical coordinates. \end_layout \begin_layout Minisec -vectorNorm3d +cyl2cart \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -vectorNorm3d +cyl2cart \end_layout \end_inset @@ -12848,72 +12905,66 @@ vectorNorm3d \end_layout \begin_layout Standard -Norm of a 3D vector or of set of 3D vectors. +Converts cylindrical to cartesian coordinates. +\end_layout + +\begin_layout Subsection +Other functions for angles \end_layout \begin_layout Minisec -hypot3 +anglePoints3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -hypot3 +anglePoints3d \end_layout \end_inset -\end_layout - -\begin_layout Standard -Computes the length of a 3D vector, - equivalent to the diagonal length of a cuboidal 3D box. -\end_layout - -\begin_layout Minisec -crossProduct3d -\begin_inset Index idx +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -crossProduct3d +angle!three points (3D) \end_layout \end_inset - + \end_layout \begin_layout Standard -Vector cross product, - faster than inbuilt MATLAB cross. +Computes angle between three 3D points. \end_layout \begin_layout Minisec -vectorAngle3d +sphericalAngle \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -vectorAngle3d +sphericalAngle \end_layout \end_inset - + \begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -angle!vectors (3D) +angle!spherical \end_layout \end_inset @@ -12922,18 +12973,18 @@ angle!vectors (3D) \end_layout \begin_layout Standard -Angle between two 3D vectors. +Computes angle between points on the sphere. \end_layout \begin_layout Minisec -isParallel3d +angleSort3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -isParallel3d +angleSort3d \end_layout \end_inset @@ -12942,18 +12993,18 @@ isParallel3d \end_layout \begin_layout Standard -Checks parallelism of two 3D vectors. +Sorts 3D coplanar points according to their angles in plane. \end_layout \begin_layout Minisec -isPerpendicular3d +randomAngle3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -isPerpendicular3d +randomAngle3d \end_layout \end_inset @@ -12962,31 +13013,43 @@ isPerpendicular3d \end_layout \begin_layout Standard -Checks orthogonality of two 3D vectors. +Returns a 3D angle uniformly distributed on unit sphere. \end_layout -\begin_layout Minisec -transformVector3d -\begin_inset Index idx -range none -pageformat default -status collapsed +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + -\begin_layout Plain Layout -transformVector3d \end_layout -\end_inset +\begin_layout Subsection +Orientation of shapes +\end_layout +\begin_layout Standard +The orientation of 3D shapes (ellipsoids, + cuboids, + 3D circles...) can be represented by a combination of rotation angles around reference axes. + Two different conventions are used to represent the orientation, + depending on the type of the shape: \end_layout -\begin_layout Standard -Applies a 3D affine transform to a vector or an array of vectors. - See the section +\begin_layout Itemize +elongated or "solid" shapes (ellipsoids, + cuboids, + cylinders...) consider two angles for representing the direction of the main axis of the shape, + and one angle to represent the rotation of the shape around that axis. + The direction is given by a (azimut, + elevation) pair (see Fig. +\begin_inset space ~ +\end_inset + + \begin_inset CommandInset ref LatexCommand ref -reference "sec:3D-Transforms" +reference "fig:Orientation-3D-Shapes" plural "false" caps "false" noprefix "false" @@ -12994,58 +13057,91 @@ nolink "false" \end_inset - for the definition of transforms. -\end_layout +). + This results in a "yaw-pitch-roll" triplet of angles ( +\begin_inset Formula $\varphi$ +\end_inset -\begin_layout Minisec -drawVector3d -\begin_inset Index idx -range none -pageformat default -status collapsed +, + +\begin_inset Formula $\theta$ +\end_inset -\begin_layout Plain Layout -drawVector3d -\end_layout +, + +\begin_inset Formula $\psi$ +\end_inset +), + corresponding to XYZ Euler angles (see also section +\begin_inset space ~ \end_inset - -\end_layout -\begin_layout Standard -Draws vector at a given position. -\end_layout +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Euler-Angles" +plural "false" +caps "false" +noprefix "false" +nolink "false" -\begin_layout Subsection -Boxes -\end_layout +\end_inset -\begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "subsec:Boxes-3D" +). +\end_layout +\begin_layout Itemize +flat objects (3D ellipses or discs), + or shapes organized around a symmetry axis consider two spherical angles for representing the main direction (usually that of the normal angle of the supporting plane), + and one angle for representing the rotation around the normal axis. + Spherical angle uses a (colatitude,azimut) pair (see Fig. +\begin_inset space ~ \end_inset -\end_layout +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Orientation-3D-Shapes" +plural "false" +caps "false" +noprefix "false" +nolink "false" -\begin_layout Standard -3D boxes are used to represent the physical extents of 3D geometries (bounding boxes), - or to clip geometries. -\begin_inset listings -inline false -status open +\end_inset -\begin_layout Plain Layout +). + This results in a triplet ( +\begin_inset Formula $\theta$ +\end_inset -box = [xmin xmax ymin ymax zmin zmax]; -\end_layout +, + +\begin_inset Formula $\varphi$ +\end_inset + +, + +\begin_inset Formula $\psi$ +\end_inset +) of three angles: + +\begin_inset Formula $\theta$ +\end_inset + + is the colatitude, + +\begin_inset Formula $\varphi$ \end_inset + is the azimut, + and +\begin_inset Formula $\psi$ +\end_inset + is the rotation angle around axis. + This corresponds to Euler angles with the "ZYZ" convention. \end_layout \begin_layout Standard @@ -13057,15 +13153,17 @@ sideways false status open \begin_layout Plain Layout +\align center +\begin_inset Graphics + filename images/geom3d/cylinder_angles.png + width 45text% + +\end_inset -\end_layout -\begin_layout Plain Layout -\align center \begin_inset Graphics - filename images/geom3d/boxes3d_intersect_merge.png - lyxscale 75 - width 70text% + filename images/geom3d/ellipse3d_angles.png + width 45text% \end_inset @@ -13078,12 +13176,11 @@ status open \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label -name "fig:Operations-on-3D-Boxes" +name "fig:Orientation-3D-Shapes" \end_inset -Operations on 3D boxes: - intersection and merge. +Orientation of 3D shapes. \end_layout \end_inset @@ -13096,15 +13193,35 @@ Operations on 3D boxes: \end_layout -\begin_layout Minisec -drawBox3d -\begin_inset Index idx -range none -pageformat default -status collapsed +\begin_layout Standard +Orientation angles of 3D shapes are always given in degrees. +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Section +Points and Vectors +\end_layout + +\begin_layout Standard +Both points and vectors are represented by a 1-by-3 array of coordinates: +\begin_inset listings +inline false +status open \begin_layout Plain Layout -drawBox3d + +point = [x0 y0 z0]; +\end_layout + +\begin_layout Plain Layout + +vector = [dx dy dz]; \end_layout \end_inset @@ -13113,39 +13230,56 @@ drawBox3d \end_layout \begin_layout Standard -Draws a 3D box, - defined by bounding coordinates along each dimension. +Arrays of points or vectors are represented by N-by-3 arrays of coordinates. +\end_layout + +\begin_layout Subsection +Points +\end_layout + +\begin_layout Standard +\begin_inset CommandInset label +LatexCommand label +name "subsec:Points-3D" + +\end_inset + + +\end_layout + +\begin_layout Standard +The library provides several generic functions for working with points or point sets. \end_layout \begin_layout Minisec -box3dVolume +midPoint3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -box3dVolume +midPoint3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes the the volume of a 3-dimensional box. +Middle point of two 3D points or of a 3D edge. \end_layout \begin_layout Minisec -boundingBox3d +isCoplanar \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -boundingBox3d +isCoplanar \end_layout \end_inset @@ -13154,36 +13288,31 @@ boundingBox3d \end_layout \begin_layout Standard -Computes the bounding box of a set of 3D points. +Tests for coplanarity of points in 3-space. \end_layout \begin_layout Minisec -intersectBoxes3d +transformPoint3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectBoxes3d +transformPoint3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes the intersection box of two 3D boxes, - i.e. - the largest box that is contained in both input boxes (See Fig. -\begin_inset space ~ -\end_inset - - +Applies a 3D affine transform to a point or an array of points. + See the section \begin_inset CommandInset ref LatexCommand ref -reference "fig:Operations-on-3D-Boxes" +reference "sec:3D-Transforms" plural "false" caps "false" noprefix "false" @@ -13191,160 +13320,82 @@ nolink "false" \end_inset -). + for the creation of 3D transform matrices. \end_layout \begin_layout Minisec -mergeBoxes3d +distancePoints3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -mergeBoxes3d +distancePoints3d \end_layout \end_inset +\begin_inset Index gen +range none +pageformat default +status open + +\begin_layout Plain Layout +distance!points (3D) \end_layout -\begin_layout Standard -Computes the union of two 3D boxes, - i.e. - the smallest box that contains both input boxes (See Fig. -\begin_inset space ~ \end_inset -\begin_inset CommandInset ref -LatexCommand ref -reference "fig:Operations-on-3D-Boxes" -plural "false" -caps "false" -noprefix "false" -nolink "false" - -\end_inset +\end_layout -). +\begin_layout Standard +Computes the Euclidean distance between pairs of 3D Points. \end_layout \begin_layout Minisec -orientedBox3d +clipPoints3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -orientedBox3d -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -Computes the 3D object-oriented bounding box of a set of points. - The bounding box is computed by first identifying the face of the convex hull that generates the smallest depth, - then computing the 2D bounding box on the plane projection. -\end_layout - -\begin_layout Standard -\begin_inset Newpage newpage -\end_inset - - -\end_layout - -\begin_layout Section -Linear shapes -\end_layout - -\begin_layout Standard -Linear shapes comprise straight lines, - edges (line segments), - and rays (half-lines). +clipPoints3d \end_layout -\begin_layout Standard -A 3D line is represented by a -\begin_inset Formula $1\times6$ \end_inset - numeric array resulting from the concatenation of a 3D point (its origin) and a 3D vector (its direction): - -\end_layout -\begin_layout Standard -\begin_inset listings -inline false -status open +\begin_inset Index gen +range none +pageformat default +status collapsed \begin_layout Plain Layout - -LINE = [X0 Y0 Z0 DX DY DZ]; +clipping!points (3D) \end_layout \end_inset -A 3D ray is represented the same way as a line. - The difference in the management is performed by the call in different functions (e.g. - -\begin_inset Quotes eld -\end_inset - -clipRay -\begin_inset Quotes erd -\end_inset - - instead of -\begin_inset Quotes eld -\end_inset - -clipLine -\begin_inset Quotes erd -\end_inset - -). -\end_layout -\begin_layout Standard -A 3D edge is represented by the coordinates of its extremities: - \end_layout \begin_layout Standard -\begin_inset listings -inline false -status open - -\begin_layout Plain Layout - -EDGE = [X1 Y1 Z1 X2 Y2 Z2]; -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Subsection -Creation +Clips a set of points by a 3D box or by another 3d shape. \end_layout \begin_layout Minisec -createLine3d +drawPoint3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -createLine3d +drawPoint3d \end_layout \end_inset @@ -13353,70 +13404,57 @@ createLine3d \end_layout \begin_layout Standard -Creates a 3D (straight) line with various inputs. +Draws 3D point on the current axis. \end_layout -\begin_layout Minisec -createRay3d -\begin_inset Index idx -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -createRay3d +\begin_layout Subsection +3D Vectors \end_layout +\begin_layout Standard +\begin_inset CommandInset label +LatexCommand label +name "subsec:Vectors-3D" + \end_inset - + \end_layout \begin_layout Standard -Creates a 3D ray (half-line) from two points. +Several functions are also provided to compute derived quantities from 3D vectors (products, + angles...). \end_layout \begin_layout Minisec -fitLine3d +normalizeVector3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -fitLine3d +normalizeVector3d \end_layout \end_inset -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -fitting!line 3D -\end_layout - -\end_inset - - \end_layout \begin_layout Standard -Fits a 3D line to a set of points. +Normalizes a 3D vector to have norm equal to 1. \end_layout \begin_layout Minisec -parallelLine3d +vectorNorm3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -parallelLine3d +vectorNorm3d \end_layout \end_inset @@ -13425,18 +13463,18 @@ parallelLine3d \end_layout \begin_layout Standard -Creates 3D line parallel to another one. +Norm of a 3D vector or of set of 3D vectors. \end_layout \begin_layout Minisec -transformLine3d +hypot3 \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -transformLine3d +hypot3 \end_layout \end_inset @@ -13445,30 +13483,19 @@ transformLine3d \end_layout \begin_layout Standard -Transforms a 3D line with a 3D affine transform. - See the section -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:3D-Transforms" -plural "false" -caps "false" -noprefix "false" -nolink "false" - -\end_inset - - for the definition of transforms. +Computes the length of a 3D vector, + equivalent to the diagonal length of a cuboidal 3D box. \end_layout \begin_layout Minisec -reverseLine3d +crossProduct3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -reverseLine3d +crossProduct3d \end_layout \end_inset @@ -13477,34 +13504,31 @@ reverseLine3d \end_layout \begin_layout Standard -Returns the same 3D line but with opposite orientation. -\end_layout - -\begin_layout Subsection -Relations with points +Vector cross product, + faster than inbuilt MATLAB cross. \end_layout \begin_layout Minisec -distancePointLine3d +vectorAngle3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -distancePointLine3d +vectorAngle3d \end_layout \end_inset - + \begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -distance!point to line (3D) +angle!vectors (3D) \end_layout \end_inset @@ -13513,18 +13537,18 @@ distance!point to line (3D) \end_layout \begin_layout Standard -Euclidean distance between 3D point and line. +Angle between two 3D vectors. \end_layout \begin_layout Minisec -isPointOnLine3d +isParallel3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -isPointOnLine3d +isParallel3d \end_layout \end_inset @@ -13533,50 +13557,38 @@ isPointOnLine3d \end_layout \begin_layout Standard -Tests if a 3D point belongs to a 3D line. +Checks parallelism of two 3D vectors. \end_layout \begin_layout Minisec -projPointOnLine3d +isPerpendicular3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -projPointOnLine3d +isPerpendicular3d \end_layout \end_inset -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -projection!on line (3D) -\end_layout - -\end_inset - - \end_layout \begin_layout Standard -Projects a 3D point orthogonally onto a 3D line. +Checks orthogonality of two 3D vectors. \end_layout \begin_layout Minisec -distancePointEdge3d +transformVector3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -distancePointEdge3d +transformVector3d \end_layout \end_inset @@ -13585,18 +13597,30 @@ distancePointEdge3d \end_layout \begin_layout Standard -Minimum distance between a 3D point and a 3D edge. +Applies a 3D affine transform to a vector or an array of vectors. + See the section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:3D-Transforms" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + + for the definition of transforms. \end_layout \begin_layout Minisec -line3dPoint +drawVector3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -line3dPoint +drawVector3d \end_layout \end_inset @@ -13605,242 +13629,243 @@ line3dPoint \end_layout \begin_layout Standard -Creates a 3D point at a given position on a 3D line. +Draws vector at a given position. \end_layout -\begin_layout Minisec -line3dPosition -\begin_inset Index idx -range none -pageformat default -status collapsed +\begin_layout Subsection +Boxes +\end_layout -\begin_layout Plain Layout -line3dPosition -\end_layout +\begin_layout Standard +\begin_inset CommandInset label +LatexCommand label +name "subsec:Boxes-3D" \end_inset - + \end_layout \begin_layout Standard -Returns the position of a 3D point projected on a 3D line. -\end_layout +3D boxes are used to represent the physical extents of 3D geometries (bounding boxes), + or to clip geometries. +\begin_inset listings +inline false +status open -\begin_layout Subsection -Clipping and conversion +\begin_layout Plain Layout + +box = [xmin xmax ymin ymax zmin zmax]; \end_layout -\begin_layout Standard -These functions compute the intersection of a linear geometry with a 3D bounding box. +\end_inset + + \end_layout -\begin_layout Minisec -clipLine3d -\begin_inset Index idx -range none -pageformat default -status collapsed +\begin_layout Standard +\begin_inset Float figure +placement document +alignment document +wide false +sideways false +status open \begin_layout Plain Layout -clipLine3d + \end_layout +\begin_layout Plain Layout +\align center +\begin_inset Graphics + filename images/geom3d/boxes3d_intersect_merge.png + lyxscale 75 + width 70text% + \end_inset -\begin_inset Index gen -range none -pageformat default -status collapsed +\end_layout \begin_layout Plain Layout -clipping!line (3D) -\end_layout +\begin_inset Caption Standard -\end_inset +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "fig:Operations-on-3D-Boxes" +\end_inset +Operations on 3D boxes: + intersection and merge. \end_layout -\begin_layout Standard -Clips a 3D line with a 3D box and return a 3D edge. -\end_layout +\end_inset -\begin_layout Minisec -clipEdge3d -\begin_inset Index idx -range none -pageformat default -status collapsed -\begin_layout Plain Layout -clipEdge3d \end_layout \end_inset - -\end_layout -\begin_layout Standard -Clips a 3D edge with a cuboid box. \end_layout \begin_layout Minisec -clipRay3d +drawBox3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -clipRay3d +drawBox3d \end_layout \end_inset - -\end_layout -\begin_layout Standard -Clip a 3D ray with a box and return a 3D edge. \end_layout -\begin_layout Subsection -Utility functions +\begin_layout Standard +Draws a 3D box, + defined by bounding coordinates along each dimension. \end_layout \begin_layout Minisec -distanceLines3d +box3dVolume \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -distanceLines3d +box3dVolume \end_layout \end_inset - + \end_layout \begin_layout Standard -Minimal distance between two 3D lines. +Computes the the volume of a 3-dimensional box. \end_layout \begin_layout Minisec -edgeToLine3d +boundingBox3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -edgeToLine3d +boundingBox3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Converts a 3D edge to a 3D straight line. +Computes the bounding box of a set of 3D points. \end_layout \begin_layout Minisec -midPoint3d +intersectBoxes3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -midPoint3d +intersectBoxes3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes the middle point of two 3D points, - or of a 3D edge, - depending on size of input argument(s). -\end_layout +Computes the intersection box of two 3D boxes, + i.e. + the largest box that is contained in both input boxes (See Fig. +\begin_inset space ~ +\end_inset -\begin_layout Subsection -Drawing -\end_layout -\begin_layout Standard -Drawing functions for linear geometries, - performing clipping with the bounding box corresponding to the current figure axes. +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Operations-on-3D-Boxes" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + +). \end_layout \begin_layout Minisec -drawLine3d +mergeBoxes3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawLine3d +mergeBoxes3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Draws a 3D line clipped by the current axes. -\end_layout +Computes the union of two 3D boxes, + i.e. + the smallest box that contains both input boxes (See Fig. +\begin_inset space ~ +\end_inset -\begin_layout Minisec -drawEdge3d -\begin_inset Index idx -range none -pageformat default -status collapsed -\begin_layout Plain Layout -drawEdge3d -\end_layout +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Operations-on-3D-Boxes" +plural "false" +caps "false" +noprefix "false" +nolink "false" \end_inset - -\end_layout - -\begin_layout Standard -Draws 3D edge in the current axes. +). \end_layout \begin_layout Minisec -drawRay3d +orientedBox3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawRay3d +orientedBox3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Draw a 3D ray on the current axis. +Computes the 3D object-oriented bounding box of a set of points. + The bounding box is computed by first identifying the face of the convex hull that generates the smallest depth, + then computing the 2D bounding box on the plane projection. \end_layout \begin_layout Standard @@ -13851,27 +13876,21 @@ Draw a 3D ray on the current axis. \end_layout \begin_layout Section -Planes +Linear shapes \end_layout \begin_layout Standard -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -plane +Linear shapes comprise straight lines, + edges (line segments), + and rays (half-lines). \end_layout +\begin_layout Standard +A 3D line is represented by a +\begin_inset Formula $1\times6$ \end_inset - -\end_layout - -\begin_layout Standard -Planes are represented by a 3D point (the plane origin) and 2 direction vectors, - which should not be colinear. + numeric array resulting from the concatenation of a 3D point (its origin) and a 3D vector (its direction): \end_layout @@ -13882,16 +13901,35 @@ status open \begin_layout Plain Layout -PLANE = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2]; +LINE = [X0 Y0 Z0 DX DY DZ]; \end_layout \end_inset +A 3D ray is represented the same way as a line. + The difference in the management is performed by the call in different functions (e.g. + +\begin_inset Quotes eld +\end_inset + +clipRay +\begin_inset Quotes erd +\end_inset + + instead of +\begin_inset Quotes eld +\end_inset + +clipLine +\begin_inset Quotes erd +\end_inset +). \end_layout \begin_layout Standard -The plane origin and direction vectors can be accessed by using array indexing: +A 3D edge is represented by the coordinates of its extremities: + \end_layout \begin_layout Standard @@ -13901,24 +13939,7 @@ status open \begin_layout Plain Layout -plane = ... -\end_layout - -\begin_layout Plain Layout - -origin = plane(1,1:3); -\end_layout - -\begin_layout Plain Layout - -v1 = plane(1, - 4:6); -\end_layout - -\begin_layout Plain Layout - -v2 = plane(1, - 7:9); +EDGE = [X1 Y1 Z1 X2 Y2 Z2]; \end_layout \end_inset @@ -13927,18 +13948,18 @@ v2 = plane(1, \end_layout \begin_layout Subsection -Creation and transformations +Creation \end_layout \begin_layout Minisec -createPlane +createLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -createPlane +createLine3d \end_layout \end_inset @@ -13947,18 +13968,18 @@ createPlane \end_layout \begin_layout Standard -Creates a plane in parametrized form. +Creates a 3D (straight) line with various inputs. \end_layout \begin_layout Minisec -medianPlane +createRay3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -medianPlane +createRay3d \end_layout \end_inset @@ -13967,18 +13988,18 @@ medianPlane \end_layout \begin_layout Standard -Creates a plane in the middle of 2 points. +Creates a 3D ray (half-line) from two points. \end_layout \begin_layout Minisec -fitPlane +fitLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -fitPlane +fitLine3d \end_layout \end_inset @@ -13990,7 +14011,7 @@ pageformat default status collapsed \begin_layout Plain Layout -fitting!plane +fitting!line 3D \end_layout \end_inset @@ -13999,18 +14020,18 @@ fitting!plane \end_layout \begin_layout Standard -Fits a 3D plane to a set of points. +Fits a 3D line to a set of points. \end_layout \begin_layout Minisec -normalizePlane +parallelLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -normalizePlane +parallelLine3d \end_layout \end_inset @@ -14019,18 +14040,18 @@ normalizePlane \end_layout \begin_layout Standard -Normalizes parametric representation of a plane. +Creates 3D line parallel to another one. \end_layout \begin_layout Minisec -parallelPlane +transformLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -parallelPlane +transformLine3d \end_layout \end_inset @@ -14039,86 +14060,86 @@ parallelPlane \end_layout \begin_layout Standard -Parallel to a plane through a point or at a given distance. +Transforms a 3D line with a 3D affine transform. + See the section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:3D-Transforms" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + + for the definition of transforms. \end_layout \begin_layout Minisec -reversePlane +reverseLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -reversePlane +reverseLine3d \end_layout \end_inset - -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -orientation!plane + \end_layout -\end_inset - - +\begin_layout Standard +Returns the same 3D line but with opposite orientation. \end_layout -\begin_layout Standard -Returns the same 3D plane but with opposite orientation. +\begin_layout Subsection +Relations with points \end_layout \begin_layout Minisec -transformPlane3d +distancePointLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -transformPlane3d +distancePointLine3d \end_layout \end_inset -\end_layout +\begin_inset Index gen +range none +pageformat default +status collapsed -\begin_layout Standard -Transforms a 3D plane with a 3D affine transform. - See the section -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:3D-Transforms" -plural "false" -caps "false" -noprefix "false" -nolink "false" +\begin_layout Plain Layout +distance!point to line (3D) +\end_layout \end_inset - for the definition of transforms. + \end_layout -\begin_layout Subsection -Computing intersections +\begin_layout Standard +Euclidean distance between 3D point and line. \end_layout \begin_layout Minisec -intersectPlanes +isPointOnLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectPlanes +isPointOnLine3d \end_layout \end_inset @@ -14127,38 +14148,30 @@ intersectPlanes \end_layout \begin_layout Standard -Returns the intersection line between 2 planes in space. +Tests if a 3D point belongs to a 3D line. \end_layout \begin_layout Minisec -intersectThreePlanes +projPointOnLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectThreePlanes +projPointOnLine3d \end_layout \end_inset - -\end_layout - -\begin_layout Standard -Returns the intersection point between 3 planes in space. -\end_layout - -\begin_layout Minisec -intersectLinePlane -\begin_inset Index idx + +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -intersectLinePlane +projection!on line (3D) \end_layout \end_inset @@ -14167,18 +14180,18 @@ intersectLinePlane \end_layout \begin_layout Standard -Intersection point between a 3D line and a plane. +Projects a 3D point orthogonally onto a 3D line. \end_layout \begin_layout Minisec -intersectEdgePlane +distancePointEdge3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectEdgePlane +distancePointEdge3d \end_layout \end_inset @@ -14187,18 +14200,18 @@ intersectEdgePlane \end_layout \begin_layout Standard -Returns intersection point between a plane and a edge. +Minimum distance between a 3D point and a 3D edge. \end_layout \begin_layout Minisec -planesBisector +line3dPoint \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -planesBisector +line3dPoint \end_layout \end_inset @@ -14207,22 +14220,18 @@ planesBisector \end_layout \begin_layout Standard -Bisector plane between two other planes. -\end_layout - -\begin_layout Subsection -Point positions +Creates a 3D point at a given position on a 3D line. \end_layout \begin_layout Minisec -planePosition +line3dPosition \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -planePosition +line3dPosition \end_layout \end_inset @@ -14231,50 +14240,38 @@ planePosition \end_layout \begin_layout Standard -Computes the position of a point on a plane. -\end_layout - -\begin_layout Minisec -planePoint -\begin_inset Index idx -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -planePoint +Returns the position of a 3D point projected on a 3D line. \end_layout -\end_inset - - +\begin_layout Subsection +Clipping and conversion \end_layout \begin_layout Standard -Computes the 3D position of a point in a plane. +These functions compute the intersection of a linear geometry with a 3D bounding box. \end_layout \begin_layout Minisec -projPointOnPlane +clipLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -projPointOnPlane +clipLine3d \end_layout \end_inset - + \begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -projection!on plane +clipping!line (3D) \end_layout \end_inset @@ -14283,70 +14280,62 @@ projection!on plane \end_layout \begin_layout Standard -Returns the orthogonal projection of a point on a plane. +Clips a 3D line with a 3D box and return a 3D edge. \end_layout \begin_layout Minisec -distancePointPlane +clipEdge3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -distancePointPlane +clipEdge3d \end_layout \end_inset -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -distance!point to plane -\end_layout - -\end_inset - - \end_layout \begin_layout Standard -Signed distance betwen 3D point and plane. +Clips a 3D edge with a cuboid box. \end_layout \begin_layout Minisec -isBelowPlane +clipRay3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -isBelowPlane +clipRay3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Tests whether a point is below or above a plane. +Clip a 3D ray with a box and return a 3D edge. +\end_layout + +\begin_layout Subsection +Utility functions \end_layout \begin_layout Minisec -projLineOnPlane +distanceLines3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -projLineOnPlane +distanceLines3d \end_layout \end_inset @@ -14355,22 +14344,18 @@ projLineOnPlane \end_layout \begin_layout Standard -Returns the orthogonal projection of a line on a plane. -\end_layout - -\begin_layout Subsection -Measures +Minimal distance between two 3D lines. \end_layout \begin_layout Minisec -planeNormal +edgeToLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -planeNormal +edgeToLine3d \end_layout \end_inset @@ -14379,74 +14364,89 @@ planeNormal \end_layout \begin_layout Standard -Computes the normal to a plane. +Converts a 3D edge to a 3D straight line. \end_layout \begin_layout Minisec -isPlane +midPoint3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -isPlane +midPoint3d \end_layout \end_inset + +\end_layout + +\begin_layout Standard +Computes the middle point of two 3D points, + or of a 3D edge, + depending on size of input argument(s). +\end_layout +\begin_layout Subsection +Drawing \end_layout \begin_layout Standard -Checks if input is a plane. +Drawing functions for linear geometries, + performing clipping with the bounding box corresponding to the current figure axes. \end_layout \begin_layout Minisec -dihedralAngle +drawLine3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -dihedralAngle +drawLine3d \end_layout \end_inset + +\end_layout -\begin_inset Index gen +\begin_layout Standard +Draws a 3D line clipped by the current axes. +\end_layout + +\begin_layout Minisec +drawEdge3d +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -angle!dihedral +drawEdge3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes the dihedral angle between 2 planes. -\end_layout - -\begin_layout Subsection -Drawing +Draws 3D edge in the current axes. \end_layout \begin_layout Minisec -drawPlane3d +drawRay3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawPlane3d +drawRay3d \end_layout \end_inset @@ -14455,7 +14455,7 @@ drawPlane3d \end_layout \begin_layout Standard -Draws a plane clipped by the current axes. +Draw a 3D ray on the current axis. \end_layout \begin_layout Standard @@ -14466,13 +14466,18 @@ Draws a plane clipped by the current axes. \end_layout \begin_layout Section -3D Polygons +Planes \end_layout \begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "sec:Polygons-3D" +\begin_inset Index gen +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +plane +\end_layout \end_inset @@ -14480,74 +14485,75 @@ name "sec:Polygons-3D" \end_layout \begin_layout Standard -These functions operate on 3D polygons that are not necessarily embedded into a plane. - As for the 2-dimensional case, - polygons correspond to closed curves, - whereas polylines correspond to open curves (see section -\begin_inset space ~ -\end_inset +Planes are represented by a 3D point (the plane origin) and 2 direction vectors, + which should not be colinear. + +\end_layout +\begin_layout Standard +\begin_inset listings +inline false +status open -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:Curves-3D" -plural "false" -caps "false" -noprefix "false" -nolink "false" +\begin_layout Plain Layout + +PLANE = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2]; +\end_layout \end_inset -). + \end_layout -\begin_layout Subsection -Representation +\begin_layout Standard +The plane origin and direction vectors can be accessed by using array indexing: \end_layout \begin_layout Standard -\begin_inset Index gen -range none -pageformat default -status collapsed +\begin_inset listings +inline false +status open \begin_layout Plain Layout -polygon (3D) + +plane = ... \end_layout -\end_inset +\begin_layout Plain Layout -Polygons are represented by -\begin_inset Formula $N\times3$ -\end_inset +origin = plane(1,1:3); +\end_layout - array of vertex coordinates. - The behaviour is not specified for 3D polygons with non-coplanar vertices. +\begin_layout Plain Layout + +v1 = plane(1, + 4:6); \end_layout -\begin_layout Standard -Some functions accept complex polygons, - represented by a series of polygonal contours. +\begin_layout Plain Layout + +v2 = plane(1, + 7:9); \end_layout -\begin_layout Subsection -Operations +\end_inset + + \end_layout -\begin_layout Standard -Comprises geometric operations such as computing intersections, - of applying geometric transform. +\begin_layout Subsection +Creation and transformations \end_layout \begin_layout Minisec -intersectLinePolygon3d +createPlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectLinePolygon3d +createPlane \end_layout \end_inset @@ -14556,18 +14562,18 @@ intersectLinePolygon3d \end_layout \begin_layout Standard -Intersection point of a 3D line and a 3D polygon. +Creates a plane in parametrized form. \end_layout \begin_layout Minisec -intersectRayPolygon3d +medianPlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectRayPolygon3d +medianPlane \end_layout \end_inset @@ -14576,30 +14582,30 @@ intersectRayPolygon3d \end_layout \begin_layout Standard -Intersection point of a 3D ray and a 3D polygon. +Creates a plane in the middle of 2 points. \end_layout \begin_layout Minisec -clipPolygonByPlane3d +fitPlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -clipPolygonByPlane3d +fitPlane \end_layout \end_inset - + \begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -clipping!polygon (3D) +fitting!plane \end_layout \end_inset @@ -14608,114 +14614,58 @@ clipping!polygon (3D) \end_layout \begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "fun:clipPolygonByPlane3d" - -\end_inset - -Clips a convex 3D polygon with a -\begin_inset Quotes eld -\end_inset - -half-space -\begin_inset Quotes erd -\end_inset - - defined by a 3D plane. - See also the function clipConvexPolyhedronByPlane -\begin_inset CommandInset ref -LatexCommand vpageref -reference "fun:clipConvexPolyhedronByPlane" -plural "false" -caps "false" -noprefix "false" -nolink "false" - -\end_inset - -. +Fits a 3D plane to a set of points. \end_layout \begin_layout Minisec -transformPolygon3d +normalizePlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -transformPolygon3d +normalizePlane \end_layout \end_inset - + \end_layout \begin_layout Standard -Transform a polygon with a 3D affine transform. +Normalizes parametric representation of a plane. \end_layout \begin_layout Minisec -projPointOnPolyline3d +parallelPlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout - -\family roman -\series medium -\shape up -\size normal -\emph off -\nospellcheck off -\bar no -\strikeout off -\xout off -\uuline off -\uwave off -\noun off -\color none -projPointOnPolyline3d -\end_layout - -\end_inset - - -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -projection!on polyline (3D) +parallelPlane \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes the position of a 3D point projected on a 3D polyline. -\end_layout - -\begin_layout Subsection -Measurements +Parallel to a plane through a point or at a given distance. \end_layout \begin_layout Minisec -polygonCentroid3d +reversePlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -polygonCentroid3d +reversePlane \end_layout \end_inset @@ -14727,7 +14677,7 @@ pageformat default status collapsed \begin_layout Plain Layout -centroid!polygon (3D) +orientation!plane \end_layout \end_inset @@ -14736,50 +14686,54 @@ centroid!polygon (3D) \end_layout \begin_layout Standard -Centroid (or center of mass) of a polygon. +Returns the same 3D plane but with opposite orientation. \end_layout \begin_layout Minisec -polygonArea3d +transformPlane3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -polygonArea3d +transformPlane3d \end_layout \end_inset -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -area!polygon (3D) \end_layout -\end_inset +\begin_layout Standard +Transforms a 3D plane with a 3D affine transform. + See the section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:3D-Transforms" +plural "false" +caps "false" +noprefix "false" +nolink "false" +\end_inset + for the definition of transforms. \end_layout -\begin_layout Standard -Area of a 3D polygon. +\begin_layout Subsection +Computing intersections \end_layout \begin_layout Minisec -polygon3dNormalAngle +intersectPlanes \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -polygon3dNormalAngle +intersectPlanes \end_layout \end_inset @@ -14788,18 +14742,18 @@ polygon3dNormalAngle \end_layout \begin_layout Standard -Computes the normal angle at a vertex of the 3D polygon. +Returns the intersection line between 2 planes in space. \end_layout \begin_layout Minisec -isPolygon3d +intersectThreePlanes \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -isPolygon3d +intersectThreePlanes \end_layout \end_inset @@ -14808,29 +14762,38 @@ isPolygon3d \end_layout \begin_layout Standard -Checks if the input is a 3D polygon. +Returns the intersection point between 3 planes in space. +\end_layout + +\begin_layout Minisec +intersectLinePlane +\begin_inset Index idx +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +intersectLinePlane \end_layout -\begin_layout Standard -\begin_inset Newpage newpage \end_inset \end_layout -\begin_layout Subsection -Drawing functions +\begin_layout Standard +Intersection point between a 3D line and a plane. \end_layout \begin_layout Minisec -drawPolygon3d +intersectEdgePlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawPolygon3d +intersectEdgePlane \end_layout \end_inset @@ -14839,18 +14802,18 @@ drawPolygon3d \end_layout \begin_layout Standard -Draws a 3D polygon specified by a list of vertex coords. +Returns intersection point between a plane and a edge. \end_layout \begin_layout Minisec -fillPolygon3d +planesBisector \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -fillPolygon3d +planesBisector \end_layout \end_inset @@ -14859,45 +14822,62 @@ fillPolygon3d \end_layout \begin_layout Standard -Fills a 3D polygon specified by a list of vertex coords. +Bisector plane between two other planes. \end_layout \begin_layout Subsection -3D Triangles +Point positions \end_layout -\begin_layout Standard -\begin_inset Index gen +\begin_layout Minisec +planePosition +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -triangle (3D) +planePosition \end_layout \end_inset + +\end_layout + +\begin_layout Standard +Computes the position of a point on a plane. +\end_layout + +\begin_layout Minisec +planePoint +\begin_inset Index idx +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +planePoint +\end_layout + +\end_inset + \end_layout \begin_layout Standard -A 3D triangle is simply defined by a triplet of 3D points. - Within MatGeom, - it is usually represented either as a 1-by-9 row vector, - or as a 3-by-3 numeric array, - where each row contains the coordinates of a single vertex. +Computes the 3D position of a point in a plane. \end_layout \begin_layout Minisec -triangleArea3d +projPointOnPlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -triangleArea3d +projPointOnPlane \end_layout \end_inset @@ -14909,7 +14889,7 @@ pageformat default status collapsed \begin_layout Plain Layout -area!triangle (3D) +projection!on plane \end_layout \end_inset @@ -14918,18 +14898,18 @@ area!triangle (3D) \end_layout \begin_layout Standard -Computes the area of a 3D triangle. +Returns the orthogonal projection of a point on a plane. \end_layout \begin_layout Minisec -distancePointTriangle3d +distancePointPlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -distancePointTriangle3d +distancePointPlane \end_layout \end_inset @@ -14941,7 +14921,7 @@ pageformat default status collapsed \begin_layout Plain Layout -distance!point to triangle (3D) +distance!point to plane \end_layout \end_inset @@ -14950,77 +14930,62 @@ distance!point to triangle (3D) \end_layout \begin_layout Standard -Comptues the minimum distance between a 3D point and a 3D triangle. +Signed distance betwen 3D point and plane. \end_layout \begin_layout Minisec -intersectLineTriangle3d +isBelowPlane \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectLineTriangle3d +isBelowPlane \end_layout \end_inset - -\end_layout -\begin_layout Standard -Computes the intersection point of a 3D line and a 3D triangle. \end_layout \begin_layout Standard -\begin_inset Newpage newpage -\end_inset - - +Tests whether a point is below or above a plane. \end_layout -\begin_layout Section -3D curves -\end_layout +\begin_layout Minisec +projLineOnPlane +\begin_inset Index idx +range none +pageformat default +status collapsed -\begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "sec:Curves-3D" +\begin_layout Plain Layout +projLineOnPlane +\end_layout \end_inset - + \end_layout \begin_layout Standard -This sections describes smooth 3D curves (other than lines or line segments) that can be manipulated within the MatGeom library. - Most curves are usually converted to 3D polyline for further computation. +Returns the orthogonal projection of a line on a plane. \end_layout \begin_layout Subsection -Polyline -\end_layout - -\begin_layout Standard -As for 2D polygons, - 3D polylines are represented by a -\begin_inset Formula $N\times3$ -\end_inset - - numeric array containing vertex coordinates. +Measures \end_layout \begin_layout Minisec -drawPolyline3d +planeNormal \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawPolyline3d +planeNormal \end_layout \end_inset @@ -15029,21 +14994,18 @@ drawPolyline3d \end_layout \begin_layout Standard -Draws a 3D polyline specified by a list of vertex coordinates. -\end_layout - -\begin_layout Subsection -Circles +Computes the normal to a plane. \end_layout -\begin_layout Standard -\begin_inset Index gen +\begin_layout Minisec +isPlane +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -circle!3D +isPlane \end_layout \end_inset @@ -15052,115 +15014,155 @@ circle!3D \end_layout \begin_layout Standard -Circles in 3D are represented by a 1-by-7 row vector containing the coordinates of the centroid, - the radius, - and three Euler angles describing the orientation of the circle. +Checks if input is a plane. \end_layout -\begin_layout Standard -\begin_inset listings -inline false -status open +\begin_layout Minisec +dihedralAngle +\begin_inset Index idx +range none +pageformat default +status collapsed \begin_layout Plain Layout - -circle = [x0 y0 z0 R PHI THETA PSI]; +dihedralAngle \end_layout \end_inset -\end_layout - -\begin_layout Minisec -fitCircle3d -\begin_inset Index idx +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -fitCircle3d +angle!dihedral \end_layout \end_inset - + \end_layout \begin_layout Standard -Fits a 3D circle to a set of points. +Computes the dihedral angle between 2 planes. +\end_layout + +\begin_layout Subsection +Drawing \end_layout \begin_layout Minisec -distancePointCircle3d +drawPlane3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -distancePointCircle3d +drawPlane3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Returns the distance between 3D points and 3D circle. +Draws a plane clipped by the current axes. \end_layout -\begin_layout Minisec -transformCircle3d -\begin_inset Index idx -range none -pageformat default -status collapsed +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset -\begin_layout Plain Layout -transformCircle3d + +\end_layout + +\begin_layout Section +3D Polygons \end_layout +\begin_layout Standard +\begin_inset CommandInset label +LatexCommand label +name "sec:Polygons-3D" + \end_inset \end_layout \begin_layout Standard -Transforms a 3D circle with a 3D affine transformation. +These functions operate on 3D polygons that are not necessarily embedded into a plane. + As for the 2-dimensional case, + polygons correspond to closed curves, + whereas polylines correspond to open curves (see section +\begin_inset space ~ +\end_inset + + +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Curves-3D" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + +). \end_layout -\begin_layout Minisec -circle3dPosition -\begin_inset Index idx +\begin_layout Subsection +Representation +\end_layout + +\begin_layout Standard +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -circle3dPosition +polygon (3D) \end_layout \end_inset - +Polygons are represented by +\begin_inset Formula $N\times3$ +\end_inset + + array of vertex coordinates. + The behaviour is not specified for 3D polygons with non-coplanar vertices. \end_layout \begin_layout Standard -Returns the angular position of a point on a 3D circle. +Some functions accept complex polygons, + represented by a series of polygonal contours. +\end_layout + +\begin_layout Subsection +Operations +\end_layout + +\begin_layout Standard +Comprises geometric operations such as computing intersections, + of applying geometric transform. \end_layout \begin_layout Minisec -circle3dPoint +intersectLinePolygon3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -circle3dPoint +intersectLinePolygon3d \end_layout \end_inset @@ -15169,18 +15171,18 @@ circle3dPoint \end_layout \begin_layout Standard -Coordinates of a point on a 3D circle from its position. +Intersection point of a 3D line and a 3D polygon. \end_layout \begin_layout Minisec -circle3dOrigin +intersectRayPolygon3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -circle3dOrigin +intersectRayPolygon3d \end_layout \end_inset @@ -15189,68 +15191,76 @@ circle3dOrigin \end_layout \begin_layout Standard -Returns the first point of a 3D circle. +Intersection point of a 3D ray and a 3D polygon. \end_layout \begin_layout Minisec -drawCircle3d +clipPolygonByPlane3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawCircle3d +clipPolygonByPlane3d \end_layout \end_inset - -\end_layout - -\begin_layout Standard -Draws a 3D circle. -\end_layout -\begin_layout Minisec -drawCircleArc3d -\begin_inset Index idx +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -drawCircleArc3d +clipping!polygon (3D) \end_layout \end_inset - + \end_layout \begin_layout Standard -Draws a 3D circle arc. -\end_layout +\begin_inset CommandInset label +LatexCommand label +name "fun:clipPolygonByPlane3d" -\begin_layout Standard -\begin_inset Newpage newpage \end_inset +Clips a convex 3D polygon with a +\begin_inset Quotes eld +\end_inset -\end_layout +half-space +\begin_inset Quotes erd +\end_inset -\begin_layout Subsection -Ellipses + defined by a 3D plane. + See also the function clipConvexPolyhedronByPlane +\begin_inset CommandInset ref +LatexCommand vpageref +reference "fun:clipConvexPolyhedronByPlane" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + +. \end_layout -\begin_layout Standard -\begin_inset Index gen +\begin_layout Minisec +transformPolygon3d +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -ellipse!3D +transformPolygon3d \end_layout \end_inset @@ -15259,112 +15269,80 @@ ellipse!3D \end_layout \begin_layout Standard -Ellipses in 3D are represented by a 1-by-9 row vector containing the coordinates of the centroid, - the length of the three semi-axes, - and three Euler angles describing the orientation of the ellipse. -\begin_inset listings -inline false -status open - -\begin_layout Plain Layout - -elli = [x0 y0 z0 A B C PHI THETA PSI]; -\end_layout - -\end_inset - - +Transform a polygon with a 3D affine transform. \end_layout \begin_layout Minisec -fitEllipse3d +projPointOnPolyline3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -fitEllipse3d + +\family roman +\series medium +\shape up +\size normal +\emph off +\nospellcheck off +\bar no +\strikeout off +\xout off +\uuline off +\uwave off +\noun off +\color none +projPointOnPolyline3d \end_layout \end_inset - -\end_layout - -\begin_layout Standard -Fits a 3D ellipse to a set of points. -\end_layout -\begin_layout Minisec -drawEllipse3d -\begin_inset Index idx +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -drawEllipse3d -\end_layout - -\end_inset - - +projection!on polyline (3D) \end_layout -\begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "fun:drawEllipse3d" - \end_inset -Draws a 3D ellipse. -\end_layout -\begin_layout Section -Smooth surfaces \end_layout \begin_layout Standard -Several geometric surfaces can be manipulated within MatGeom. - They include spheres, - ellipsoids, - cylinders, - and revolution surfaces. +Computes the position of a 3D point projected on a 3D polyline. \end_layout \begin_layout Subsection -Spheres +Measurements \end_layout -\begin_layout Standard -\begin_inset Index gen +\begin_layout Minisec +polygonCentroid3d +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -sphere +polygonCentroid3d \end_layout \end_inset -\end_layout - -\begin_layout Standard -Spheres are defined by a center and a radius. -\end_layout - -\begin_layout Standard -\begin_inset listings -inline false -status open +\begin_inset Index gen +range none +pageformat default +status collapsed \begin_layout Plain Layout - -sphere = [x0 y0 z0 R] +centroid!polygon (3D) \end_layout \end_inset @@ -15372,39 +15350,51 @@ sphere = [x0 y0 z0 R] \end_layout -\begin_layout Subsubsection -Creation and intersections +\begin_layout Standard +Centroid (or center of mass) of a polygon. \end_layout \begin_layout Minisec -createSphere +polygonArea3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -createSphere +polygonArea3d \end_layout \end_inset +\begin_inset Index gen +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +area!polygon (3D) +\end_layout + +\end_inset + + \end_layout \begin_layout Standard -Creates a sphere passing through 4 points. +Area of a 3D polygon. \end_layout \begin_layout Minisec -intersectLineSphere +polygon3dNormalAngle \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectLineSphere +polygon3dNormalAngle \end_layout \end_inset @@ -15413,87 +15403,92 @@ intersectLineSphere \end_layout \begin_layout Standard -Returns the intersection points between a line and a sphere. +Computes the normal angle at a vertex of the 3D polygon. \end_layout \begin_layout Minisec -intersectPlaneSphere +isPolygon3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -intersectPlaneSphere +isPolygon3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Returns the intersection circle between a plane and a sphere. +Checks if the input is a 3D polygon. \end_layout -\begin_layout Subsubsection -Drawing functions +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + \end_layout -\begin_layout Standard -Several functions are provided to draw spheres, - or geometries defined over a sphere. +\begin_layout Subsection +Drawing functions \end_layout \begin_layout Minisec -drawSphere +drawPolygon3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawSphere +drawPolygon3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Draws a sphere as a mesh. +Draws a 3D polygon specified by a list of vertex coords. \end_layout \begin_layout Minisec -drawSphericalEdge +fillPolygon3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawSphericalEdge +fillPolygon3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Draws an edge on the surface of a sphere. +Fills a 3D polygon specified by a list of vertex coords. \end_layout -\begin_layout Minisec -drawSphericalTriangle -\begin_inset Index idx +\begin_layout Subsection +3D Triangles +\end_layout + +\begin_layout Standard +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -drawSphericalTriangle +triangle (3D) \end_layout \end_inset @@ -15502,38 +15497,34 @@ drawSphericalTriangle \end_layout \begin_layout Standard -Draws a triangle on a sphere. +A 3D triangle is simply defined by a triplet of 3D points. + Within MatGeom, + it is usually represented either as a 1-by-9 row vector, + or as a 3-by-3 numeric array, + where each row contains the coordinates of a single vertex. \end_layout \begin_layout Minisec -fillSphericalTriangle +triangleArea3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -fillSphericalTriangle +triangleArea3d \end_layout \end_inset - -\end_layout - -\begin_layout Standard -Fills a triangle on a sphere. -\end_layout - -\begin_layout Minisec -drawSphericalPolygon -\begin_inset Index idx + +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -drawSphericalPolygon +area!triangle (3D) \end_layout \end_inset @@ -15542,18 +15533,30 @@ drawSphericalPolygon \end_layout \begin_layout Standard -Draws a spherical polygon. +Computes the area of a 3D triangle. \end_layout \begin_layout Minisec -fillSphericalPolygon +distancePointTriangle3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -fillSphericalPolygon +distancePointTriangle3d +\end_layout + +\end_inset + + +\begin_inset Index gen +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +distance!point to triangle (3D) \end_layout \end_inset @@ -15562,18 +15565,18 @@ fillSphericalPolygon \end_layout \begin_layout Standard -Fills a spherical polygon. +Comptues the minimum distance between a 3D point and a 3D triangle. \end_layout \begin_layout Minisec -sphericalVoronoiDomain +intersectLineTriangle3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -sphericalVoronoiDomain +intersectLineTriangle3d \end_layout \end_inset @@ -15582,86 +15585,80 @@ sphericalVoronoiDomain \end_layout \begin_layout Standard -Computes a spherical voronoi domain. -\end_layout - -\begin_layout Subsection -Ellipsoids +Computes the intersection point of a 3D line and a 3D triangle. \end_layout \begin_layout Standard -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -ellipsoid -\end_layout - +\begin_inset Newpage newpage \end_inset \end_layout -\begin_layout Standard -Ellipsoids are a generalization of spheres, - that are defined by a center, - three radius, - and three Euler angles (see Section -\begin_inset space ~ -\end_inset - +\begin_layout Section +3D curves +\end_layout -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:Euler-Angles" -plural "false" -caps "false" -noprefix "false" -nolink "false" +\begin_layout Standard +\begin_inset CommandInset label +LatexCommand label +name "sec:Curves-3D" \end_inset -). + \end_layout \begin_layout Standard -\begin_inset listings -inline false -status open - -\begin_layout Plain Layout +This sections describes smooth 3D curves (other than lines or line segments) that can be manipulated within the MatGeom library. + Most curves are usually converted to 3D polyline for further computation. +\end_layout -Elli = [x0 y0 z0 RA RB RC PHI THETA PSI] +\begin_layout Subsection +Polyline \end_layout +\begin_layout Standard +As for 2D polygons, + 3D polylines are represented by a +\begin_inset Formula $N\times3$ \end_inset - + numeric array containing vertex coordinates. \end_layout \begin_layout Minisec -equivalentEllipsoid +drawPolyline3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -equivalentEllipsoid +drawPolyline3d \end_layout \end_inset +\end_layout + +\begin_layout Standard +Draws a 3D polyline specified by a list of vertex coordinates. +\end_layout + +\begin_layout Subsection +Circles +\end_layout + +\begin_layout Standard \begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -moments!points (3D) +circle!3D \end_layout \end_inset @@ -15670,62 +15667,55 @@ moments!points (3D) \end_layout \begin_layout Standard -Computes the ellipsoid with the same moments up to the second order as the given set of 3D points (Fig. -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "fig:Equivalent-Ellipsoid" -nolink "false" - -\end_inset - -). - Note that it -\series bold -does not -\series default -correspond to the inertia ellipsoid as defined from mechanical conventions. +Circles in 3D are represented by a 1-by-7 row vector containing the coordinates of the centroid, + the radius, + and three Euler angles describing the orientation of the circle. \end_layout \begin_layout Standard -\begin_inset Float figure -placement document -alignment document -wide false -sideways false +\begin_inset listings +inline false status open \begin_layout Plain Layout -\align center -\begin_inset Graphics - filename images/demoInertiaEllipsoid_03.png - lyxscale 50 - width 60text% + +circle = [x0 y0 z0 R PHI THETA PSI]; +\end_layout \end_inset \end_layout -\begin_layout Plain Layout -\begin_inset Caption Standard +\begin_layout Minisec +fitCircle3d +\begin_inset Index idx +range none +pageformat default +status collapsed \begin_layout Plain Layout -\begin_inset CommandInset label -LatexCommand label -name "fig:Equivalent-Ellipsoid" +fitCircle3d +\end_layout \end_inset -Equivalent ellipsoid of a point cloud. + \end_layout -\end_inset +\begin_layout Standard +Fits a 3D circle to a set of points. +\end_layout +\begin_layout Minisec +distancePointCircle3d +\begin_inset Index idx +range none +pageformat default +status collapsed +\begin_layout Plain Layout +distancePointCircle3d \end_layout \end_inset @@ -15733,15 +15723,19 @@ Equivalent ellipsoid of a point cloud. \end_layout +\begin_layout Standard +Returns the distance between 3D points and 3D circle. +\end_layout + \begin_layout Minisec -isPointInEllipsoid +transformCircle3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -isPointInEllipsoid +transformCircle3d \end_layout \end_inset @@ -15750,89 +15744,78 @@ isPointInEllipsoid \end_layout \begin_layout Standard -Determines if a 3D points lies within or outside an ellipsoid. +Transforms a 3D circle with a 3D affine transformation. \end_layout \begin_layout Minisec -ellipsoidSurfaceArea +circle3dPosition \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -ellipsoidSurfaceArea +circle3dPosition \end_layout \end_inset -\begin_inset Index gen +\end_layout + +\begin_layout Standard +Returns the angular position of a point on a 3D circle. +\end_layout + +\begin_layout Minisec +circle3dPoint +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -area!ellipsoid +circle3dPoint \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes an approximation of the surface area of an ellipsoid from the semi-axis lengths. - The approximation formula is given by: -\begin_inset Formula -\begin{align*} -S & \sim4\pi\cdot\left(\frac{1}{3}\left(a^{p}\cdot b^{p}+a^{p}\cdot c^{p}+b^{p}\cdot c^{p}\right)\right)^{1/p} -\end{align*} - -\end_inset - -with -\begin_inset Formula $p=1.6075$ -\end_inset - -. - The resulting error should be less than -\begin_inset Formula $1.061\%$ -\end_inset - -. +Coordinates of a point on a 3D circle from its position. \end_layout \begin_layout Minisec -oblateSurfaceArea +circle3dOrigin \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -oblateSurfaceArea +circle3dOrigin \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes the approximated surface area of an oblate ellipsoid, - given its largest and smallest radiusses. +Returns the first point of a 3D circle. \end_layout \begin_layout Minisec -prolateSurfaceArea +drawCircle3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -prolateSurfaceArea +drawCircle3d \end_layout \end_inset @@ -15841,19 +15824,18 @@ prolateSurfaceArea \end_layout \begin_layout Standard -Computes the approximated surface area of a prolate ellipsoid, - given its largest and smallest radiusses. +Draws a 3D circle. \end_layout \begin_layout Minisec -drawEllipsoid +drawCircleArc3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawEllipsoid +drawCircleArc3d \end_layout \end_inset @@ -15862,29 +15844,18 @@ drawEllipsoid \end_layout \begin_layout Standard -Draws a 3D ellipsoid. - It is possible to specify color or transparency of the ellipsoid surface. - The three orthogonal reference 3D ellipses can also be displayed. - See also the drawEllipse3d function (p. -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand pageref -reference "fun:drawEllipse3d" -plural "false" -caps "false" -noprefix "false" -nolink "false" +Draws a 3D circle arc. +\end_layout +\begin_layout Standard +\begin_inset Newpage newpage \end_inset -). + \end_layout \begin_layout Subsection -Cylinders +Ellipses \end_layout \begin_layout Standard @@ -15894,7 +15865,7 @@ pageformat default status collapsed \begin_layout Plain Layout -cylinder +ellipse!3D \end_layout \end_inset @@ -15903,20 +15874,16 @@ cylinder \end_layout \begin_layout Standard -A cylinder is defined by two end-points and a radius. - It is represented as a -\begin_inset Formula $1\times7$ -\end_inset - - row vector (three values for each endpoint, - and one value for the radius). +Ellipses in 3D are represented by a 1-by-9 row vector containing the coordinates of the centroid, + the length of the three semi-axes, + and three Euler angles describing the orientation of the ellipse. \begin_inset listings inline false status open \begin_layout Plain Layout -Cylinder = [X1 Y1 Z1 X2 Y2 Z2 R]; +elli = [x0 y0 z0 A B C PHI THETA PSI]; \end_layout \end_inset @@ -15925,112 +15892,94 @@ Cylinder = [X1 Y1 Z1 X2 Y2 Z2 R]; \end_layout \begin_layout Minisec -cylinderSurfaceArea +fitEllipse3d \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -cylinderSurfaceArea +fitEllipse3d \end_layout \end_inset -\begin_inset Index gen +\end_layout + +\begin_layout Standard +Fits a 3D ellipse to a set of points. +\end_layout + +\begin_layout Minisec +drawEllipse3d +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -area!cylinder +drawEllipse3d \end_layout \end_inset - + \end_layout \begin_layout Standard -Computes the surface area of a cylinder, - based on its length and radius. -\end_layout - -\begin_layout Minisec -intersectLineCylinder -\begin_inset Index idx -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -intersectLineCylinder -\end_layout +\begin_inset CommandInset label +LatexCommand label +name "fun:drawEllipse3d" \end_inset - +Draws a 3D ellipse. \end_layout -\begin_layout Standard -Computes the intersection points between a line and a cylinder. +\begin_layout Section +Smooth surfaces \end_layout -\begin_layout Minisec -drawCylinder -\begin_inset Index idx -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -drawCylinder +\begin_layout Standard +Several geometric surfaces can be manipulated within MatGeom. + They include spheres, + ellipsoids, + cylinders, + and revolution surfaces. \end_layout -\end_inset - - +\begin_layout Subsection +Spheres \end_layout \begin_layout Standard -Draws a cylinder on the current axis. -\end_layout - -\begin_layout Minisec -drawEllipseCylinder -\begin_inset Index idx +\begin_inset Index gen range none pageformat default status collapsed \begin_layout Plain Layout -drawEllipseCylinder +sphere \end_layout \end_inset - + \end_layout \begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "fun:drawEllipseCylinder" - -\end_inset +Spheres are defined by a center and a radius. +\end_layout -Draws a cylinder with an ellipse cross-section. - -\begin_inset Note Note +\begin_layout Standard +\begin_inset listings +inline false status open \begin_layout Plain Layout -TODO: - Figure to display more sample surface (cylinder, - capsule, - dome, - torus...) + +sphere = [x0 y0 z0 R] \end_layout \end_inset @@ -16038,82 +15987,59 @@ TODO: \end_layout -\begin_layout Subsection -Other smooth surfaces -\end_layout - -\begin_layout Standard -Other functions allow to create and draw more general surfaces. +\begin_layout Subsubsection +Creation and intersections \end_layout -\begin_layout Standard -\begin_inset Note Note -status open +\begin_layout Minisec +createSphere +\begin_inset Index idx +range none +pageformat default +status collapsed \begin_layout Plain Layout -TODO: - Figure to display more sample surface (capsule, - dome, - torus...) +createSphere \end_layout \end_inset - + \end_layout \begin_layout Standard -\begin_inset Float figure -placement document -alignment document -wide false -sideways false -status open - -\begin_layout Plain Layout -\align center -\begin_inset Graphics - filename images/demoRevolutionSurface_01.png - lyxscale 50 - width 60text% - -\end_inset - - +Creates a sphere passing through 4 points. \end_layout -\begin_layout Plain Layout -\begin_inset Caption Standard +\begin_layout Minisec +intersectLineSphere +\begin_inset Index idx +range none +pageformat default +status collapsed \begin_layout Plain Layout -\begin_inset CommandInset label -LatexCommand label -name "fig:Revolution-Surface" - -\end_inset - -3D revolution surface +intersectLineSphere \end_layout \end_inset - + \end_layout -\end_inset - - +\begin_layout Standard +Returns the intersection points between a line and a sphere. \end_layout \begin_layout Minisec -revolutionSurface +intersectPlaneSphere \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -revolutionSurface +intersectPlaneSphere \end_layout \end_inset @@ -16122,46 +16048,47 @@ revolutionSurface \end_layout \begin_layout Standard -Creates a surface of revolution from a planar curve. - See the Figure -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "fig:Revolution-Surface" -plural "false" -caps "false" -noprefix "false" -nolink "false" +Returns the intersection circle between a plane and a sphere. +\end_layout -\end_inset +\begin_layout Subsubsection +Drawing functions +\end_layout -. +\begin_layout Standard +Several functions are provided to draw spheres, + or geometries defined over a sphere. \end_layout \begin_layout Minisec -surfaceCurvature +drawSphere \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -surfaceCurvature +drawSphere \end_layout \end_inset - -\begin_inset Index gen + +\end_layout + +\begin_layout Standard +Draws a sphere as a mesh. +\end_layout + +\begin_layout Minisec +drawSphericalEdge +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -curvature +drawSphericalEdge \end_layout \end_inset @@ -16170,30 +16097,38 @@ curvature \end_layout \begin_layout Standard -Curvature on a surface from angle and principal curvatures. +Draws an edge on the surface of a sphere. \end_layout \begin_layout Minisec -drawTorus +drawSphericalTriangle \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawTorus +drawSphericalTriangle \end_layout \end_inset - -\begin_inset Index gen + +\end_layout + +\begin_layout Standard +Draws a triangle on a sphere. +\end_layout + +\begin_layout Minisec +fillSphericalTriangle +\begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -torus +fillSphericalTriangle \end_layout \end_inset @@ -16202,18 +16137,18 @@ torus \end_layout \begin_layout Standard -Draws a torus (3D ring). +Fills a triangle on a sphere. \end_layout \begin_layout Minisec -drawCapsule +drawSphericalPolygon \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawCapsule +drawSphericalPolygon \end_layout \end_inset @@ -16222,19 +16157,18 @@ drawCapsule \end_layout \begin_layout Standard -Draws a 3D capsule, - composed of a cylinder and two domes at the extremities. +Draws a spherical polygon. \end_layout \begin_layout Minisec -drawDome +fillSphericalPolygon \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawDome +fillSphericalPolygon \end_layout \end_inset @@ -16243,19 +16177,18 @@ drawDome \end_layout \begin_layout Standard -Draws a 3D dome, - or half-sphere. +Fills a spherical polygon. \end_layout \begin_layout Minisec -drawSurfPatch +sphericalVoronoiDomain \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -drawSurfPatch +sphericalVoronoiDomain \end_layout \end_inset @@ -16264,19 +16197,11 @@ drawSurfPatch \end_layout \begin_layout Standard -Draws a 3D surface patch, - with 2 parametrized surfaces. -\end_layout - -\begin_layout Standard -\begin_inset Newpage newpage -\end_inset - - +Computes a spherical voronoi domain. \end_layout -\begin_layout Section -Angles and coordinate systems +\begin_layout Subsection +Ellipsoids \end_layout \begin_layout Standard @@ -16286,19 +16211,26 @@ pageformat default status collapsed \begin_layout Plain Layout -angle!3D +ellipsoid \end_layout \end_inset -A precise definition of the coordinate systems is necessary to further define 3D transforms (in section + +\end_layout + +\begin_layout Standard +Ellipsoids are a generalization of spheres, + that are defined by a center, + three radius, + and three Euler angles (see Section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref -reference "sec:3D-Transforms" +reference "subsec:Euler-Angles" plural "false" caps "false" noprefix "false" @@ -16307,77 +16239,70 @@ nolink "false" \end_inset ). - Several of these coordinate systems are based on angles. - For eaxample the spherical coordinates can be useful for considering positions of dimensionless objects such as points. - \end_layout \begin_layout Standard -Contrary to the planar case, - several angles are often necessary to define a coordinate system or a 3D transform. - Euler angles are a popular solution to represent arbitrary 3D rotations, - but several definitions exist. - They are presented in section -\begin_inset space ~ -\end_inset +\begin_inset listings +inline false +status open +\begin_layout Plain Layout -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:Euler-Angles" -plural "false" -caps "false" -noprefix "false" -nolink "false" +Elli = [x0 y0 z0 RA RB RC PHI THETA PSI] +\end_layout \end_inset -. -\end_layout -\begin_layout Subsection -Spherical coordinates \end_layout -\begin_layout Standard -Spherical coordinates comprise three components: - two angular coordinates on the surface of the sphere, - and the distance to origin. - They can be useful for considering positions of dimensionless objects such as points. - +\begin_layout Minisec +equivalentEllipsoid +\begin_inset Index idx +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +equivalentEllipsoid \end_layout -\begin_layout Standard -The two spherical angles used by MatGeom are 1) the colatitude, - corresponding to the angle with the -\begin_inset Formula $z$ \end_inset --axis, - and 2) the azimut. - The last coordinate is the distance to the origin. - Note that a different convention from standard Matlab was used: - A discussion can be found here -\begin_inset Foot + +\begin_inset Index gen +range none +pageformat default status collapsed \begin_layout Plain Layout -\begin_inset Flex URL -status open +moments!points (3D) +\end_layout + +\end_inset -\begin_layout Plain Layout -http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf \end_layout +\begin_layout Standard +Computes the ellipsoid with the same moments up to the second order as the given set of 3D points (Fig. +\begin_inset space ~ \end_inset -\end_layout +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Equivalent-Ellipsoid" +nolink "false" \end_inset -. +). + Note that it +\series bold +does not +\series default +correspond to the inertia ellipsoid as defined from mechanical conventions. \end_layout \begin_layout Standard @@ -16391,8 +16316,9 @@ status open \begin_layout Plain Layout \align center \begin_inset Graphics - filename images/geom3d/spherical-angles.png - scale 60 + filename images/demoInertiaEllipsoid_03.png + lyxscale 50 + width 60text% \end_inset @@ -16403,7 +16329,13 @@ status open \begin_inset Caption Standard \begin_layout Plain Layout -Definition of spherical coordinates. +\begin_inset CommandInset label +LatexCommand label +name "fig:Equivalent-Ellipsoid" + +\end_inset + +Equivalent ellipsoid of a point cloud. \end_layout \end_inset @@ -16417,34 +16349,105 @@ Definition of spherical coordinates. \end_layout \begin_layout Minisec -sph2cart2 +isPointInEllipsoid \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -sph2cart2 +isPointInEllipsoid +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Determines if a 3D points lies within or outside an ellipsoid. +\end_layout + +\begin_layout Minisec +ellipsoidSurfaceArea +\begin_inset Index idx +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +ellipsoidSurfaceArea \end_layout \end_inset +\begin_inset Index gen +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +area!ellipsoid +\end_layout + +\end_inset + + \end_layout \begin_layout Standard -Converts spherical coordinates to cartesian coordinates. +Computes an approximation of the surface area of an ellipsoid from the semi-axis lengths. + The approximation formula is given by: +\begin_inset Formula +\begin{align*} +S & \sim4\pi\cdot\left(\frac{1}{3}\left(a^{p}\cdot b^{p}+a^{p}\cdot c^{p}+b^{p}\cdot c^{p}\right)\right)^{1/p} +\end{align*} + +\end_inset + +with +\begin_inset Formula $p=1.6075$ +\end_inset + +. + The resulting error should be less than +\begin_inset Formula $1.061\%$ +\end_inset + +. \end_layout \begin_layout Minisec -cart2sph2 +oblateSurfaceArea \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -cart2sph2 +oblateSurfaceArea +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Computes the approximated surface area of an oblate ellipsoid, + given its largest and smallest radiusses. +\end_layout + +\begin_layout Minisec +prolateSurfaceArea +\begin_inset Index idx +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +prolateSurfaceArea \end_layout \end_inset @@ -16453,18 +16456,19 @@ cart2sph2 \end_layout \begin_layout Standard -Converts cartesian coordinates to spherical coordinates. +Computes the approximated surface area of a prolate ellipsoid, + given its largest and smallest radiusses. \end_layout \begin_layout Minisec -cart2sph2d +drawEllipsoid \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -cart2sph2d +drawEllipsoid \end_layout \end_inset @@ -16473,53 +16477,258 @@ cart2sph2d \end_layout \begin_layout Standard -Converts cartesian coordinates to spherical coordinates in degrees. +Draws a 3D ellipsoid. + It is possible to specify color or transparency of the ellipsoid surface. + The three orthogonal reference 3D ellipses can also be displayed. + See also the drawEllipse3d function (p. +\begin_inset space ~ +\end_inset + + +\begin_inset CommandInset ref +LatexCommand pageref +reference "fun:drawEllipse3d" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + +). +\end_layout + +\begin_layout Subsection +Cylinders +\end_layout + +\begin_layout Standard +\begin_inset Index gen +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +cylinder +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +A cylinder is defined by two end-points and a radius. + It is represented as a +\begin_inset Formula $1\times7$ +\end_inset + + row vector (three values for each endpoint, + and one value for the radius). +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +Cylinder = [X1 Y1 Z1 X2 Y2 Z2 R]; +\end_layout + +\end_inset + + \end_layout \begin_layout Minisec -sph2cart2d +cylinderSurfaceArea \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -sph2cart2d +cylinderSurfaceArea \end_layout \end_inset +\begin_inset Index gen +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +area!cylinder +\end_layout + +\end_inset + + \end_layout \begin_layout Standard -Converts spherical coordinates to cartesian coordinates in degrees. +Computes the surface area of a cylinder, + based on its length and radius. +\end_layout + +\begin_layout Minisec +intersectLineCylinder +\begin_inset Index idx +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +intersectLineCylinder +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Computes the intersection points between a line and a cylinder. +\end_layout + +\begin_layout Minisec +drawCylinder +\begin_inset Index idx +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +drawCylinder +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Draws a cylinder on the current axis. +\end_layout + +\begin_layout Minisec +drawEllipseCylinder +\begin_inset Index idx +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +drawEllipseCylinder +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset CommandInset label +LatexCommand label +name "fun:drawEllipseCylinder" + +\end_inset + +Draws a cylinder with an ellipse cross-section. + +\begin_inset Note Note +status open + +\begin_layout Plain Layout +TODO: + Figure to display more sample surface (cylinder, + capsule, + dome, + torus...) +\end_layout + +\end_inset + + \end_layout \begin_layout Subsection -Cylindrical coordinates +Other smooth surfaces \end_layout \begin_layout Standard -Cylindrical coordinates comprise three components: - the azimut angle, - the distance to the -\begin_inset Formula $z$ +Other functions allow to create and draw more general surfaces. +\end_layout + +\begin_layout Standard +\begin_inset Note Note +status open + +\begin_layout Plain Layout +TODO: + Figure to display more sample surface (capsule, + dome, + torus...) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Float figure +placement document +alignment document +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Graphics + filename images/demoRevolutionSurface_01.png + lyxscale 50 + width 60text% + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "fig:Revolution-Surface" + +\end_inset + +3D revolution surface +\end_layout + +\end_inset + + +\end_layout + \end_inset --axis, - and the altitude. + \end_layout \begin_layout Minisec -cart2cyl +revolutionSurface \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -cart2cyl +revolutionSurface \end_layout \end_inset @@ -16528,42 +16737,66 @@ cart2cyl \end_layout \begin_layout Standard -Converts cartesian to cylindrical coordinates. +Creates a surface of revolution from a planar curve. + See the Figure +\begin_inset space ~ +\end_inset + + +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Revolution-Surface" +plural "false" +caps "false" +noprefix "false" +nolink "false" + +\end_inset + +. \end_layout \begin_layout Minisec -cyl2cart +surfaceCurvature \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -cyl2cart +surfaceCurvature \end_layout \end_inset +\begin_inset Index gen +range none +pageformat default +status collapsed + +\begin_layout Plain Layout +curvature \end_layout -\begin_layout Standard -Converts cylindrical to cartesian coordinates. +\end_inset + + \end_layout -\begin_layout Subsection -Other functions for angles +\begin_layout Standard +Curvature on a surface from angle and principal curvatures. \end_layout \begin_layout Minisec -anglePoints3d +drawTorus \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -anglePoints3d +drawTorus \end_layout \end_inset @@ -16575,7 +16808,7 @@ pageformat default status collapsed \begin_layout Plain Layout -angle!three points (3D) +torus \end_layout \end_inset @@ -16584,30 +16817,18 @@ angle!three points (3D) \end_layout \begin_layout Standard -Computes angle between three 3D points. +Draws a torus (3D ring). \end_layout \begin_layout Minisec -sphericalAngle +drawCapsule \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -sphericalAngle -\end_layout - -\end_inset - - -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -angle!spherical +drawCapsule \end_layout \end_inset @@ -16616,38 +16837,40 @@ angle!spherical \end_layout \begin_layout Standard -Computes angle between points on the sphere. +Draws a 3D capsule, + composed of a cylinder and two domes at the extremities. \end_layout \begin_layout Minisec -angleSort3d +drawDome \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -angleSort3d +drawDome \end_layout \end_inset - + \end_layout \begin_layout Standard -Sorts 3D coplanar points according to their angles in plane. +Draws a 3D dome, + or half-sphere. \end_layout \begin_layout Minisec -randomAngle3d +drawSurfPatch \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -randomAngle3d +drawSurfPatch \end_layout \end_inset @@ -16656,7 +16879,8 @@ randomAngle3d \end_layout \begin_layout Standard -Returns a 3D angle uniformly distributed on unit sphere. +Draws a 3D surface patch, + with 2 parametrized surfaces. \end_layout \begin_layout Standard @@ -17107,6 +17331,16 @@ transfo = createRotationOz(theta); Euler Angles and 3D rotations \end_layout +\begin_layout Standard +\begin_inset CommandInset label +LatexCommand label +name "subsec:Euler-Angles" + +\end_inset + + +\end_layout + \begin_layout Standard Several different conventions exist for considering 3D rotations. One possibility is to consider the @@ -17126,13 +17360,6 @@ Euler Angles \end_layout \begin_layout Standard -\begin_inset CommandInset label -LatexCommand label -name "subsec:Euler-Angles" - -\end_inset - - \begin_inset Index gen range none pageformat default @@ -17149,8 +17376,14 @@ angle!Euler angles \begin_layout Standard Euler Angles are defined by a series of three rotations along specific axes. - Several definitions of Euler angles exist. - The MatGeom library uses Euler angles defined as a series of three + Several definitions of Euler angles exist, + depending on the axes and on the order rotations are performed, + and if the rotation are performed in the global coordinate system, + or in the coordinate system of the reference object after rotation. +\end_layout + +\begin_layout Standard +The MatGeom library usually uses Euler angles defined as a series of three \begin_inset Quotes eld \end_inset @@ -17175,23 +17408,12 @@ global -axis: \begin_inset Formula \begin{align} -R_{\varphi,\theta,\psi} & =R_{z}(\psi)\cdot R_{y}(\theta)\cdot R_{x}(\varphi) +R_{\varphi,\theta,\psi} & =R_{z}(\varphi)\cdot R_{y}(\theta)\cdot R_{x}(\psi) \end{align} \end_inset -Note that within the library, - Euler angles are usually given in the order -\begin_inset Formula $(\varphi,\theta,\psi)$ -\end_inset -, - i.e. - in the reverse order to that they are applied. - Moreover, - when used for describing the 3D rotation of a shape, - they are expressed in degrees. - \end_layout \begin_layout Standard @@ -17293,6 +17515,21 @@ PSI is the 'roll', with value in degrees \end_layout +\begin_layout Standard +Note that within the MatGeom library, + Euler angles are usually given in the order +\begin_inset Formula $(\varphi,\theta,\psi)$ +\end_inset + +, + i.e. + in the reverse order to that they are applied. + Moreover, + when used for describing the 3D rotation of a shape, + they are expressed in degrees. + +\end_layout + \begin_layout Minisec eulerAnglesToRotation3d \begin_inset Index idx @@ -18282,7 +18519,7 @@ Geometric processing of 3D polygonal meshes requires to take into account both t several abstract data types have been proposed to efficiently represent such data \begin_inset CommandInset citation LatexCommand citep -key "Bieri_1991,Chen_1996,DeBerg_2000" +key "Bieri_1991,Chen_1996,DeBerg_2000,Botsch_2010" literal "false" \end_inset @@ -18854,20 +19091,6 @@ faces that maybe useful or necessary for some functions. \end_layout -\begin_layout Standard -\begin_inset Note Note -status open - -\begin_layout Plain Layout -Add illustration of triangular mesh with vertex ring + boundary edges ; - also simple 3D quad mesh -\end_layout - -\end_inset - - -\end_layout - \begin_layout Section Mesh visualization \end_layout @@ -21360,36 +21583,40 @@ f2 = triangulateFaces(f); \end_layout \begin_layout Minisec -mergeCoplanarFaces +reverseMeshFaceOrientation \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -mergeCoplanarFaces + +\family roman +\series medium +\shape up +\size normal +\emph off +\nospellcheck off +\bar no +\strikeout off +\xout off +\uuline off +\uwave off +\noun off +\color none +reverseMeshFaceOrientation \end_layout \end_inset - -\end_layout - -\begin_layout Standard -Merges coplanar faces of a polyhedral mesh. -\end_layout -\begin_layout Standard -\begin_inset listings -inline false -status open +\begin_inset Index gen +range none +pageformat default +status collapsed \begin_layout Plain Layout - -[v2, - f2] = mergeCoplanarFaces(v, - f, - tol); +orientation!mesh \end_layout \end_inset @@ -21397,24 +21624,48 @@ status open \end_layout +\begin_layout Standard +Reverses the normal of each face within the mesh. + In case of boundary-free mesh, + the volume enclosed by the resulting mesh becomes the opposite of that of the original mesh. +\end_layout + \begin_layout Minisec -meshComplement +mergeCoplanarFaces \begin_inset Index idx range none pageformat default status collapsed \begin_layout Plain Layout -meshComplement +mergeCoplanarFaces \end_layout \end_inset + +\end_layout +\begin_layout Standard +Merges coplanar faces of a polyhedral mesh. \end_layout \begin_layout Standard -Reverses the normal of each face in the mesh. +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +[v2, + f2] = mergeCoplanarFaces(v, + f, + tol); +\end_layout + +\end_inset + + \end_layout \begin_layout Minisec @@ -21890,54 +22141,6 @@ Clips a mesh by a plane. Generic operations \end_layout -\begin_layout Minisec -reverseMeshFaceOrientation -\begin_inset Index idx -range none -pageformat default -status collapsed - -\begin_layout Plain Layout - -\family roman -\series medium -\shape up -\size normal -\emph off -\nospellcheck off -\bar no -\strikeout off -\xout off -\uuline off -\uwave off -\noun off -\color none -reverseMeshFaceOrientation -\end_layout - -\end_inset - - -\begin_inset Index gen -range none -pageformat default -status collapsed - -\begin_layout Plain Layout -orientation!mesh -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -Reverses the normal of each face within the mesh. - In case of boundary-free mesh, - the volume enclosed by the resulting mesh becomes the opposite of that of the original mesh. -\end_layout - \begin_layout Minisec averageMesh \begin_inset Index idx diff --git a/docs/matGeom-manual/matGeom.bib b/docs/matGeom-manual/matGeom.bib index 41a152e3..d1b82e1c 100644 --- a/docs/matGeom-manual/matGeom.bib +++ b/docs/matGeom-manual/matGeom.bib @@ -304,4 +304,13 @@ @Book{DeBerg_2000 timestamp = {2000.00.00}, } +@Book{Botsch_2010, + author = {Botsch, Mario and Kobbelt, Leif and Pauly, Mark and Alliez, Pierre and L\'evy, Bruno}, + publisher = {CRC Press}, + title = {{Polygon Mesh Processing}}, + year = {2010}, + creationdate = {2024-07-16T17:54:13}, + url = {https://www.pmp-book.org/}, +} + @Comment{jabref-meta: databaseType:bibtex;}