{
 "blyg": "0.4",
 "id": "342e0cy8zcd58rhkp0q3aja6yv",
 "kind": "thread",
 "origin": "https://notionparallax.co.uk/",
 "page": "https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux",
 "author": {
  "name": "Ben Doherty",
  "url": "https://notionparallax.co.uk/"
 },
 "created": "2016-01-06T21:15:35Z",
 "updated": "2016-01-06T21:15:35Z",
 "version": 1,
 "content_md": "# Centroid of points on the surface of a sphere: redux\n\n\n<style type=\"text/css\">\n  iframe.world{\n    width:100%;\n    height:50vh;\n  }\n  h1,h2,h3{\n    clear:both;\n  }\n  .scruffy{\n    width:65%;\n  }\n  .alignright {\n    float: right;\n  }\n</style>\n\nImagine you are an international sort of person. All your friends are international sorts too. Where should you all fly your private helicopters to for a party?\n\n<iframe class=\"world\" src=\"https://notionparallax.github.io/whereToMeet/sphere.html\" >\nThere really should be an iframe here :(\n</iframe>\n\nThis problem comes up whenever someone is planning a conference or a wedding or anything that needs global travel.\n\nIt's a bit of a toy problem because it doesn't take into account transport methods. It's a lot easier for me to meet a South African and an Argentinian in Dubai than it is to meet in Antarctica, even though that [minimises travel distance](http://bit.ly/2l4By3G). Ignoring the realities of planes, how _do_ you work it out?\n\nBack in 2009 I published a post called [centroid of points on the surface of a sphere](https://notionparallax.co.uk/2009/centroid-of-points-on-the-surface-of-a-sphere). Then in 2012 I did another one where I looked at [which posts get visited the most](https://notionparallax.co.uk/2012/post-popularity). Turns out that something like 6 times as many people want to look at that post than the next most popular one. This problem consumed me for ages in 2009! I dismissed the most obvious solution (vectors) because I spotted a degenerate solution. What if the points were evenly spaced? [Antonia J. Jones](http://users.cs.cf.ac.uk/O.F.Rana/Antonia.J.Jones/)[^1] pointed out that this was a problem in all situations, not a solution specific one.\n\n# General solution\n\nIt's the vectors stupid. If you assume that the world is spherical[^2] then 2 points on the  surface make a pie segment shape, [a sector ⌔](https://en.wikipedia.org/wiki/Circular_sector). The midpoint of the curved bit of the sector is the midpoint between those two points. You can either do that by measuring the arc, or by bisecting the angle.\n\nThe angle bisection is really just the average of the two vectors. The neat thing is that you don't need to do anything magic when you get 3 points, or 100 points. Vector averages will still give you the right answer.\n\nSome js that I wrote to do the job (which I thought about for almost exactly no seconds) looks like this:\n\n```js\nfunction meanVector(people) {\n    let xTotal = 0;\n    let yTotal = 0;\n    let zTotal = 0;\n    let n = people.length;\n\n    for (let p of people) {\n        xTotal += p.vector.x;\n        yTotal += p.vector.y;\n        zTotal += p.vector.z;\n    }\n\n    return new THREE.Vector3(xTotal / n, yTotal / n, zTotal / n);\n}\n```\n\n## Degenerate cases\n\n### Opposites\n\n<a href=\"https://en.wikipedia.org/wiki/Antipodal_point\"><img class=\"alignright\" src=\"https://notionparallax.co.uk/assets/Digon_on_circle.png\" alt=\"\" width=\"240\" /></a>If you have two points that are exactly opposite each other then there is no answer. The two vectors resolve to [the centre of the earth](https://en.wikipedia.org/wiki/Journey_to_the_Center_of_the_Earth)!\n\n### Equal spacing\n\n<a href=\"http://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere\"><img class=\"alignright\" src=\"https://notionparallax.co.uk/assets/NsCif.png\" alt=\"\" width=\"240\" /></a>The points don't need to be opposite. If the points are evenly spaced on the sphere then it'll fail too. This could be even spacing along a great circle, e.g. at exactly a quarter apart. In fact, direct opposites is a subset of this when they are exactly 1/2 apart.\n\nIt could also be some kind of magnetic repulsions spacing over the whole surface. They are an equal distance from each other, but in 3 dimensions. (See [here](http://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere) and [here](http://web.archive.org/web/20120421191837/http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere))\n\n# Three.js implementation\n\nGo on, click the world and drag it about!\n\n<iframe class=\"world\" src=\"https://notionparallax.github.io/whereToMeet/sphere.html\">\nThere really should be an iframe here :(\n</iframe>\n\nWhile I'm a free agent[^3] I don't have access to any of the tools that I'm accustomed to having (Grasshopper etc.) so I thought I'd have a crack at doing it in something more universally accessible. [Three.js](http://threejs.org/) lets you do 3d geometry stuff in your browser[^4].\n\nIt shows 12 people, randomly spaced all over the globe. The orange spike (which you might need to hunt for a bit) shows the centroid of those points. If the iframe is annoying, you can [see it full screen here](https://notionparallax.github.io/whereToMeet/sphere.html).\n\nI might add a bit more UI to it soon to pick cities etc. so that you can use it to pick the positions of your own friends. In the meantime, [this does almost exactly that](http://www.geomidpoint.com/)!\n\n[^1]: Sadly, [here's her obituary](http://www.legacy.com/obituaries/staugustine/obituary.aspx?n=antonia-j-jones&pid=150288587).\n[^2]: It's [not spherical](https://en.wikipedia.org/wiki/Figure_of_the_Earth), it's an <a class=\"mw-redirect\" title=\"Oblate spheroid\" href=\"https://en.wikipedia.org/wiki/Oblate_spheroid\">oblate spheroid</a>, but let's not let that get in the way. I'm sure if you were even moderately good at maths that you could correct for that. (I'm not.)\n[^3]: where free agent == willingly unemployed.\n[^4]: There is some slightly strange stuff to get it going, but I found it surprisingly easy to pick up. The model above took me about 3 hours with no prior experience.[Alexandra Etienne](http://twitter.com/andraconnect) and [Jerome Etienne](http://twitter.com/jerome_etienne) have a super cool tutorial on [how to make a planet](http://learningthreejs.com/blog/2013/09/16/how-to-make-the-earth-in-webgl/) which helped a lot.\n",
 "content_html": "<h1>Centroid of points on the surface of a sphere: redux</h1>\n<style type=\"text/css\">\n  iframe.world{\n    width:100%;\n    height:50vh;\n  }\n  h1,h2,h3{\n    clear:both;\n  }\n  .scruffy{\n    width:65%;\n  }\n  .alignright {\n    float: right;\n  }\n</style>\n\n<p>Imagine you are an international sort of person. All your friends are international sorts too. Where should you all fly your private helicopters to for a party?</p>\n\n<iframe class=\"world\" src=\"https://notionparallax.github.io/whereToMeet/sphere.html\">\n  <p>There really should be an iframe here :(</p>\n</iframe>\n\n<p>This problem comes up whenever someone is planning a conference or a wedding or anything that needs global travel.</p>\n\n<p>It’s a bit of a toy problem because it doesn’t take into account transport methods. It’s a lot easier for me to meet a South African and an Argentinian in Dubai than it is to meet in Antarctica, even though that <a href=\"http://bit.ly/2l4By3G\">minimises travel distance</a>. Ignoring the realities of planes, how <em>do</em> you work it out?</p>\n\n<p>Back in 2009 I published a post called <a href=\"https://notionparallax.co.uk/2009/centroid-of-points-on-the-surface-of-a-sphere\">centroid of points on the surface of a sphere</a>. Then in 2012 I did another one where I looked at <a href=\"https://notionparallax.co.uk/2012/post-popularity\">which posts get visited the most</a>. Turns out that something like 6 times as many people want to look at that post than the next most popular one. This problem consumed me for ages in 2009! I dismissed the most obvious solution (vectors) because I spotted a degenerate solution. What if the points were evenly spaced? <a href=\"http://users.cs.cf.ac.uk/O.F.Rana/Antonia.J.Jones/\">Antonia J. Jones</a><sup id=\"fnref:1\" role=\"doc-noteref\"><a href=\"https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux#fn:1\" class=\"footnote\" rel=\"footnote\">1</a></sup> pointed out that this was a problem in all situations, not a solution specific one.</p>\n\n<h1 id=\"general-solution\">General solution</h1>\n\n<p>It’s the vectors stupid. If you assume that the world is spherical<sup id=\"fnref:2\" role=\"doc-noteref\"><a href=\"https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux#fn:2\" class=\"footnote\" rel=\"footnote\">2</a></sup> then 2 points on the  surface make a pie segment shape, <a href=\"https://en.wikipedia.org/wiki/Circular_sector\">a sector ⌔</a>. The midpoint of the curved bit of the sector is the midpoint between those two points. You can either do that by measuring the arc, or by bisecting the angle.</p>\n\n<p>The angle bisection is really just the average of the two vectors. The neat thing is that you don’t need to do anything magic when you get 3 points, or 100 points. Vector averages will still give you the right answer.</p>\n\n<p>Some js that I wrote to do the job (which I thought about for almost exactly no seconds) looks like this:</p>\n\n<div class=\"language-js highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">function</span> <span class=\"nx\">meanVector</span><span class=\"p\">(</span><span class=\"nx\">people</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"kd\">let</span> <span class=\"nx\">xTotal</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"p\">;</span>\n    <span class=\"kd\">let</span> <span class=\"nx\">yTotal</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"p\">;</span>\n    <span class=\"kd\">let</span> <span class=\"nx\">zTotal</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"p\">;</span>\n    <span class=\"kd\">let</span> <span class=\"nx\">n</span> <span class=\"o\">=</span> <span class=\"nx\">people</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">;</span>\n\n    <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kd\">let</span> <span class=\"nx\">p</span> <span class=\"k\">of</span> <span class=\"nx\">people</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"nx\">xTotal</span> <span class=\"o\">+=</span> <span class=\"nx\">p</span><span class=\"p\">.</span><span class=\"nx\">vector</span><span class=\"p\">.</span><span class=\"nx\">x</span><span class=\"p\">;</span>\n        <span class=\"nx\">yTotal</span> <span class=\"o\">+=</span> <span class=\"nx\">p</span><span class=\"p\">.</span><span class=\"nx\">vector</span><span class=\"p\">.</span><span class=\"nx\">y</span><span class=\"p\">;</span>\n        <span class=\"nx\">zTotal</span> <span class=\"o\">+=</span> <span class=\"nx\">p</span><span class=\"p\">.</span><span class=\"nx\">vector</span><span class=\"p\">.</span><span class=\"nx\">z</span><span class=\"p\">;</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"k\">return</span> <span class=\"k\">new</span> <span class=\"nx\">THREE</span><span class=\"p\">.</span><span class=\"nx\">Vector3</span><span class=\"p\">(</span><span class=\"nx\">xTotal</span> <span class=\"o\">/</span> <span class=\"nx\">n</span><span class=\"p\">,</span> <span class=\"nx\">yTotal</span> <span class=\"o\">/</span> <span class=\"nx\">n</span><span class=\"p\">,</span> <span class=\"nx\">zTotal</span> <span class=\"o\">/</span> <span class=\"nx\">n</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"degenerate-cases\">Degenerate cases</h2>\n\n<h3 id=\"opposites\">Opposites</h3>\n\n<p><a href=\"https://en.wikipedia.org/wiki/Antipodal_point\"><img class=\"alignright\" src=\"https://notionparallax.co.uk/assets/Digon_on_circle.png\" alt=\"\" width=\"240\" /></a>If you have two points that are exactly opposite each other then there is no answer. The two vectors resolve to <a href=\"https://en.wikipedia.org/wiki/Journey_to_the_Center_of_the_Earth\">the centre of the earth</a>!</p>\n\n<h3 id=\"equal-spacing\">Equal spacing</h3>\n\n<p><a href=\"http://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere\"><img class=\"alignright\" src=\"https://notionparallax.co.uk/assets/NsCif.png\" alt=\"\" width=\"240\" /></a>The points don’t need to be opposite. If the points are evenly spaced on the sphere then it’ll fail too. This could be even spacing along a great circle, e.g. at exactly a quarter apart. In fact, direct opposites is a subset of this when they are exactly 1/2 apart.</p>\n\n<p>It could also be some kind of magnetic repulsions spacing over the whole surface. They are an equal distance from each other, but in 3 dimensions. (See <a href=\"http://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere\">here</a> and <a href=\"http://web.archive.org/web/20120421191837/http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere\">here</a>)</p>\n\n<h1 id=\"threejs-implementation\">Three.js implementation</h1>\n\n<p>Go on, click the world and drag it about!</p>\n\n<iframe class=\"world\" src=\"https://notionparallax.github.io/whereToMeet/sphere.html\">\n  <p>There really should be an iframe here :(</p>\n</iframe>\n\n<p>While I’m a free agent<sup id=\"fnref:3\" role=\"doc-noteref\"><a href=\"https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux#fn:3\" class=\"footnote\" rel=\"footnote\">3</a></sup> I don’t have access to any of the tools that I’m accustomed to having (Grasshopper etc.) so I thought I’d have a crack at doing it in something more universally accessible. <a href=\"http://threejs.org/\">Three.js</a> lets you do 3d geometry stuff in your browser<sup id=\"fnref:4\" role=\"doc-noteref\"><a href=\"https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux#fn:4\" class=\"footnote\" rel=\"footnote\">4</a></sup>.</p>\n\n<p>It shows 12 people, randomly spaced all over the globe. The orange spike (which you might need to hunt for a bit) shows the centroid of those points. If the iframe is annoying, you can <a href=\"https://notionparallax.github.io/whereToMeet/sphere.html\">see it full screen here</a>.</p>\n\n<p>I might add a bit more UI to it soon to pick cities etc. so that you can use it to pick the positions of your own friends. In the meantime, <a href=\"http://www.geomidpoint.com/\">this does almost exactly that</a>!</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\" role=\"doc-endnote\">\n      <p>Sadly, <a href=\"http://www.legacy.com/obituaries/staugustine/obituary.aspx?n=antonia-j-jones&amp;pid=150288587\">here’s her obituary</a>. <a href=\"https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:2\" role=\"doc-endnote\">\n      <p>It’s <a href=\"https://en.wikipedia.org/wiki/Figure_of_the_Earth\">not spherical</a>, it’s an <a class=\"mw-redirect\" title=\"Oblate spheroid\" href=\"https://en.wikipedia.org/wiki/Oblate_spheroid\">oblate spheroid</a>, but let’s not let that get in the way. I’m sure if you were even moderately good at maths that you could correct for that. (I’m not.) <a href=\"https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux#fnref:2\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:3\" role=\"doc-endnote\">\n      <p>where free agent == willingly unemployed. <a href=\"https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux#fnref:3\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:4\" role=\"doc-endnote\">\n      <p>There is some slightly strange stuff to get it going, but I found it surprisingly easy to pick up. The model above took me about 3 hours with no prior experience.<a href=\"http://twitter.com/andraconnect\">Alexandra Etienne</a> and <a href=\"http://twitter.com/jerome_etienne\">Jerome Etienne</a> have a super cool tutorial on <a href=\"http://learningthreejs.com/blog/2013/09/16/how-to-make-the-earth-in-webgl/\">how to make a planet</a> which helped a lot. <a href=\"https://notionparallax.co.uk/2016/centroid-of-points-on-the-surface-of-a-sphere-redux#fnref:4\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n",
 "content_hash": "sha256:584f6ecd6b31ca4d1c57d29b76850b23cb910172b621dfefb3c6305e506b1d43",
 "media": [],
 "changelog": [
  {
   "version": 1,
   "at": "2016-01-06T21:15:35Z",
   "note": null
  }
 ],
 "transclusions": []
}