< Back to IRCAM Forum

Maths question about circles

Hello,

I have what I hope is a trivial maths question… I am writing a spatialisation process with spat in max. I simply would like to have a source move smoothly between a randomly selected loudspeaker e.g. 1-6 at a certain speed.

The patch design simply outputs one of the 6 loudspeaker positions at random every time there is a bang, generated by a metro object. The speaker positions form a hexagon, at -30 30 90 150 -150 -90 degrees. I use a line object to make the source glide between speaker positions with a time interval related to the speed of the bang interval. Patch copied below.

The problem is that the line object and list of positions are only 1D and so the line moves only back and forth along the list of speaker positions i.e. it doesn’t always take the shortest path on the circle e.g. between speakers 4 and 5 at 150 and -150 degrees it goes anticlockwise 300 degrees rather than clockwise 60 degrees.

Is there an alternative paradigm to work in a more circular manner that would enable the system to always glide the shortest path between speakers? I’m hoping it’s a trivial problem and I’m just a little ignorant with my bad teenage maths knowledge.

It would be great to know an alternative paradigm that might work for larger speaker arrays, and eventually in 3D too.

Thanks!
Nick


----------begin_max5_patcher----------
3129.3oc6cs0iahjE94t+UfrxaqiScEnFo4gYlUZdYizpYk1UqRV0BaWs6JA
CV.NcmLZ9uu0E.CXvtvFncFMcR6KUATmy24RcphCm92u+tYKiegmNy4Gb9fy
c2862e2c5lTMbW92ua11fWVEFjpOrYqh2tkGkMatouL9KY51WrXQ1Sbmz38I
q3NOKBCch3egm3jkD7EdnyZQBeUV3WcVxydlyibR2wC9LOI0g3DDs1gN2QjY
NufvmC9ZpylXG0ULLNZiirghQLTDwWEuOROrj7Fi1uMdeVHOSSjf7VEq0jV7
xO8Vhew4uKHa0ShnMOnnGCmiYjEf4NTO8aPJP8lq7Um+2gquHp3xCUs8G2eu
5k4VBaa4ooAa3GAauy.XuSN.KkfEbty6xAlhlbOzT56B9lyaw.G4+Y.Eg57V
8KLI8tLHZSOvHXKXjaw4aNtrutia.nYyJQhVfOHxaAf4Ac8AlefR1f3hMfIS
Clnt.SzE.lQ7mkz6QXYpj1nK9hf+LOYVqLMtElF2MSOO+2Sw7HleEcGOW0qn
N41BTOUZSr9A43KuNODjkkHVtOyXHdWISqFujfs7LdxC7nfkgZBCn6SiXCDt
sqvV7soYIwK4yrVgAcYJLHl2BF.4iQ.LDQXLBddAPBgvEfp+P8NEfRpNJRwd
C.7QQnxITpHNpBOb2rfc6pz7cUNEEj8oX8ExedYShHSSvxlR3eQTb9zxVCRj
7ZljQ2mnQhYu3Rlc3xDulmDsWT5DQK7xIIsXJRJtkpwqLmrRZVz8AzS6cx3h
hnei3WwUkTGXSX7pOyWWwSnT.siGIh1kvSkNuCxxI7xtWyeLXeX1COFGkkJ9
ld3gRPus9eLm7ZsSECno8eJQDDVR8aRDqiiTDQMwfp4hgS5GgZ7XTkYzGQTv
tVNYi0SGclJYx8oKCRTRobKGTQmYwwg06p77B4Olk28NQTTCTLKdW2clH17z
IN2kwxN2dpqstmzG1GY58AoBQ1CJOE0OtfvvbC45W9WBhDaCx3YBiH.AJ6z3
83ozUIwgg03WSOeokdVKUvWweVrN6I8.UUYPd3hcEJQyJkxqEa3oY0aKKXSZ
8VRy9pAzqzz9k4FvOjw2tKTxE0O.oogHMK8o3mSyOvBEsp.vgHYpZPW0qXs1
Ok2wFyr7rPNnNnpc1p2wldHYUOitcR14Lq4yd5B0ywfZN4xw9CwEsalf3tho
GFX.YiTBcJ3.0Ab3cZ7XtMXhwMABqeiXAlflFLIyYoin+PB4jPhIpNmYBUrb
mUawagLLZBUOQJho9xoQF3.hLOJCTe+19y+3Y03pVB34bpLZLpFS9XbhzSn5
PbOCjYlAkZBV0D3+zAYmPY5agKhxdxA1a7zmM.lX4nBxDdg2DahoW2S+Yb+Q
PQpEvgxLKrwkcioxjJWkMn+vlc9eNKrfjdcj9abg50AgI2PtkEx+srafA2Av
fOIvnbHOu7MqzbvLnBhnHs+Yxsilinb+brOxFevYgGawCWhsyWMQpLhGcdi.
57i+n7MjZSnhb.N7vTtp4diTdzqKHvbKKJCXVdzsSDO+MmK.MPCldC3VSuII
HZc7VGR+AE3PAJ58BPor7cwb1T7zLmM1ycARhNXy9yM0SZWeyeqqyz+0TRtx
EURPPCXf8dMreNEXze2IDuqCLJ0L9y.XfwWqlAPy9t92ZXAn+XA7JUL7MtPe
cvhyEluC7T69BocHAwrJT+luagMjweJPuiLTKB8m75uuCH2Wy8cfditsCW1d
XA8Fr8vxfE4disYmGlp4oa+1t1a2RP+qbGggZ+Q4Ax.wvoMNur3MaB48lqQf
qxXydEGXtJCo30oQwodRQz18NnaHCzAj0Hz3iXXeSxJ.07sG13A9FvEhTxlD
6.AfKv3vh8hxR8.esYhK6lYsxeKbQHOp+SSMD2wDeiWByhBwd2LXhNEUTY8x
oVxbWAy3ay1yU7q8dPJRCAalTldieu.vfqW4g9Zdq.Noe0cb95d6VEBNiaUW
jIKD.fppAfagYRToOxO7wnOFY1moOFsRknGOKR4eLJHJST90pmcsTAi1W3x6
LnEAfNFs7tIl2MTjl4D+XQtM4rKNUnRYgzdqyfcOCJff3JyEO45L5qZ+Wfr2
UumiD1Bl4GWeOBi4yJtsF3xW6FBph1EBxpI8gldiVye4FAut1H2I3EjIBsPu
9nE652Qa2oS8B+pCXDv0odQYnICsFxsuwvo81mLAN6bICi+w3gGAaKf.uVuS
GxgQ0TvcjYZZBW0e6HkI4vyUAJRfJm5T8ZdZlHpLkN+vg6nj5.sRRcQTAzBp
PEj93QEDKoBUJwnNvwiJrQh.GUr.aIULlPgFmshHviHT36aq.gLlXgsJmE5O
iGUzG2EUNvsh06hkySm64J+Fg3RLocoKQmsO09Fwr0+Dfd6Fzear3Krsl9fw
TFqnBjsTwnhEVIioiIU.5CULVRjBV77RjwzpSkhK1QEioevVLo6PhfFQpfZ8
DSGGYSbxZySzC7Ulz5lx.iBkQrchT5Xp.Q7tEnBrsRIxjKlrlzzgACmRcaL7
1E0f2rnFxV6Nxj6rRSZ1DqAdLMFsFfZQHOxpUHlkgDhGyUFqxpDqmSAMRDAz
6VXIoPa2j.7XFiNz1UC5O4NBslzvfI2aCnOqgdzzfH8I1wwRCB0qsbCNo977
5yTojIUCx5cgwaLCdzV83B+1iCUXsXZL2m.rsRDzjGbi0jFzepMwv1FwSQnQ
iyRwrUO1eT2jYaiNt6HrxarnpWXacPoWUbfMgwKCBaTl.ZqfDb4ERktplO.q
KcJvKrV6forEHrKzkhcITeLFRTOKptsmj5Weo1oKNkB5AudgkIFUJ3enLwPK
el+GC9riRiSXbv5pEVoyxq9cxp0xdQqKiR4U9A+yTVgFNN9ckOXAVHX6jYqd
+8aMyQvnFhVl+nIZq9ro0dhyUKwBIGpTXclmxV7.AXEammn6Gmrgil7cWvmU
OPzVKiQCYMdB6mWheH8oFOMj9sdCz4M1qfifCHySLYkNlcZY8P58RM2ts58P
1rqR2tcd17DtPNi9MdDpndPUwx6MP6clQGPYM0jWjL3HHq6m6LHb7bmc7DzT
1X4Na+VdzdqqpetWDSWMow6ePX4Oe9.fck.PQFea98Ve1uoSnW03NW8xubHQ
dya4mpkdulnnGH6kS9fMcdylKzpAi7WPcYDluKyiICfEwjXmIKya4oZ55Map
8jKYgm+KVAp+E9v7GV+idlk51nQeD0yqLCFzbIc4HwwasVsaTdWqiqxsR3Hz
11Qx2lAp1tleXI83qZjabUGQdDYy.gFfAhZ6.AuxAx01ABckCDDZ6HgOV+.d
c5G1H1PCgXCZCb5NQFaMHlFo4ED6tf1bQnPpIsYc8W3czzdp9FZQiM7As+rA
v7ryhkuczTOp9NlMPWmb2FMLHbpD7ndiXHDxrjE1BRs37pM2b8sf8xQKaLGI
Cg4nMiDr8ojtNVDY0HyFhojH15b6Zmp.YkazgPIGxrA8nGMRlnkZTxmUCRiR
8bix77wk34tKuyMKsy5M31ToaaDg1gBj790h3+ktLE+v6KWaSQwTtNTrbyih
vvUwgwGUgqKh9blo2xpIcwwppWzHFAB8UEMZLD6gb0eR9AJs5cSwbNvhShPI
xPUUGJwE4Qn5O4ivTrt5S23zPGFK.jYFA.yGPLeR1jxAb0SSt3x7xxrWkZK7
tj3cwIk0m5EXV4wuWFBeRvZQ9ShQ85f97bMoDYuMKvvy1JATQw4TUyqTX72M
ntCD9ywgqc9mwp35EmRjTsRYqJKCKJ04FHR48j+QeG+4G5p3x8g7JwsihuZr
1DyiFZM8jtkcfE9zgmCu.jF78ImVrY4ChzbVsdKJH6e3fwrUdLJslZ2A.1yk
3owCrOQGqmzAPCi3Kz12ZYwE4wXLbL79fW7rQY8uv8gA2+zxk1auvr1b4uDO
Ci34yogBY.O+GUzPmRNUgiz6oWsWFHmrla9wOGtmeZerAqVIGfZXLFpDlJj0
sLZGVt7cnIveMgyi5MEp+S8AEq9Q8I4xyjAiM7D2uwW2aRyqT8GRnRUTcXgx
3C0Kmdfou+KOLL94dSh9HJTKd87g9ZaV.kQUwx1bF1JS9hTGD.3OTLf9907q
xfR5OBK0DAZW.TFBR0bBrpKfAg.2EDwC+2h3xGC6QYMHpkaPXZNf4B77MKmP
pLqWXA5RVEB765UgXVUZG+U+49+39+Oft3Joz
-----------end_max5_patcher-----------

Hi Nick,

Just some hints (I haven’t tried to actually implement it) :
you want to use the shortest path (i.e. shortest arc length). So, at some point, you need a “shortest path”-aware line.
For that, you need to keep track of the last output value from line. Compare that last value to the next (target) azimuth.
If difference is greater than 180, you need to modulo (%360) the start/end azimuths of the line.
(NB : incidentally, you could also adapt the duration of the line so that the trajectory has a constant angular speed)

I believe you can keep your p speaker-strobe unchanged; just modify the line part of your patcher.

Even though the underlying math is rather simple, you might want to opt for a js implementation, for the sake of readibility/maintenance ?

Extension to 3D is a little more complex, as you need to use the great-circle distance.

Hope this helps,
T.

Thanks T,

I think I understand the principle but not the next step. If I modulo 360 the start/end points when the difference between the last and next value is greater than 180 then I’ll still just get the same values from before, -150 to 150, as they’re all less than 360. Did I misunderstand the hint?

Are you saying that whenever the difference is greater than 180 the points should be transformed e.g. -150 to 150 becomes 210 to 150, 150 to -90 becomes 150 to 270 etc? This seems to be a solution but I’m not sure how to implement it in max.

I know I could rewrite the speaker points as positive integers, 30 90 150 210 270 330 but then I’d have the same problem with the source never moving over 0 degrees.

Or, is there a way to move a source by instruction e.g. move 210 degrees clockwise? This could bypass the problem because I wouldn’t need to reconcile absolute positions within a circle.

I made a workaround that makes the previous patch take the shortest route from speakers 4 to 5, but then it’s v inelegant to apply this to the other affected paths (3-5, 5-3, 5-4, 4-6, 6-4), and besides I’d like to work it out so that it can be used more flexibly for different speaker layouts, not just this hexagon.

I don’t know js yet…

Thanks again!
Nick

I have found a workaround for the specific hexagon layout where I just substitute different values whenever the difference between the last two positions exceeds 180, as as hinted at in T’s suggestion, patch below (a little messy). Now the source takes the shortest path between positions.

It would be cool to know if there is a more flexible or smarter way to implement this so that it would work with any number of speakers and not rely on the workaround hand-written for the hexagon layout. I don’t know which bit of circle geometry I’d have to study to work it out myself, I’m no engineer :frowning:

Cheers
Nick


----------begin_max5_patcher----------
4376.3oc6cz0aiia74r+JTC19RahC+Tj7.tBbsEnuzBTzBzhhcKBjiUxpaUj
Lrj2r2Vz+6kTTxVxVRdrMobxhl6VmXQIw4aNyvgj+m2c00yy+Zbw0A+PvGBt
5p+y6t5ppKYtvU0e+pqeN5qOjFUTcaW+bbQQzSwWeissx3uVVc82iuI38jf2
SaZIa8y4qKSiKqdNb8UsWp7WVFa6zquN3eW2zxnxG9TR1S2uJ9gRaqDkbF5l
.AlZ9EWY9jPlg17LIKp5774+7sXQ6tNIqomIlq8ee26LebCPjLK9E8qbObbc
1xnG9b+HHYHDLIq75ar+B.pFR4leIEiip3dQUr6PUChFjX9OOvOCELyuvb1n
XYnpWrj5Nr72FfORz6vrQwLEhHoDDESXJEipEbYnJDUMiOB5xj9V9s3kDM.6
VFZenqpRFlQFk6xDNi6Vl+zSowSAmjYQMBq4y9QMd+pma5rUQOGWFu593rn4
oU.Dxcb4n4ESBofX4uxw4xHeao52EfknIAgYgFTkN9nPLru0hucJPVp0R8gL
YQdSOjKBWYmxxWYiOjKULUC45T6y0nHtRn0hnChhDuO.T4XtTPAvNgvUsVjn
TKliFGkUtiqt944wqNRIUCBMOJ6IHXDQUYvkONFQQWxwdp3Qt05jUBlJv.rG
Qcmw2ghyAyQA2p+nogzjr3GxWmU1lO6BUWI2xtoxsbcSvA8KG6cCw9v5jDUg
a5gbfXcB88f0IoM9NFlCv5D9sf0oZLhJBAXcBG98k0II256PcjriacBy7d.d
qmWTlTttLtxFU.AiNAV9nXLVnQxPESICUBENLjn1DfKFiGk6ilTBfRi+Bmi+
b4vnOZz7YnTNC6eH+4mi2JLuMz.CS+2n48yXA+ng6+wrOlYHD5qQMWQTckdG
6h0KgBMBkPUwsCUg1j4TQCDCDSrh6LSYOllqeG9vTVchKBCoCXJ6w7UOGUcy
g8fhzKosse0cAzPzriz9llVFUBhlXC6c7b5HcmDt+YxHwovjExKIS9NStN7F
Ola83b7Db3+rr697WEFhaICOdFqDDeGmuGvOqkXFD7Kj+FvmxZDhijG1mxP1
znQ5OjsV5bPCRsQ1KZz89HUqMxtB.IWkG5LaOyWWVlmcj3BfXgrSrUHeKxX9
rWjYZbWvOHpPpfinj2xHJ6H3n32vHZn5H3nWTqPkAyClejFhqP+afqASH17s
Mp6tLkucUvqnZsNLLTU71FUYGAWk+lFUq0iggpr21nJ+H3ptqhY7j8WN7AZX
Si82glBjaUHWNK.BsGflzlp.LCOTo2mfGGib7ZrBBxodk6daHBtOBCMe4eG3
iPMY.jcGp6FMYjYjzoRrniPcj3c0wacL5UGscM5Qoix779TN9q8QD0VLrNad
rQwPGVxGCMmDza4A2cWfBETlamUpMeqZBJ32RMWopE80TUsqaw9EyzUvtMzb
s5a3V6cT+spYzH7VV0qv9Vq6BcK0ey9N3seG02SyKwBGr1vQyaA27sdmzDYC
aXUbgF4iJSxytuycfO54UQRr4CxN0hXI2N0ZCLwJD2UfcCNqRTTf9+0T2lhe
HXPW..fW1eUOeQFan8WJG910za8iZW87fOtcS1jTJC9op4ZvyZCKiO9f2kMK
+TbPQ95UODG7RRZZPV9KAQouD8KEAkqh9RbZP0c7o7UkwEkAZ74SGQk6fNXo
rKCQsjlMCmzK+V5cu.tyREtylmZsXbvcEKii9b7plKEt8RE2E8sf9UquIv5G
D3YH9zFF1L3jRfCkH6OXrYYAPstWxr1IFfVF58hHPCu7YeII9kgR3OczxG3F
XqBBIoxMRwnk8Da7rDWnEwWbu9F0u76iJKWkn872tfdtZCROh21VJlqJQrfZ
wqaKJWkOO16Kz.BmtorSZ+CWLBAseWVYs6ZMaeGB3iIoweQq2nGduENb00QK
W15xW05QLjreNeUKmDLWJIydI7lKsJ9KIMOOeyUiVoI.kZre8pJxy0ecyzbY
dM4KhWksNYiMjJlWMHUwlxzrasX7C1G1vMaZt8r91pnUjVkNIVrkroECdJM+
gOGunksPMiaYbVRVaOd5z7h3GiVmVd+i4YkEIeqBBvFWQ6o8GqgvdazfCUf+
OsJIJcCB7zpjE4YFfnCmvb4lt6CA1xqCyaiLU2QVzxddXqBz.MVnQx0EyiVY
XT0JOjlFKyyS61zlmKM9wx5lWljksCUrLe4vMtJ4oOMxyNOW23yi8tqZo390
Y1VuWKSTduwXQ26KJMsVWt6q+qQYIOGUFWlXYADzlFsFP9TwCqxSS6fu1V9R
OsrPKi+P7KIKzC9Z5n1BC5aOYYiPz0a3xKRdROdc2qUF8TQ2qTT9KVhdqKsd
dsN78kwOuLUiEcuAs1QRQo1ifWJpuwFAs1DfsKJx15zsML145iYfru0fU.oc
i8Zf7.FIGr97rp0MAAtWxI1qpk1AP1YkXscLhqZFgvwDjmzbnwHGjQIG2.gj
XsFPnCrrz1ijHFjlPlFZhI8UImHIoIMVs8ieXgEgw8cFefE6ydTF1fTFrCoL
cJ9qSQjnSJ7FD4sUsIenp8q+hAavp9aPmzNfGXdWX5aoyxJ+zlU5peTwpok1
Tht+RoZvJEzypXsKZGuIHwU0wsnFQPpMxKesKxTniaFcl1eNHYiXJkZ8HUXl
MeBGjrwt7lkMKPj4CSXniQX5tPQ.IYQsSMF2VRerCKYQmD6yiPh1tDKNVOaf
LdUC8HjAa7JI5RKxj7Xv6SvA+3Op+EwjKpr.TPbZQr4x9xGvZMKtpN2TGziG
A+RSm9sA3IPtAATtQPtzziUQYKxeNf4ehBSh5eyUYOhB96nwrMoomvGYYqMX
4ZdYGzta5e6Jy3sXJYDrkXQEvzeXSi6ciQL7lw0MRNfIFhueIFLsC+FzODX.
jT5EmVf7lfQc8TBlVfuzCxT4le.drruvf3p+t+FfNT8j+ZW2QGz0exv1SXu4
x6.2EocfD9ZOFxoJGVMy7p.VlGvhIIDowr.MZ8T39DBikspKALEePJjbRrK0
YS6xG92ZELv0hD6sicMXgzbY0n5VnCir+sMb4JLXA3XqvXrcgZS2s7a1ifbw
SlflNuJO.iPmpxwQXOFKsaMgGLLH7EOMTeKcVZblWSmqzZkvFTH8fFUIW7YL
opHUL08xXgLy.jdtl+A2BSc4bfObLjjgsrx+9Yt.3G2TAPmlbzMpc0kwwKNY
ypgDawFfPCTWi6uOnLIFVGCiMUPxOXpKVadl9X1ClB83kjh3OlEkUlr4qse5
NECF+TIWLDYexkXjAlEWbpUZRQYP9iMk2Tvx7hDSIKTbxxLDLs0Xw.jYngSB
Un5s5QexXpYJ6OgRASojplo0ft4yAIACKHzlZ2vHaWzGUuorEwe80D8BvjpR
mwNYpkzMTKxaHoKZ34HdobCAi9VQ7hqHmN0hgbC0xkouwRBNYaxXtbe5gvVl
6.HHXPgOdRVm1VCilgfGnxzpvHS68SorkGdsrQcgeEzEaVDWTljsohN+vVDy
bifXTGKPXDi.AElZlvaPAEJsfn7ITHABElDznCzo8MluZgsnkQWVPyDH3N23
FPC6GPS.EzP9j2AUN1j2VuAEDvRPBeBEf4HFvkMkBKfAMybcOspXlzJABzLU
mpAz7CABpbbC35GZAT43dT67rDDXPSpFFz7jDjXOY1QnZ9RBBKNlQw7lMnPn
ZS56i3KfPAkg3SWrHPctoAJlNIVRM0+vfF80.AhM8N2fOlgRwuJAM1jaHrQZ
40HUi9pkpwfZ3l6SkQl50.TvoGwvGSJWBNjM4FqDPsHXptVuw5Zd4G1AMeJ.
YJnZXPgO8iVB0a9Jv0WdDJoGCTf7IT.wWCIx2PAFJT3MNB6XBCt6M9bxhk4I
Yk0YgrtZGCY10VYHqZI8z4a0GNFr5ihJd0T84O7BB0U4UsN4wDCs23wPGHU4
S6fpiYfTeQJTrWCgjpfJbJ8Js.ZRBHdkVHNRCP8NoHuq8FeAzsBkiZGG3oz7
4Qo6rMAz2FRvouWpLz94iS2z6nb0LBMDGxoZayRJEyzRADHGoZgdeG9iibKt
JUs1oXznFVA4z206GfZo4QKZu0J4pMky91Ikv1E0znGDDReuAqcW.wwawZLJ
oKqsdC.5.rV2wY81Y.w9XFjC6QB6RtGqtLx4GHfX6ZQr9TVd7SGO+ejGVMfl
ONOO6aurRvj.NQ.c2Ih9g1G4vlsHt2i89d3kvdT2qF+jii+FPGduAdH1c1fC
cjHNI5vqeNNa8ocxVdv8yt98tf0tpX6h8kwOWG930+sp5O0zE2X93OrstSqu
xO0oZT68Lw4xtYneDaNpmnCMjdNxAE7AVMOcVyxNSqoyh0wqG730JM6udc5X
6+rX4UuwtkRkkFraXL0Th8miytEZwPQSRaUkE6QuA2Wcmnkg5qcfnto58z67
tyM1ncN14cd2R6Yn3TIaiV9L6JLjt5b4mDBDJJSzOEE4+9Vo5WRhLAnMh4Eo
XAERmqbg1ZHHEFA0ERRLHcUXqJb3LnfX.5G19B6j9BFdc1rKl.D6B6h9pa4f
L3fFXWPC6VYEi1Wm+.THPiQnbFM7vVOI9v5IlwA04RmHXJAOLwY2WHF395bM
jnTSVWAzwIFo+gbNWYEXcN2IxJvbo.4j9BjxNyEFVfgVTWfVvLggC8gnBkbA
6a0ErukWt9FigEWCxEiEiYf6qye7QXiE6jXlvf7mo8jbel8EATec1zvcD4Fp
ubg+LRHhgJWDrf.h1lzE3DnfsDtvIIH5U6.MNJZ1PHpYBxDgi9I2OgP71kGN
Q33NPiiFGfCQUOzEVU.kwvPm3KCjdh5CIFPdS3kdlApmch9HjA8bhOofRMg6
5I7jP83SFehCAmbxnPPLe4tdZZ3SPhdkpbUOMI5ST9ToOQAI64BpGGhuVLmz
SPhR0IoihCQ1yIINgCwKNlKF8GTVSbRRS.kMA+L5O5h0yfFozERLfT2bP7tT
.FPbRrtfRChSRRIn7g5kb8.IBJWPLAkOqtpm6rXJBwy36UJmBg8XVWMi0opV
EsNo9bFsBVtHmHhE+XoU1sTYJUNCsa8xDRm47r..hgGdzLbjc+5MTNSrWQUY
Zy4SONnffmJa.UY8m57jY.smO2YchCsiN2gHHP6ny12EPzN5DYSfMv7APOOI
S9ogi1JIamCAVSmryg+5NG7q6enuN7A95tG1qUq2E6Ae4NUu11yK00KRx+6U
mZo2+W1T1mMmspcIEye5wjzzGxSy26LusoR9t115lyW1l68CAnYDECikZxxL
JlJHgU+k9O371qxH6yfadHFmoPDysxBIBFu5ujDJmZ9KzNOFYaegvJaOfTRD
y9W5KYLZ19whxdp9TZUz5nFc4p7k4q1bb0Nip1b+qKyeZUzhj5MlstmLx2TK
IsR25tm2nW+rlflz7Lsk71vL9iVpd.F+6ySWD7WyM0HYxXrj1Gbtlsu8Yaj4
bDn7WX+4C0+MOyGpO8cCL.+NEyoc6fsivvvLHzLIeyiOEXHTJ8jhoHefoMKv
E333VzCh5+FUi90lohPlnBuoRVkWJZs4czHOQEYvz7SR8u6xGr8wQ8GZE7k+
kUi9p.hv5+mU4FCx+774+e8E2nurUuP4L0hOWjlnc34eZ7FZL9TKbsZMPz4C
GAK10E1uOcc731Xid3AcGzg5SwF1rglGtwaGUMm20.3eZUbb1QCgHCHwoleL
+kNHTsyXtG39awKNZPSrQw.y3Zg2J2B09GZBj20v2+JNMM+kiFDkDNth8JjX
Yk1Lhq3FeYaoas6fGDyMgPRWg.UKks+j1ekimBqkDQUFG3JBlWgI31FGbB.t
LJKN8ejjuYWY1KwfXB2fopv.UHRHsgSnElqBrfbJQgfeSGEhMpzpEukgUTrr
1slp03069uu6+A.ZbI+C
-----------end_max5_patcher-----------

Here is a quick and dirty example using javascript.
Could definitely be improved.

(should work with arbitrary number of speakers…)

Hope this helps,
T.

strobe-example.maxpat (11.2 KB) strobe.js (2.1 KB)

Thanks T,

When I try to download the js file I get taken to the following error page:

The change you wanted was rejected.
Maybe you tried to change something you didn’t have access to.

It doesn’t work if I try to save the linked address too.

Some kind of problem with sharing js files over the forum?

Hi Thibaut,

there’s really a trouble for downloading the script…

I’m thrilling, waiting for fix !

@both : Really interesting topic ! :slight_smile:

Let’s give it another try :

1 Like

Thank you very much !!!

Nice work

thanks T. I can see that js is easier to use for these kinds of problems.

Am I correct in thinking that your script can only work with the lists always read in sequence (normal or reverse) / only in one direction, it can’t change direction itself?

I’m trying to work out just with Max a more universal approach for a list of n positions in any sequence/ at random, but I don’t feel like I have the chops to conceptualise the problem and solution properly. So far, I think if I still want to use a Line as the core object like above then it comes down to making a patch that can switch between giving the next value as either positive or negative to get the shortest path depending the last value and the difference with the next. I think this means a patch has to incorporate the below 8 possible operations to fully cover all the possibilities:

  1. next value is positive when last value was positive to move clockwise (0-360)
  2. nv is + when lv was + to move anticlockwise
  3. nv is + when lv was - to move clockwise
  4. nv is + when lv was - to move anticlockwise
  5. nv is - when lv was + to move clockwise
  6. nv is - when lv was + to move anticlockwise
  7. nv is - when lv was - to move clockwise
  8. nv is - when lv was - to move anticlockwise

There is some redundancy to account for all the possible outcomes. Maybe this is overthinking it, or not the right way, but I’ll try more this week to make something that works.

I’d be grateful if anyone has some tips or can just magic up the solution, if it’s a trivial maths problem.

Am I correct in thinking that your script can only work with the lists always read in sequence (normal or reverse) / only in one direction, it can’t change direction itself?

Yes. The js script was not intended to be a generic solution; it just implements clockwise/anticlockwise rotations.
But feel free to use it as a starting point, and adapt it to your needs and more complex scenarios.

(I’m not a big fan of js, but usually a few lines of code can convey your intent / logic more expressively than a patcher)