{"id":276,"date":"2017-05-31T21:35:09","date_gmt":"2017-05-31T19:35:09","guid":{"rendered":"http:\/\/www.gianlucamancusi.com\/?p=276"},"modified":"2018-03-25T18:14:45","modified_gmt":"2018-03-25T16:14:45","slug":"simulate-realistic-weapons-spread-with-a-good-approach","status":"publish","type":"post","link":"https:\/\/www.gianlucamancusi.com\/wordpress\/2017\/05\/31\/simulate-realistic-weapons-spread-with-a-good-approach\/","title":{"rendered":"Realistic fire spread"},"content":{"rendered":"<p style=\"text-align: left;\"><a href=\"https:\/\/wararm.eu\/\">WarArm<\/a> team (The video game team I&#8217;m part of) is currently trying to improve the weapon&#8217;s gun experience that\u00a0must be ergonomic for the player and must reflect a soldier who in war tries to aim right on target. We noticed over time that the soldier&#8217;s fire was too random in the scope of the target and the propagation of the projectiles took place in an uncontrolled manner. How to fix the problem? How to control the <strong>randomness<\/strong> of the bullets?\u00a0Someone would just say to increase the accuracy and thus reduce the range of randomness, but so it becomes too easy for the player. We want more control of the weapon, it needs to shoot more in the center and less on the sides.<\/p>\n<h3 style=\"text-align: center;\">Let me explain with pictures<\/h3>\n<figure id=\"attachment_281\" aria-describedby=\"caption-attachment-281\" style=\"width: 471px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-281\" src=\"http:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20uniformdistribution-1-1024x1024.png\" alt=\"\" width=\"471\" height=\"471\" srcset=\"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20uniformdistribution-1-1024x1024.png 1024w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20uniformdistribution-1-150x150.png 150w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20uniformdistribution-1-300x300.png 300w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20uniformdistribution-1-768x768.png 768w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20uniformdistribution-1-160x160.png 160w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20uniformdistribution-1-320x320.png 320w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20uniformdistribution-1.png 1080w\" sizes=\"(max-width: 471px) 100vw, 471px\" \/><figcaption id=\"caption-attachment-281\" class=\"wp-caption-text\">These 20 bullets were fired with a uniform casuality<\/figcaption><\/figure>\n<figure id=\"attachment_282\" aria-describedby=\"caption-attachment-282\" style=\"width: 471px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-282\" src=\"http:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20normal-1024x1024.png\" alt=\"\" width=\"471\" height=\"471\" srcset=\"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20normal-1024x1024.png 1024w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20normal-150x150.png 150w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20normal-300x300.png 300w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20normal-768x768.png 768w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20normal-160x160.png 160w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20normal-320x320.png 320w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/20normal.png 1080w\" sizes=\"(max-width: 471px) 100vw, 471px\" \/><figcaption id=\"caption-attachment-282\" class=\"wp-caption-text\">This is what we want, 20 bullets that tend to be fired more towards the center<\/figcaption><\/figure>\n<h3 style=\"text-align: center;\">How to fix this problem?<\/h3>\n<p>My approach is to use the theory of probability and I therefore decided to help me with the wonderful gaussian function. Gaussian function appears as the density function of the normal distribution and we will use this.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-287\" src=\"http:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/image002.png\" alt=\"\" width=\"179\" height=\"74\" \/><\/p>\n<p>We must consider this function with<strong> \u03bc = 0<\/strong> and\u00a0\u03c3 = &#8220;<em>weapon accuracy<\/em>&#8220;. This values transform our &#8220;normal distribution&#8221; into a &#8220;normal standard distribution&#8221; density function. We have a density that has the following <em>graph<\/em> and has <em>mean<\/em> values at zero point. Zero point will be the center of our screen, where the shots should go. If at point x, the corresponding f(x) is high then there is more chance that the shot goes to that point.<\/p>\n<figure id=\"attachment_290\" aria-describedby=\"caption-attachment-290\" style=\"width: 480px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-290 size-full\" src=\"http:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/giphy.gif\" alt=\"\" width=\"480\" height=\"270\" \/><figcaption id=\"caption-attachment-290\" class=\"wp-caption-text\">By varying the\u00a0&#8220;<em>weapon accuracy<\/em>&#8221; (zero is the center of the screen)<\/figcaption><\/figure>\n<h3 style=\"text-align: center;\">It all seems complicated but &#8230;<\/h3>\n<p>This formula does not seem easy to apply. The computer fails to generate randomness of this type, because the random features available in the basic libraries of most languages are of uniform distribution. That is, uniform randomness over a range [a, b) such as the bullets distribution in the first image.\u00a0Searching and searching I found a way that allows us to approximate normal distribution starting from two randomly uniformly distributed variables (which we have available with any function that generates a random number).<\/p>\n<h3 id=\"firstHeading\" class=\"firstHeading\" lang=\"en\" style=\"text-align: center;\">Box\u2013Muller transform<\/h3>\n<p>Here we are finally at the heart of the matter.\u00a0Now we understand how to generate random numbers so as to simulate the will of the soldier to shoot tensely toward the center rather than at random in a spherical range. To get to a normal distribution we use the <b>Box\u2013Muller transform\u00a0<\/b>for generating standard, independent, <strong>normally distributed<\/strong>\u00a0with zero expectation, unit variance (that we will change) random numbers, given a source of <strong>uniformly distributed random numbers<\/strong>.<\/p>\n<p>This transformation get in input two-dimensional continuous uniform distribution to give in output a normal distribution. If x<sub><small>1<\/small><\/sub> and x<sub><small>2<\/small><\/sub> are our two random generated values between 0 and 1, we can use these random variables in this formula to get a normal distributed value:<\/p>\n<figure id=\"attachment_293\" aria-describedby=\"caption-attachment-293\" style=\"width: 209px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-293\" src=\"http:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/image002-1.png\" alt=\"\" width=\"209\" height=\"37\" srcset=\"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/image002-1.png 305w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/image002-1-300x53.png 300w\" sizes=\"(max-width: 209px) 100vw, 209px\" \/><figcaption id=\"caption-attachment-293\" class=\"wp-caption-text\">At the same formula can be applied the cosine<\/figcaption><\/figure>\n<h3 style=\"text-align: center;\">Code example in C#<\/h3>\n<pre class=\"lang:c# decode:true\">System.Random rand = new System.Random(); \/\/Generate the object once because the shoots occur frequently\r\ndouble RandomNormalDistribution(double mean = 0, double stdDev = 1f) \/\/mean = 0 is the center of the screen\r\n{\r\n    \/\/uniform in (0,1] interval\r\n    double x1 = (1.0 - rand.NextDouble());\r\n    double x2 = (1.0 - rand.NextDouble());\r\n\r\n    double randStdNormal = mean + stdDev * (Math.Sqrt(-2.0f * Math.Log(x1)) * Math.Sin(2.0f * Math.PI * x2)); \/\/normal(mean, stdDev)\r\n    return randStdNormal;\r\n}<\/pre>\n<p>This is an example of use:<\/p>\n<pre class=\"lang:default decode:true\">\/\/You can change the accuracy value (remember to leave the mean to zero, is the center of the screen)\r\ndouble ErrorX = RandomNormalDistribution(stdDev: Accuracy); \r\ndouble ErrorY = RandomNormalDistribution(stdDev: Accuracy);<\/pre>\n<p>The two error variables (ErrorX and ErrorY) will be used to define the point of the shot.<strong>\u00a0Firing several shots you will notice that they will tend toward the center!\u00a0<\/strong>It will no longer be a totally random shot. I wonder if the best games on the market will use a similar technique.<\/p>\n<p>What do you think of this idea?<\/p>\n<figure id=\"attachment_302\" aria-describedby=\"caption-attachment-302\" style=\"width: 354px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-302\" src=\"http:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/gaussprobability-1024x1024.png\" alt=\"\" width=\"354\" height=\"354\" srcset=\"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/gaussprobability-1024x1024.png 1024w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/gaussprobability-150x150.png 150w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/gaussprobability-300x300.png 300w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/gaussprobability-768x768.png 768w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/gaussprobability-160x160.png 160w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/gaussprobability-320x320.png 320w, https:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/gaussprobability.png 1080w\" sizes=\"(max-width: 354px) 100vw, 354px\" \/><figcaption id=\"caption-attachment-302\" class=\"wp-caption-text\">Firing probability: red very likely. Yellow unlikely<\/figcaption><\/figure>\n<h2 style=\"text-align: center;\">Update<\/h2>\n<h3 style=\"text-align: center;\">Polar form (computationally faster)<\/h3>\n<p>You can avoid the sine function and apply a formula in polar coordinates that returns a normal distributed random variable.<br \/>\nWe need the usual two uniformly distributed random variables (u and v) and a variable <em><strong>s<\/strong> = u^2 + v^2 such that 0&lt;<strong>s<\/strong>\u22641\u00a0<\/em>(These hypotheses are important).<\/p>\n<p>Now we can get two normal variables (maybe one to cache for next use) with this formula:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-312\" src=\"http:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/image002-2.png\" alt=\"\" width=\"131\" height=\"68\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-313\" src=\"http:\/\/www.gianlucamancusi.com\/wordpress\/wp-content\/uploads\/2017\/05\/image004.png\" alt=\"\" width=\"130\" height=\"68\" \/><\/p>\n<p>Obviously we will multiply these variables for variance to change the accuracy.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>WarArm team (The video game team I&#8217;m part of) is currently trying to improve the weapon&#8217;s gun experience that\u00a0must be ergonomic for the player and must reflect a soldier who in war tries to aim right on target. We noticed over time that the soldier&#8217;s fire was too random in the scope of the target&hellip;<\/p>\n","protected":false},"author":1,"featured_media":298,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"footnotes":""},"categories":[48,12,5],"tags":[45,54,52,55,6,56,53],"aioseo_notices":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/posts\/276"}],"collection":[{"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/comments?post=276"}],"version-history":[{"count":23,"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/posts\/276\/revisions"}],"predecessor-version":[{"id":386,"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/posts\/276\/revisions\/386"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/media\/298"}],"wp:attachment":[{"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/media?parent=276"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/categories?post=276"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gianlucamancusi.com\/wordpress\/wp-json\/wp\/v2\/tags?post=276"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}