In this post we’ll be doing some heavy math to calculate the distance between BF and EN. And to learn a little more gl, we’ll be displaying the data, like so:
Note the nice circular formation of the cubes – this is a stable “merry-go-round” configuration in which the friends chase each other in a circle while keeping their enemies at least one cube distant. See my last post for the starting positions and relationships that create this very nice pattern.
The first part of this patch is to make the stack of cubes in the upper left corner. We do this by dumping just the color information from the points table, and incrementing the y position of the cube placement using the index.
Show Max Compressed Code<pre><code> ----------begin_max5_patcher---------- 1243.3ocyYssaaiCD8YmuBtF4oEJFhWDIUeb2OihEAzVL1pQlzvhNWZQ+2Wp gRwJMRIrI1JEAvjhhilYN7vCujebwr4KsOnqmi9B5qnYy9wEylAM0zvr1mmM eq5gUUpZnayWY2tUabySBuyoevAsarN8WPFK5aktEqqVrQYJpzInZKxsQiVc XotFU6TOh1cvgtei1.suWW6P1af506TqznxZzdqS4zEKPFsx8WctppznWYOX .+Qaarr.7tc42tR10warFmQsUCu4esG1Wp2i9GaUQWGLG1VZpzNHiv8rpt76 fUX4hzi80dv004tV24iaOJnbkVy060qbAHjgIdCQrLQSQZ6On+qyJka0lRy5 QsfxAa3fQM17yKtn4mjO3fSwd08vPPyHvpaGDQIuDQEe9HZVN.LDoLVD84Vf oPAibhQz0ZidumjhdDsxZ2WfVpp0EHqAUZJzODKmk+4ivTYF.Tx7XQ3maQKB ex4r0Ukd0fpRu9PoAsQUcSrz1rOeP8JLO.QQSa4hdFbtXs9Ps.I8bUy554uD 3Xe9.Gl.3.OZxHICfJIHihy.SHryk94.fFcJAsAxeJvzn3SQ9az26SoWj9UV UQCmYfrGOAYeWmCM4dbmNj5ygX5UIGDPohx.Lpcgg2K3rUWWqVqeI4Puys4Z sQsrR6iUjuvTz64px0abMw0wlp2Zsdap2nJ7u.giUYCSHuO7lbRv6nvZICjt R4ghSKSzuCwaQ2D9a.1H4cJ8yN+vSqxNIKr1IK6bLQ8u8pk3gvE1mIs4Fu9g 6UAGJl0a0O9YAa9dEJrkB5P.DcB.HxnDmj3HOc63BmeVDxpTO5yUVBZq8Nsy htJcQN5Rle0GT3UzDz5pU1J6dzkXzkDzkTOgKKIbzB+TcVrBY+Aqi0MQMf0r T1GRGa4AmyZFhwk9pKLdpVA7oroa+jefcUNxDqCeuDIGZqAxIXLl9pHSxwxR iKFfRhOeJPvDBelmhDCAWuySam86.WrwfqF3IoUIJdzBmFDjH4mG7ppBsy5i kgNrBdJN6L6UkrS9MjtCy8n4xiHUqQMo40EJmpEgZgnYyeR.Ulz1RWu9Jzum 5o+M2perWx0zxcppCsQqWH2ugCIimzTMUPvTLbvJNOGyZpwwYMEzbnPJCCiy 5FDGzWjw7EgvjBYyGBiwBL3JRFllSZpkkK.mjQIPoPHxhwczwbmTxEBvIXNM SRfjDmRjzPpwB9QlEJy7OGi+Xild4XRC94qRYYhbZnpfIDPPHCoUa5wyhxaY i4MtOOxygAmToDpPX9DN3DVvGoAeQIwkZoi5LFlxCrDrD2kYRYZJ78yw88Vy .XLdiO5.WJmR4PFIxxjTfR1BtoKXAelJCdiIixYhQG0Rwo7.qOWPDz.PJSyC CVA7iEfUeO56r1pduFlvVqtSWbsWCxOI+ZkysuzuJe3Vz6O8UucoFjqvsle5 TFaui85a0d8Fz818G055qPNEWMwGdSsrvE3PB2X1KVCA9Bv9I+k+MEvWro8m Ce09raUWLzc1GzQ01Bcs+v3v0N0uS9CNhnO0oMkEEZS+adYaYQ6JQfQirLWr wDbN92LnZF+50oydPESH8KA94Nl9SDm.txaRnlXbpABvwPxmP9DOlXhM8wza N1Mw7ozX33xoEmDwDS7oMljwDShOPL4e3mW7+4M5DNA -----------end_max5_patcher----------- </code></pre>
Once the cubes are drawn once, we can leave them; the renderer will happily render them each frame.
Now we need to calculate the distance from each cube to its EN. To do this, we use the 3d equivalent of Pythagorean theorem (a2 + b2 = c2), which is:
x2 + y2 + z2 = d2
where x, y, and z here refer to the distance between the cube and its EN, and d is the resultant distance. So if we think of the cube as being at x1, y1, z1 and its EN as being at x2, y2, z2
then we can more accurately use the formula:![]()
To carry this out, we’ll take the result of the vector subtraction we used earlier in creating the “normalized vectors” and feed it into:
expr sqrt(($f1*$f1) + ($f2*$f2) + ($f3*$f3))
And store the results in a new coll called “dist2enemy”
<pre><code> ----------begin_max5_patcher---------- 1487.3oc6assbaaCD8Y4uBLZxCIsJdv8K8w1OiLc7PIA4vFJRWQHWmjo+6EX AYLsMoLrTHq8LJdjDHH.1cOKvdVPh78KlMeY0c154neC8IzrYe+hYyfpBULq 45Yy2lc2phrZnYyWUscqszMeQ7dN6cNn9ZW0NKZcdsKqbksFkWhxPk1+A4xV VXaad9ZnwUK+qOxZqaSUoqLaqEtyeTseWtcG52qJV21fx8ayKKrNPAHc5Uc9 2fdQzWhuusU6csMts1a1Yq8JclKup7pc1UtnEywgNhzbxkhEHbnr+Kze11qL 2pOmWdcmdPk7PqTBdnGLtHbEkG5TnO+6EWD9ZQhXoGd7HwSfxatEsZ+tcdE9 J+sCx9onGcTPuUUEU6hVJ9RshKHADgJvFcnfhnjb0BDoCH8P.mbX.Wpo.foj 8B3wAx80arwlOe9g7EdsBFLIKLXDCeT7EYq9BJGsoGW.AqNNm.8kLElbTXSD mUT.ZnzQAZbnk8hKZyDrxlNDrrLq754KPy2TTk4R.ijB7HhQorTlfkutWLeL S8j5wbUo2zJ.tFpszt8q8MITOASB4CBPK57Ig0oBf.hnX2CV26DKtZclKqAj ZPovM1W55vwMadaq9DJB0AXNNH0Y2ZW2LA7pLmaW9x8tHse2gztcoEPPRS2O BGleYmGi5wgvwI6P7CX9V+fDzDOtLZgJhgHVzDy3ftIBLml.zVjSj0enLnZy cB4pPCMsVPmxrl5I+GlLhDJH+GBaLVcau6lcn5+dm68u+caH+h+yGP+JxWl5 KSaJy7kYe3C8fQpij+gMAzxPJOBgIfdbsbbnkKB+0WF2SQJ2rmMl3AyuFqBX Rah4mF.4Cx4pJ6iwkeP6LQO8yF0PPgn6bvVDj1uOJaYqstN6Z6S71E1xqcet Oaj9pM4TgAvBBUFI+.mLcDxP3lpbuQzaJWuIxNnEnD.PQ3ziH8.8SSO.ttsk 967E6W6XbgZtMqXusM0QLVIUPtiXtxPgjGYLkTaBkjDXmbLC7iV2j6QqKrWI Q6UReDeIgyDJP.RJgZngRBAVPAQILJPHBFE9UoThTDGaHwIDZiTBhSIwLYG6 QxixPKh+J7Wmhr3CIKIiIX9gxWjZjZBGJJwBkAjKQGsoFaSJRRbhgDGU5+Wi 3TZINZaRtQBfpe2.PE3nzXzzrN7PhSIzTSzj3DktwPCfHEjrgzUbAGXJhSNH XxIRLGfM+7DPVLuMxfQmiiOaAcTXbcRxRMnrvLVz2foZlLhWLplRh9qXE73T Sr4ASI+eLQbernk1c8kEvHscyDS5NuLsTt4MOpHF7i.OFoJ8sBTcQtOiaVuI ILELnzCRRbX.BHGXxFxA8nsQ6goQouM3QoBXeJ9Esm4QOyidlG8LO5XGXjXd SDXTRiwEUmiKdNt343hmiKdxwE2WFdio8FRT+JXaGgeNT.QhABE5CMz4QSMF 4TuwazkqG5w7Svz2D7GDS7IzJgsmQzO88W8RmQhmXlZo7MAP2raXFFelo9LS 8Yl5yL0+DhK5iK3CwgQp9hKdjafQ7SItXCac6mmi0tI5HwHhuWIyXPaeK7Zo e2FxGe2FZuOuvWuGGLkI9hHi3S7UQdz3yMYk19d8xjWvKU8PGwfH2FPzohYT HvxGoqfwNuHu7wGdUX.C0+PCn16DV0BU+HcTD4Gf1ZasKuDNuhcaU3Abhtmj 8y4q84r00.1lutI2hNm7lm.nopUvylui75WqnSpNAyqeVcJbnKlPk5Qhqech OsNOcJ5D4Qd3Q26gSw6ENsbSpRISBpTSpV8noKCfTloeNEIIfhLcQoXonT7W n2iFeGebQ7n+ngiHU3hSN9EMA+JXSu.skafiMLq47sFOYfvUmr5lf1JMSLEP JKWmXZIZRgPl33Zo563SlNISgUhM4rRI48HSLszij2PZ0zt3SlDWImN8J0yy K8BUJAiBgQY.E.mA6Z4gWQYwGPKV.+u1Hb0I60SJuM9DywlTJRxSYYq+h+8h +CX+n8SM -----------end_max5_patcher----------- </code></pre>
Lastly we need to dynamically add the text next to each cube, indicating the distance from that cube to its EN.
Here we need to make modifications to the rendering section of our previous patch:
Our metro needs to be replaced with a qmetro because we will be drawing the text in between the erasure and re-rendering of the GL context. Because we must execute all eight draw events between the erase and the render, Max needs to know to wait for these events before pushing ahead, which is the purpose of qmetro. You can think of it as a variable-speed metro that slows down to make sure that every event in its path takes place before it sends another “bang.”
We’ll add this send betw_e_b so we can get a “bang” in the moment right after the context is erased and right before it is re-rendered.
In this patch we use that bang to dump the dist2enemy table, using the index to set the y location of the text (assuring that the correct value will appear next to each cube), and drawing the text using a jit.gl.text2d object with @automatic set to 0 (so multiple drawing between renders in enabled):
Show Max Compressed Code<pre><code> ----------begin_max5_patcher---------- 1118.3oc0YtsaaiCDF9Z6mhAF8pEIFhTGnbupGPuceAJVXPKRmvtRjFhT0Is nu6KOXUaGK6nlXq3EHQJhhjZ32L7mCY943QSVndfqm.uG9JLZzOGOZjuHWAi 177nIUzGJJoZe0lTnpp3RyjaBuyvev3KulWvEemCl64vBp7NXA2rlyk.ulp4 .UxfZtjwqaaof4amZw2tEE2V3RkzHoUb+q9rpoVvqgOoJYsUP1TIjkbi2XP6 zJs3G9VgxmFsstpFSakaKcUMWaG.TiPImasZSXzGihsMDRItqQat.+Sainlh 6Ex6NVCRR8OfSbsw0jeMdr6xM8jpR9ZKHNDpdJNmOeQWTC+xnVzooVgpTUGF hQSyIIoHGJvoQyxc+AAQxRH2.ncny9ft0qDJx73Jdn2lL4T3DkmuEmHzrWEN OVPp4dgFr+3BRwLvUNXQo0HlBef1XTU1vhBHBnkkp0ZnpozHVUx80z1Lk0e. rZ5Z4z19tTH4EpFo+CD2gWB81Gamlh8rEkz2f68aQLJycKK5L6Nbjz6KrilE VXP0dP2IZwcf1nq.zR7Arww48FsDeUiCDFkEzOvmYzVTyoFN7HrRoENaFVpp CA7NpKbBzVcYFXeivJK+PmPO4PnO6sm4IQAw19y73YA8D+Wrk4N+v4UcotQV 3ntUm.CLdgnhVBqJoE1kX6YLc1aOdwanaTeoKhri63REPyZpV40JXBsgJK7T 9K+MXnKJ4cr5X5U.Hy8jDkj063zr.CIQAIhrKxpfVakA49rzzNM2kTswc2JU nEcSyjgjlGxEblGHyxNGX4X4ZYmUxbNHTGi+WXpV3+jw+qJuIbxYIwoivlRE k4BW5fL4CPjwQIi2lNEcvIddjDxUeF4R.mleHf7NHCY.hYhOIYtY6cgaEmmO LZlOeurzKAmt0M4B2k3B4sb10Rav8oYSbHsAbFxm1vqCNUbsldG+vD1ba6xs +pT61OhrlqUV1tHmTUaShv9fcLBerVXSn.0ICStZUnZmCl3AWRdP8FedCt74 TYGnQ.oK57B0uS+SnSxwniatmcJX6u8bpHJNnniuHJ5+kMTqqE5h+exbwP1o WFgpUzh+EVBK6BOW8IBDGM6LrT2wTo98tIuMZZNFdG1l0VXWkuypXcjTDhiu 5gVHkx3vVyO+ZSkk9ssf4Rd0icQngH+5ipOsq3TuTlBaOAQ14LO2d3gkyYTC cCk1foQS98dd2XailzVquBAV63bnSzzuyYyCmK2bpwTKVzXBmR8tcIuZA2iP zlle97XeSXldW4T2yXFrVUWx167A6xENDIBiOoK7ztNR3.8RO0Vn78f+LJdx +S.eO5JeeVpsithVan8LogsgCLt1Hj98EuSkH6Um6ELFWt6F.qDrUJ6pj5cC ONvw1WSJuGVjK6oAzjdxmqaaJNePsImH80lMQ5iqCOrXpOA3OgkW7vodYSCa Ht+ygdNahL71zywogMbpWdtANBuWy5FVOWBoubB8BsI6C+Z7+AL2mSwF -----------end_max5_patcher----------- </code></pre>









