<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Make balls bounce</title>
		<link>http://www.allegro.cc/forums/view/617610</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 08 Nov 2018 23:49:28 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Does anyone see anything wrong with the following code? There&#39;s something wrong with my normals, they don&#39;t bounce properly.</p><p><b>EDIT</b><br />The highlighted lines are wrong. (Because the DotProduct function was wrong)
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">bool</span> MakeCirclesBounce<span class="k2">(</span>Circle<span class="k3">*</span> c1 , Circle<span class="k3">*</span> c2<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  2</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>c1 <span class="k3">|</span><span class="k3">|</span> <span class="k3">!</span>c2<span class="k2">)</span> <span class="k2">{</span><span class="k1">return</span> <span class="k1">false</span><span class="k2">;</span><span class="k2">}</span>
<span class="number">  3</span>   
<span class="number">  4</span>   <span class="c">/// Normalized normal vectors, these point from one circle towards the other</span>
<span class="number">  5</span>   Vec2 N1 <span class="k3">=</span> Vec2<span class="k2">(</span>c2-&gt;cx <span class="k3">-</span> c1-&gt;cx , c2-&gt;cy <span class="k3">-</span> c1-&gt;cy<span class="k2">)</span>.Normalize<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  6</span>   Vec2 N2 <span class="k3">=</span> Vec2<span class="k2">(</span>c1-&gt;cx <span class="k3">-</span> c2-&gt;cx , c1-&gt;cy <span class="k3">-</span> c2-&gt;cy<span class="k2">)</span>.Normalize<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  7</span>   
<span class="number">  8</span>   Vec2 V1<span class="k2">(</span>c1-&gt;vx , c1-&gt;vy<span class="k2">)</span><span class="k2">;</span>
<span class="number">  9</span>   Vec2 V2<span class="k2">(</span>c2-&gt;vx , c2-&gt;vy<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 10</span>   
<span class="number"> 11</span>   <span class="k1">const</span> <span class="k1">double</span> m1 <span class="k3">=</span> c1-&gt;mass<span class="k2">;</span>
<span class="number"> 12</span>   <span class="k1">const</span> <span class="k1">double</span> m2 <span class="k3">=</span> c2-&gt;mass<span class="k2">;</span>
<span class="number"> 13</span>
<span class="number"> 14</span>   Vec2 I1 <span class="k3">=</span> V1<span class="k3">*</span>m1<span class="k2">;</span>
<span class="number"> 15</span>   Vec2 I2 <span class="k3">=</span> V2<span class="k3">*</span>m2<span class="k2">;</span>
<span class="number"> 16</span><span class="c">///   double Itotal = (I1 + I2).Magnitude();</span>
<span class="number"> 17</span>   
<span class="number"> 18</span>   <span class="c">/// The angle between V and N determines how much energy is transferred</span>
<span class="number"> 19</span>   
<span class="number"> 20</span>   <span class="k1">const</span> <span class="k1">double</span> I1M <span class="k3">=</span> I1.Magnitude<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 21</span>   <span class="k1">const</span> <span class="k1">double</span> I2M <span class="k3">=</span> I2.Magnitude<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 22</span>
<span class="number"> 23</span>   <span class="k1">double</span> cosA1 <span class="k3">=</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">;</span>
<span class="number"> 24</span>   <span class="k1">double</span> cosA2 <span class="k3">=</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">;</span>
<span class="number"> 25</span>   
<span class="number"> 26</span>   <span class="k1">if</span> <span class="k2">(</span>I1M <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 27</span>      cosA1 <span class="k3">=</span> DotProduct<span class="k2">(</span>I1 , N1<span class="k2">)</span><span class="k3">/</span>I1M<span class="k2">;</span><span class="c">/// Magnitude of N is always 1, they're normalized</span>
<span class="number"> 28</span>   <span class="k2">}</span>
<span class="number"> 29</span>   <span class="k1">if</span> <span class="k2">(</span>I2M <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span><span class="c">/// Object has momentum</span>
<span class="number"> 30</span>      cosA2 <span class="k3">=</span> DotProduct<span class="k2">(</span>I2 , N2<span class="k2">)</span><span class="k3">/</span>I2M<span class="k2">;</span><span class="c">/// Magnitude of N is always 1, they're normalized</span>
<span class="number"> 31</span>   <span class="k2">}</span>
<span class="number"> 32</span>   
<span class="number"> 33</span>   <span class="c">/// Momentum of circle one in the normal direction***</span>
<div class="highlight"><span class="number"> 34</span>   Vec2 I1N <span class="k3">=</span> N1<span class="k3">*</span>cosA1<span class="k3">*</span>I1M<span class="k2">;</span></div><span class="number"> 35</span>   <span class="c">/// Momentum of circle two in the normal direction***</span>
<div class="highlight"><span class="number"> 36</span>   Vec2 I2N <span class="k3">=</span> N2<span class="k3">*</span>cosA2<span class="k3">*</span>I2M<span class="k2">;</span></div><span class="number"> 37</span>
<span class="number"> 38</span>   <span class="k1">if</span> <span class="k2">(</span>cosA1 <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 39</span>      <span class="c">/// Circle one is moving towards circle two</span>
<span class="number"> 40</span>      <span class="c">/// Give circle ones normal momentum to circle two</span>
<span class="number"> 41</span>      I1 <span class="k3">=</span> I1 <span class="k3">-</span> I1N<span class="k2">;</span><span class="c">/// This momentum is lost, transferred to the other circle</span>
<span class="number"> 42</span>      I1N <span class="k3">*</span><span class="k3">=</span> ELASTICITY<span class="k2">;</span><span class="c">/// Energy is lost due to inelasticity</span>
<span class="number"> 43</span>      <span class="k1">if</span> <span class="k2">(</span>c2-&gt;fixed<span class="k2">)</span> <span class="k2">{</span><span class="c">/// We hit an immovable object</span>
<span class="number"> 44</span>         I1N <span class="k3">*</span><span class="k3">=</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="c">/// Reflection of normal energy</span>
<span class="number"> 45</span>         I1 <span class="k3">+</span><span class="k3">=</span> I1N<span class="k2">;</span><span class="c">/// rebound effect</span>
<span class="number"> 46</span>      <span class="k2">}</span>
<span class="number"> 47</span>      <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 48</span>         I2 <span class="k3">=</span> I2 <span class="k3">+</span> I1N<span class="k2">;</span><span class="c">/// The remaining momentum is gained by the other circle</span>
<span class="number"> 49</span>      <span class="k2">}</span>
<span class="number"> 50</span>   <span class="k2">}</span>
<span class="number"> 51</span>
<span class="number"> 52</span>   <span class="k1">if</span> <span class="k2">(</span>cosA2 <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 53</span>      <span class="c">/// Circle two is moving towards circle one</span>
<span class="number"> 54</span>      <span class="c">/// Give circle twos normal momentum to circle one</span>
<span class="number"> 55</span>      I2 <span class="k3">=</span> I2 <span class="k3">-</span> I2N<span class="k2">;</span><span class="c">/// This momentum is lost</span>
<span class="number"> 56</span>      I2N <span class="k3">*</span><span class="k3">=</span> ELASTICITY<span class="k2">;</span><span class="c">/// Energy lost due to inelasticity</span>
<span class="number"> 57</span>      <span class="k1">if</span> <span class="k2">(</span>c1-&gt;fixed<span class="k2">)</span> <span class="k2">{</span><span class="c">/// We hit an immovable object</span>
<span class="number"> 58</span>         I2N <span class="k3">*</span><span class="k3">=</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="c">/// Reflection of normal energy</span>
<span class="number"> 59</span>         I2 <span class="k3">+</span><span class="k3">=</span> I2N<span class="k2">;</span><span class="c">/// rebound effect</span>
<span class="number"> 60</span>      <span class="k2">}</span>
<span class="number"> 61</span>      <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 62</span>         I1 <span class="k3">=</span> I1 <span class="k3">+</span> I2N<span class="k2">;</span><span class="c">/// The remaining momentum is gained by the other circle</span>
<span class="number"> 63</span>      <span class="k2">}</span>
<span class="number"> 64</span>   <span class="k2">}</span>
<span class="number"> 65</span><span class="c">///   double Itotal2 = (I1 + I2).Magnitude();</span>
<span class="number"> 66</span>   
<span class="number"> 67</span>   <span class="k1">bool</span> changed <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span>
<span class="number"> 68</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>c1-&gt;fixed <span class="k3">&amp;</span><span class="k3">&amp;</span> m1 <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 69</span>      V1 <span class="k3">=</span> I1<span class="k3">*</span><span class="k2">(</span><span class="n">1</span>.<span class="n">0</span><span class="k3">/</span>m1<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 70</span>      c1-&gt;SetSpeed<span class="k2">(</span>V1.x , V1.y<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 71</span>      changed <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 72</span>   <span class="k2">}</span>
<span class="number"> 73</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>c2-&gt;fixed <span class="k3">&amp;</span><span class="k3">&amp;</span> m2 <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 74</span>      V2 <span class="k3">=</span> I2<span class="k3">*</span><span class="k2">(</span><span class="n">1</span>.<span class="n">0</span><span class="k3">/</span>m2<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 75</span>      c2-&gt;SetSpeed<span class="k2">(</span>V2.x , V2.y<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 76</span>      changed <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 77</span>   <span class="k2">}</span>
<span class="number"> 78</span>   <span class="k1">return</span> changed<span class="k2">;</span>
<span class="number"> 79</span><span class="k2">}</span>
</div></div><p>

I would suspect the problem to be here :
</p><div class="source-code snippet"><div class="inner"><pre>   <span class="k1">if</span> <span class="k2">(</span>I1M <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
      <span class="c">/// Magnitude of N is always 1, they're normalized</span>
<div class="highlight">      cosA1 <span class="k3">=</span> DotProduct<span class="k2">(</span>I1 , N1<span class="k2">)</span><span class="k3">/</span>I1M<span class="k2">;</span></div>
   <span class="k2">}</span>
   <span class="k1">if</span> <span class="k2">(</span>I2M <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span><span class="c">/// Object has momentum</span>
      <span class="c">/// Magnitude of N is always 1, they're normalized</span>
<div class="highlight">      cosA2 <span class="k3">=</span> DotProduct<span class="k2">(</span>I2 , N2<span class="k2">)</span><span class="k3">/</span>I2M<span class="k2">;</span></div>
   <span class="k2">}</span>
   
   <span class="c">/// Momentum of circle one in the normal direction</span>
<div class="highlight">   Vec2 I1N <span class="k3">=</span> N1<span class="k3">*</span>cosA1<span class="k3">*</span>I1M<span class="k2">;</span></div>
   <span class="c">/// Momentum of circle two in the normal direction</span>
<div class="highlight">   Vec2 I2N <span class="k3">=</span> N2<span class="k3">*</span>cosA2<span class="k3">*</span>I2M<span class="k2">;</span></div>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Wed, 07 Nov 2018 02:58:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I’m a little thrown by your instance variables starting with capitals. You should consider all class names with capitals and instances with lowercase.</p><p>Too drunk to actually think math, but you might consider breaking up parts of your function into smaller parts and testing on them individually.  There’s a lot of potential points of failure here and if you can narrow it down with confidence then you can eliminate the guessing and checking.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 08 Nov 2018 12:55:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/617610/1039943#target">Mark Oates</a> said:</div><div class="quote"><p>
I’m a little thrown by your instance variables starting with capitals. You should consider all class names with capitals and instances with lowercase.
</p></div></div><p>
Next time I&#39;ll consult a style guide. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /> They&#39;re mathematical variables, and constants. Usually I DO use lowercase for variables, but in this case, I felt it made things clearer, not worse.</p><p>The real clincher is, does the projection of A unto B really equal ^B*|A|(A.B)?</p><p>Ah hah ha hha haahahah hhaaaaaaaa I fixed it.</p><p>First, my dot product was wrong. I was doing some bizarre hybrid of a cross product and a dot product.</p><p>Second, you don&#39;t need to multiply by the |A|.</p><p>The projection of A unto B really is as simple as ^B*(A.^B).</p><p>Here&#39;s a little demo program to play with :</p><p><a href="https://www.allegro.cc/files/attachment/611745">Download win32 binary here (CVC.7z)</a>.</p><p><span class="remote-thumbnail"><span class="json">{"name":"611744","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/9\/89998192365f296251917fb8ccf783fe.png","w":802,"h":633,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/9\/89998192365f296251917fb8ccf783fe"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/8/9/89998192365f296251917fb8ccf783fe-240.jpg" alt="611744" width="240" height="189" /></span></p><p>There&#39;s a little problem of balls escaping the pen every once in a while, and I have to figure that out next.</p><p>If anyone wants to check out the source code, it&#39;s on GitHub here :</p><p><a href="https://github.com/EdgarReynaldo/Interceptor">https://github.com/EdgarReynaldo/Interceptor</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Thu, 08 Nov 2018 20:52:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>So, for the benefit of others (obviously <i>I</i> know <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /> ) which line was incorrect in your original code?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Peter Hull)</author>
		<pubDate>Thu, 08 Nov 2018 22:44:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>So the problem was DotProduct. It returned x1y2 + x2y1, which is nonsense. It should be x1x2 + y1*y2.</p><p>The updated code is here :</p><p><a href="https://github.com/EdgarReynaldo/Interceptor">https://github.com/EdgarReynaldo/Interceptor</a></p><p><a href="https://github.com/EdgarReynaldo/Interceptor/blob/master/Circle.cpp">https://github.com/EdgarReynaldo/Interceptor/blob/master/Circle.cpp</a></p><p>The collision detection is super easy. Here is the code :
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">double</span> CalculateCollision<span class="k2">(</span>Circle<span class="k3">*</span> c1 , Circle<span class="k3">*</span> c2<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  2</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>c1 <span class="k3">|</span><span class="k3">|</span> <span class="k3">!</span>c2<span class="k2">)</span> <span class="k2">{</span><span class="k1">return</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="k2">}</span>
<span class="number">  3</span>   
<span class="number">  4</span>   <span class="k1">const</span> <span class="k1">double</span> dx <span class="k3">=</span> c2-&gt;cx <span class="k3">-</span> c1-&gt;cx<span class="k2">;</span>
<span class="number">  5</span>   <span class="k1">const</span> <span class="k1">double</span> dy <span class="k3">=</span> c2-&gt;cy <span class="k3">-</span> c1-&gt;cy<span class="k2">;</span>
<span class="number">  6</span>   <span class="k1">const</span> <span class="k1">double</span> dvx <span class="k3">=</span> c2-&gt;vx <span class="k3">-</span> c1-&gt;vx<span class="k2">;</span>
<span class="number">  7</span>   <span class="k1">const</span> <span class="k1">double</span> dvy <span class="k3">=</span> c2-&gt;vy <span class="k3">-</span> c1-&gt;vy<span class="k2">;</span>
<span class="number">  8</span>   <span class="k1">const</span> <span class="k1">double</span> rsq <span class="k3">=</span> <span class="k2">(</span>c1-&gt;rad <span class="k3">+</span> c2-&gt;rad<span class="k2">)</span><span class="k3">*</span><span class="k2">(</span>c1-&gt;rad <span class="k3">+</span> c2-&gt;rad<span class="k2">)</span><span class="k2">;</span>
<span class="number">  9</span>   
<span class="number"> 10</span>   <span class="c">/// Quadratic equation Ax^2 + Bx + C = 0</span>
<span class="number"> 11</span>   <span class="k1">const</span> <span class="k1">double</span> A <span class="k3">=</span> <span class="k2">(</span>dvx<span class="k3">*</span>dvx <span class="k3">+</span> dvy<span class="k3">*</span>dvy<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 12</span>   <span class="k1">const</span> <span class="k1">double</span> B <span class="k3">=</span> <span class="n">2</span>.<span class="n">0</span><span class="k3">*</span><span class="k2">(</span>dvx<span class="k3">*</span>dx <span class="k3">+</span> dvy<span class="k3">*</span>dy<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 13</span>   <span class="k1">const</span> <span class="k1">double</span> C <span class="k3">=</span> dx<span class="k3">*</span>dx <span class="k3">+</span> dy<span class="k3">*</span>dy <span class="k3">-</span> rsq<span class="k2">;</span>
<span class="number"> 14</span>
<span class="number"> 15</span>   <span class="k1">if</span> <span class="k2">(</span>A <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 16</span>      <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="c">/// No relative movement, collision is impossible</span>
<span class="number"> 17</span>   <span class="k2">}</span>
<span class="number"> 18</span>   
<span class="number"> 19</span>   <span class="c">/// Overlap check here - if they are already colliding at time 0.0, let them pass undisturbed</span>
<span class="number"> 20</span>   <span class="k1">if</span> <span class="k2">(</span>C <span class="k3">&lt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span><span class="k1">return</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="k2">}</span>
<span class="number"> 21</span>
<span class="number"> 22</span>   <span class="k1">const</span> <span class="k1">double</span> TWOA <span class="k3">=</span> <span class="n">2</span>.<span class="n">0</span><span class="k3">*</span>A<span class="k2">;</span>
<span class="number"> 23</span>   <span class="k1">const</span> <span class="k1">double</span> DISCRIM <span class="k3">=</span> B<span class="k3">*</span>B <span class="k3">-</span> <span class="n">4</span>.<span class="n">0</span><span class="k3">*</span>A<span class="k3">*</span>C<span class="k2">;</span>
<span class="number"> 24</span>   <span class="k1">if</span> <span class="k2">(</span>DISCRIM <span class="k3">&lt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span><span class="k1">return</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="k2">}</span><span class="c">/// no real roots</span>
<span class="number"> 25</span>   <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span>DISCRIM <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 26</span>      <span class="k1">return</span> <span class="k3">-</span>B<span class="k3">/</span>TWOA<span class="k2">;</span>
<span class="number"> 27</span>   <span class="k2">}</span>
<span class="number"> 28</span>   <span class="k1">const</span> <span class="k1">double</span> SQRTD <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_738.html" target="_blank">sqrt</a><span class="k2">(</span>DISCRIM<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 29</span>   <span class="k1">const</span> <span class="k1">double</span> T1 <span class="k3">=</span> <span class="k2">(</span><span class="k3">-</span>B <span class="k3">-</span> SQRTD<span class="k2">)</span><span class="k3">/</span>TWOA<span class="k2">;</span>
<span class="number"> 30</span>   <span class="k1">const</span> <span class="k1">double</span> T2 <span class="k3">=</span> <span class="k2">(</span><span class="k3">-</span>B <span class="k3">+</span> SQRTD<span class="k2">)</span><span class="k3">/</span>TWOA<span class="k2">;</span>
<span class="number"> 31</span>   <span class="k1">if</span> <span class="k2">(</span>T1 <span class="k3">&gt;</span><span class="k3">=</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 32</span>      <span class="k1">return</span> T1<span class="k2">;</span>
<span class="number"> 33</span>   <span class="k2">}</span>
<span class="number"> 34</span><span class="c">///   else if (T2 &gt;= 0.0) {</span>
<span class="number"> 35</span><span class="c">///      return T2;</span>
<span class="number"> 36</span><span class="c">///   }</span>
<span class="number"> 37</span>   <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="c">/// No collision possible in the future</span>
<span class="number"> 38</span><span class="k2">}</span>
</div></div><p>

And the new code for bouncing is here :</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">bool</span> MakeCirclesBounce2<span class="k2">(</span>Circle<span class="k3">*</span> c1 , Circle<span class="k3">*</span> c2<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  2</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>c1 <span class="k3">|</span><span class="k3">|</span> <span class="k3">!</span>c2<span class="k2">)</span> <span class="k2">{</span><span class="k1">return</span> <span class="k1">false</span><span class="k2">;</span><span class="k2">}</span>
<span class="number">  3</span>   
<span class="number">  4</span>   <span class="c">/// Normalized normal vectors, these point from one circle towards the other</span>
<span class="number">  5</span>   Vec2 N1 <span class="k3">=</span> Vec2<span class="k2">(</span>c2-&gt;cx <span class="k3">-</span> c1-&gt;cx , c2-&gt;cy <span class="k3">-</span> c1-&gt;cy<span class="k2">)</span>.Normalize<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  6</span>   Vec2 N2 <span class="k3">=</span> Vec2<span class="k2">(</span>c1-&gt;cx <span class="k3">-</span> c2-&gt;cx , c1-&gt;cy <span class="k3">-</span> c2-&gt;cy<span class="k2">)</span>.Normalize<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  7</span>   
<span class="number">  8</span>   Vec2 V1<span class="k2">(</span>c1-&gt;vx , c1-&gt;vy<span class="k2">)</span><span class="k2">;</span>
<span class="number">  9</span>   Vec2 V2<span class="k2">(</span>c2-&gt;vx , c2-&gt;vy<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 10</span>   
<span class="number"> 11</span>   <span class="k1">const</span> <span class="k1">double</span> m1 <span class="k3">=</span> c1-&gt;mass<span class="k2">;</span>
<span class="number"> 12</span>   <span class="k1">const</span> <span class="k1">double</span> m2 <span class="k3">=</span> c2-&gt;mass<span class="k2">;</span>
<span class="number"> 13</span>
<span class="number"> 14</span>   Vec2 I1 <span class="k3">=</span> V1<span class="k3">*</span>m1<span class="k2">;</span>
<span class="number"> 15</span>   Vec2 I2 <span class="k3">=</span> V2<span class="k3">*</span>m2<span class="k2">;</span>
<span class="number"> 16</span><span class="c">///   double Itotal = (I1 + I2).Magnitude();</span>
<span class="number"> 17</span>   
<span class="number"> 18</span>   <span class="c">/// The angle between V and N determines how much energy is transferred</span>
<span class="number"> 19</span>   
<span class="number"> 20</span>   <span class="k1">const</span> <span class="k1">double</span> I1M <span class="k3">=</span> I1.Magnitude<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 21</span>   <span class="k1">const</span> <span class="k1">double</span> I2M <span class="k3">=</span> I2.Magnitude<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 22</span>
<span class="number"> 23</span>   Vec2 I1N<span class="k2">(</span><span class="n">0</span>,<span class="n">0</span><span class="k2">)</span><span class="k2">;</span><span class="c">/// Momentum of circle one in the normal direction</span>
<span class="number"> 24</span>   Vec2 I2N<span class="k2">(</span><span class="n">0</span>,<span class="n">0</span><span class="k2">)</span><span class="k2">;</span><span class="c">/// Momentum of circle two in the normal direction</span>
<span class="number"> 25</span>
<span class="number"> 26</span>   <span class="k1">if</span> <span class="k2">(</span>I1M <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 27</span>      I1N <span class="k3">=</span> ScalarProjection<span class="k2">(</span>I1 , N1<span class="k2">)</span><span class="k2">;</span><span class="c">/// Magnitude of N is always 1, they're normalized</span>
<span class="number"> 28</span>   <span class="k2">}</span>
<span class="number"> 29</span>   <span class="k1">if</span> <span class="k2">(</span>I2M <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span><span class="c">/// Object has momentum</span>
<span class="number"> 30</span>      I2N <span class="k3">=</span> ScalarProjection<span class="k2">(</span>I2 , N2<span class="k2">)</span><span class="k2">;</span><span class="c">/// Magnitude of N is always 1, they're normalized</span>
<span class="number"> 31</span>   <span class="k2">}</span>
<span class="number"> 32</span>
<span class="number"> 33</span>   <span class="k1">if</span> <span class="k2">(</span>DotProduct<span class="k2">(</span>I1,N1<span class="k2">)</span> <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 34</span>      <span class="c">/// Circle one is moving towards circle two</span>
<span class="number"> 35</span>      <span class="c">/// Give circle ones normal momentum to circle two</span>
<span class="number"> 36</span>      I1 <span class="k3">=</span> I1 <span class="k3">-</span> I1N<span class="k2">;</span><span class="c">/// This momentum is lost, transferred to the other circle</span>
<span class="number"> 37</span>      I1N <span class="k3">*</span><span class="k3">=</span> ELASTICITY<span class="k2">;</span><span class="c">/// Energy is lost due to inelasticity</span>
<span class="number"> 38</span>      <span class="k1">if</span> <span class="k2">(</span>c2-&gt;fixed<span class="k2">)</span> <span class="k2">{</span><span class="c">/// We hit an immovable object</span>
<span class="number"> 39</span>         I1N <span class="k3">*</span><span class="k3">=</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="c">/// Reflection of normal energy</span>
<span class="number"> 40</span>         I1 <span class="k3">+</span><span class="k3">=</span> I1N<span class="k2">;</span><span class="c">/// rebound effect</span>
<span class="number"> 41</span>      <span class="k2">}</span>
<span class="number"> 42</span>      <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 43</span>         I2 <span class="k3">=</span> I2 <span class="k3">+</span> I1N<span class="k2">;</span><span class="c">/// The remaining momentum is gained by the other circle</span>
<span class="number"> 44</span>      <span class="k2">}</span>
<span class="number"> 45</span>   <span class="k2">}</span>
<span class="number"> 46</span>
<span class="number"> 47</span>   <span class="k1">if</span> <span class="k2">(</span>DotProduct<span class="k2">(</span>I2,N2<span class="k2">)</span> <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 48</span>      <span class="c">/// Circle two is moving towards circle one</span>
<span class="number"> 49</span>      <span class="c">/// Give circle twos normal momentum to circle one</span>
<span class="number"> 50</span>      I2 <span class="k3">=</span> I2 <span class="k3">-</span> I2N<span class="k2">;</span><span class="c">/// This momentum is lost</span>
<span class="number"> 51</span>      I2N <span class="k3">*</span><span class="k3">=</span> ELASTICITY<span class="k2">;</span><span class="c">/// Energy lost due to inelasticity</span>
<span class="number"> 52</span>      <span class="k1">if</span> <span class="k2">(</span>c1-&gt;fixed<span class="k2">)</span> <span class="k2">{</span><span class="c">/// We hit an immovable object</span>
<span class="number"> 53</span>         I2N <span class="k3">*</span><span class="k3">=</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span><span class="c">/// Reflection of normal energy</span>
<span class="number"> 54</span>         I2 <span class="k3">+</span><span class="k3">=</span> I2N<span class="k2">;</span><span class="c">/// rebound effect</span>
<span class="number"> 55</span>      <span class="k2">}</span>
<span class="number"> 56</span>      <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 57</span>         I1 <span class="k3">=</span> I1 <span class="k3">+</span> I2N<span class="k2">;</span><span class="c">/// The remaining momentum is gained by the other circle</span>
<span class="number"> 58</span>      <span class="k2">}</span>
<span class="number"> 59</span>   <span class="k2">}</span>
<span class="number"> 60</span><span class="c">///   double Itotal2 = (I1 + I2).Magnitude();</span>
<span class="number"> 61</span>   
<span class="number"> 62</span>   <span class="k1">bool</span> changed <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span>
<span class="number"> 63</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>c1-&gt;fixed <span class="k3">&amp;</span><span class="k3">&amp;</span> m1 <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 64</span>      V1 <span class="k3">=</span> I1<span class="k3">*</span><span class="k2">(</span><span class="n">1</span>.<span class="n">0</span><span class="k3">/</span>m1<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 65</span>      c1-&gt;SetSpeed<span class="k2">(</span>V1.x , V1.y<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 66</span>      changed <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 67</span>   <span class="k2">}</span>
<span class="number"> 68</span>   <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>c2-&gt;fixed <span class="k3">&amp;</span><span class="k3">&amp;</span> m2 <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 69</span>      V2 <span class="k3">=</span> I2<span class="k3">*</span><span class="k2">(</span><span class="n">1</span>.<span class="n">0</span><span class="k3">/</span>m2<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 70</span>      c2-&gt;SetSpeed<span class="k2">(</span>V2.x , V2.y<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 71</span>      changed <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 72</span>   <span class="k2">}</span>
<span class="number"> 73</span>   <span class="k1">return</span> changed<span class="k2">;</span>
<span class="number"> 74</span><span class="k2">}</span>
</div></div><p>

The code for ScalarProjection is here :</p><div class="source-code snippet"><div class="inner"><pre>Vec2 ScalarProjection<span class="k2">(</span>Vec2 A , Vec2 B<span class="k2">)</span> <span class="k2">{</span>
   B.Normalize<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
   <span class="k1">return</span> B<span class="k3">*</span>DotProduct<span class="k2">(</span>A,B<span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

And the code for DotProduct is here :
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">inline</span> <span class="k1">double</span> DotProduct<span class="k2">(</span><span class="k1">const</span> Vec2<span class="k3">&amp;</span> v1 , <span class="k1">const</span> Vec2<span class="k3">&amp;</span> v2<span class="k2">)</span> <span class="k2">{</span>
   <span class="k1">return</span> v1.x<span class="k3">*</span>v2.x <span class="k3">+</span> v1.y<span class="k3">*</span>v2.y<span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

What&#39;s really interesting though, is the collision table. Check it out :</p><p><a href="https://github.com/EdgarReynaldo/Interceptor/blob/master/CollTable.cpp">https://github.com/EdgarReynaldo/Interceptor/blob/master/CollTable.cpp</a><br /><a href="https://github.com/EdgarReynaldo/Interceptor/blob/master/CollTable.hpp">https://github.com/EdgarReynaldo/Interceptor/blob/master/CollTable.hpp</a></p><p>It is a vector of pairs of circles, representing each possible combination of N circles. It is exactly (N*(N-1))/2 in size. If you&#39;re doing a 1000 circle collision resolution, it will make 499,500 pairs. But the beauty is you only have to recalculate it if the velocity of one of the circles changes. This eliminates 99% of the wasted calculations of doing a frame by frame overlap check.</p><p><b>EDIT</b><br /><span class="remote-thumbnail"><span class="json">{"name":"611747","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/3\/635673b9af24f3c2c81797b18d2333ee.png","w":1027,"h":800,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/3\/635673b9af24f3c2c81797b18d2333ee"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/6/3/635673b9af24f3c2c81797b18d2333ee-240.jpg" alt="611747" width="240" height="186" /></span></p><p>You&#39;ll notice that balls 13 and 14 are missing. They escaped. <img src="http://www.allegro.cc/forums/smileys/shocked.gif" alt=":o" /></p><p><span class="remote-thumbnail"><span class="json">{"name":"611748","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/9\/c9d7ea71f2e32e14391e295f5548be94.png","w":1027,"h":800,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/9\/c9d7ea71f2e32e14391e295f5548be94"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/c/9/c9d7ea71f2e32e14391e295f5548be94-240.jpg" alt="611748" width="240" height="186" /></span></p><p>The fuller it is the more often they escape.</p><p>It&#39;s really quite stable, except for the escaping bit.</p><p>Aha! I fixed it. No more escape for you my pretties. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /></p><p><span class="remote-thumbnail"><span class="json">{"name":"611749","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/a\/aab5277509ad27b99a5096f0cd412ec9.png","w":1026,"h":801,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/a\/aab5277509ad27b99a5096f0cd412ec9"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/a/a/aab5277509ad27b99a5096f0cd412ec9-240.jpg" alt="611749" width="240" height="187" /></span></p><p>The problem was in CollTable.cpp on line 114 :
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number"> 102</span>std::vector<span class="k3">&lt;</span>CollInfo<span class="k3">*</span><span class="k3">&gt;</span> CollTable::GetFirstCollisionsEarlierThanDT<span class="k2">(</span><span class="k1">double</span> dt<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 103</span>   std::vector<span class="k3">&lt;</span>CollInfo<span class="k3">*</span><span class="k3">&gt;</span> clist<span class="k2">;</span>
<span class="number"> 104</span>   <span class="k1">const</span> <span class="k1">unsigned</span> <span class="k1">int</span> N <span class="k3">=</span> ctable.size<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 105</span>   <span class="k1">double</span> first <span class="k3">=</span> <span class="k3">-</span><span class="n">1</span>.<span class="n">0</span><span class="k2">;</span>
<span class="number"> 106</span>   <span class="k1">for</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">int</span> n <span class="k3">=</span> <span class="n">0</span> <span class="k2">;</span> n <span class="k3">&lt;</span> N <span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>n<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 107</span>      CollInfo<span class="k3">&amp;</span> info <span class="k3">=</span> ctable<span class="k2">[</span>n<span class="k2">]</span><span class="k2">;</span>
<span class="number"> 108</span>      <span class="k1">if</span> <span class="k2">(</span>info.dt <span class="k3">&lt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span><span class="k1">continue</span><span class="k2">;</span><span class="k2">}</span>
<span class="number"> 109</span>      <span class="k1">if</span> <span class="k2">(</span>info.dt <span class="k3">&gt;</span> dt<span class="k2">)</span> <span class="k2">{</span><span class="k1">continue</span><span class="k2">;</span><span class="k2">}</span>
<span class="number"> 110</span>      <span class="k1">if</span> <span class="k2">(</span>first <span class="k3">&lt;</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 111</span>         first <span class="k3">=</span> info.dt<span class="k2">;</span>
<span class="number"> 112</span>      <span class="k2">}</span>
<span class="number"> 113</span>      <span class="k1">if</span> <span class="k2">(</span>info.dt <span class="k3">&gt;</span> first<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 114</span><span class="k3">-</span>         <span class="k1">break</span><span class="k2">;</span>
<span class="number"> 115</span><span class="k3">+</span>         <span class="k1">continue</span><span class="k2">;</span>
<span class="number"> 116</span>      <span class="k2">}</span>
<span class="number"> 117</span>      clist.push_back<span class="k2">(</span><span class="k3">&amp;</span>ctable<span class="k2">[</span>n<span class="k2">]</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 118</span>   <span class="k2">}</span>
<span class="number"> 119</span>   std::sort<span class="k2">(</span>clist.begin<span class="k2">(</span><span class="k2">)</span> , clist.end<span class="k2">(</span><span class="k2">)</span> , CompareCInfo<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 120</span>   <span class="k1">return</span> clist<span class="k2">;</span>
<span class="number"> 121</span><span class="k2">}</span>
</div></div><p>

<a href="https://github.com/EdgarReynaldo/Interceptor/commit/2e72f6c26576b87a82db4c0acbe8d992a658a051#diff-c7e697629af47a878a6163ae0d115670L114">https://github.com/EdgarReynaldo/Interceptor/commit/2e72f6c26576b87a82db4c0acbe8d992a658a051#diff-c7e697629af47a878a6163ae0d115670L114</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Thu, 08 Nov 2018 23:49:28 +0000</pubDate>
	</item>
</rss>
