<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>[Math] Elasticity/Deflection</title>
		<link>http://www.allegro.cc/forums/view/588217</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Fri, 27 Oct 2006 01:31:18 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Quite a few questions here. I&#39;m looking for a very simple way to demonstrate elasticity! Basically, I have a line with two points. I have a spherical object. I want to check the line for a collision with this spherical object. After that, I need a way to find the angle of deflection... and update the spherical objects speed/direction accordingly.</p><p><span class="remote-thumbnail"><span class="json">{"name":"590377","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/7\/f7433584382862f02fff33c41ec27b86.png","w":339,"h":235,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/7\/f7433584382862f02fff33c41ec27b86"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/f/7/f7433584382862f02fff33c41ec27b86-240.jpg" alt="590377" width="240" height="166" /></span>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ngiacomelli)</author>
		<pubDate>Thu, 26 Oct 2006 04:13:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You can use these 3d equations with 2D with some minor adjustments;</p><p>Point1 = ( x1, y1, 0 );<br />Point2 = ( x2, y2, 0 );<br />Point3 = ( x2, y2, -5 );<br />Dir = direction Vector<br />spherePos = center sphere<br />sphereRadius = As it says<br />ArbitraryPointOnLine = As it says</p><p>Normal to Line:
</p><div class="source-code snippet"><div class="inner"><pre>normal <span class="k3">=</span> <span class="k2">(</span> Point2 <span class="k3">-</span> Point3 <span class="k2">)</span>.crossProduct<span class="k2">(</span> Point2 <span class="k3">-</span> Point1 <span class="k2">)</span><span class="k2">;</span>
normal <span class="k3">=</span> normal <span class="k3">/</span> normal.length<span class="k2">;</span> <span class="c">// normalize</span>
</pre></div></div><p>
Distance to Line: (distance is signed, neg means other side )
</p><div class="source-code snippet"><div class="inner"><pre>distance <span class="k3">=</span> normal.dotProduct<span class="k2">(</span> spherePos <span class="k3">-</span> ArbitraryPointOnLine <span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
To be a hit then distance is less than sphereRadius.
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">if</span> <span class="k2">(</span> distance <span class="k3">&lt;</span> sphereRadius <span class="k2">)</span>
<span class="k2">{</span>
    spherePos <span class="k3">=</span> spherePos <span class="k3">+</span> Dir <span class="k3">+</span> this-&gt;normal <span class="k3">*</span> <span class="n">2</span>.<span class="n">0</span> <span class="k3">*</span> <span class="k2">(</span> sphereRadius <span class="k3">-</span> distance <span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DanielH)</author>
		<pubDate>Thu, 26 Oct 2006 06:45:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
normal = ( Point2 - Point3 ).crossProduct( Point2 - Point1 );
</p></div></div><p>For reference (since a cross product for 2D seems a bit silly), you can find the normal direction of a 2D line like this: Say your line is p1 to p2, and it&#39;s direction is d = (p2 - p1) = (dx, dy).  Then the normal direction is just (-dy, dx).  And the normalized normal, as in the 3D case, may be found by dividing the normal direction by its magnitude.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Point3 = ( x2, y2, -5 );
</p></div></div><p>
There should be no need to keep around that Point3 variable, or use 3D math functions -- functions that only operate on 2D vectors will work just fine.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
distance = normal.dotProduct( spherePos - ArbitraryPointOnLine );
</p></div></div><p>Note that to detect a hit on a line <i>segment</i>, which is what it looks like you might be talking about, you also would want to do another dot product to find how far along the line segment the circle lies, and you&#39;d want to do two distance tests against the line segment&#39;s endpoints.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
After that, I need a way to find the angle of deflection... and update the spherical objects speed/direction accordingly.
</p></div></div><p>
You probably don&#39;t want to use an angle of deflection, or a direction vector, or a speed value.  Just track velocity.  To adjust the velocity in response to a collision, do something like this:<br />velocity += (1 + elasticity) * dotProduct(velocity, normal);<br />Where elasticity is a value between 0 and 1 (inclusive).</p><p>I&#39;ll note that I really have no idea what math you do or don&#39;t understand, so ... if anything doesn&#39;t make sense: sorry!  Ask for clarifications as needed.<br />Do you understand the dot product, and why it&#39;s useful here?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Zaphos)</author>
		<pubDate>Thu, 26 Oct 2006 07:14:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I&#39;ll note that I really have no idea what math you do or don&#39;t understand, so ... if anything doesn&#39;t make sense: sorry! Ask for clarifications as needed.<br />Do you understand the dot product, and why it&#39;s useful here?
</p></div></div><p>

I&#39;m not so hot when it comes to number work. I understand that the dot product is the result of adding two vectors together. I&#39;m not entirely sure why DanielH is using 3d equations, but I assume I can just remove the references to point3. </p><p>I&#39;m definately going to need my hand held for a little. I&#39;m not even sure how I would go about writing the routines to calculate the dot product or cross product.</p><p>I don&#39;t like to just copy and paste code. So if anyone&#39;s willing to (try) and explain this to me, that&#39;d be wonderful.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ngiacomelli)</author>
		<pubDate>Thu, 26 Oct 2006 13:40:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I&#39;m not entirely sure why DanielH is using 3d equations
</p></div></div><p>
That&#39;s all I&#39;ve been working with for the past few weeks.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DanielH)</author>
		<pubDate>Thu, 26 Oct 2006 20:33:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I understand that the dot product is the result of adding two vectors together.
</p></div></div><p>Okay, so for notation I&#39;ll refer to a vector as if it had this structure: <span class="source-code"><span class="k1">struct</span> vector <span class="k2">{</span> <span class="k1">float</span> x<span class="k2">;</span> <span class="k1">float</span> y<span class="k2">;</span> <span class="k2">}</span><span class="k2">;</span></span></p><p>The dot product is an operation that takes two vectors and returns a scalar (single number).  It takes the components of the vectors, multiplies them together, then sums the results.<br />In code, that&#39;s:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">float</span> <a href="http://www.allegro.cc/manual/dot_product" target="_blank"><span class="a">dot_product</span></a><span class="k2">(</span>vector a, vector b<span class="k2">)</span> <span class="k2">{</span>
   <span class="k1">return</span> a.x <span class="k3">*</span> b.x <span class="k3">+</span> a.y <span class="k3">*</span> b.y<span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

Abstractly, the dot product is useful because of one interesting identity: dot_product(v, n) = length(v) * length(n) * cos(theta), where theta is the angle between vectors v and n.<br />(wikipedia has a <a href="http://en.wikipedia.org/wiki/Image:Scalarproduct.gif">picture</a>, to help visualize.)<br />Computing the angle between two vectors, and their lengths, is relatively slow.  The dot product is fast and easy.  When we use the dot product, we&#39;re really using it as a short-cut to get at the length * cos(theta) value.</p><p>In our case what we want is really the length(velocity) * cos(theta).  We get this out of dot_product(velocity, normal) by ensuring the normal vector is &#39;normalized&#39; -- has length(n) == 1.<br />If you&#39;ll recall from trigonometry, the length(velocity) * cos(theta) gives the magnitude of velocity <i>in the normal direction</i>, ignoring magnitude of the velocity <i>parallel to the wall</i>.</p><p>Now, think back to your collision example.  Let&#39;s look at a picture:<br /><span class="remote-thumbnail"><span class="json">{"name":"590378","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/1\/717f363fba88a8270ff65394cac2c3a3.png","w":368,"h":187,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/1\/717f363fba88a8270ff65394cac2c3a3"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/7/1/717f363fba88a8270ff65394cac2c3a3-240.jpg" alt="590378" width="240" height="121" /></span><br />In this case, the black arrow represents our ball&#39;s velocity.  This arrow can be broken down into the red arrow (velocity in to the wall) and the green arrow (velocity parallel to the wall).<br />When you hit a wall, your motion parallel to the wall is unchanged.  Your motion &#39;in to&#39; the wall is either stopped (inelastic collision) or reversed (elastic collision).  So we first want to isolate: how much of the motion is &#39;in to&#39; the wall?  As noted above, that&#39;s: dot_product(normal, velocity).  Now, that&#39;s just a length, but we can make that a vector along the correct direction by simply scaling the normal: normal * dot_product(normal, velocity).  This should give us a vector equivalent to the red vector*.  Now, to change the black vector so it no longer has any motion &#39;in to&#39; the wall, we can simply subtract the red vector from the black vector.  To change the black vector so the ball bounces away from the wall, simply subtract the red vector an additional time.<br />In code, that&#39;s:<br /><span class="source-code">velocity <span class="k3">+</span><span class="k3">=</span> <span class="k2">(</span><span class="n">1</span> <span class="k3">+</span> elasticity<span class="k2">)</span> <span class="k3">*</span> <a href="http://www.allegro.cc/manual/dot_product" target="_blank"><span class="a">dot_product</span></a><span class="k2">(</span>velocity, normal<span class="k2">)</span> <span class="k3">*</span> normal<span class="k2">;</span></span></p><ul><li><p>you may be concerned that the dot_product(normal, velocity) will be negative, if the normal and velocity are in opposite directions.  This is true, but okay, because in this case the normal, when scaled by a negative, will reverse directions and again match the red vector as expected.</p></li></ul><p>Is this making sense?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Zaphos)</author>
		<pubDate>Thu, 26 Oct 2006 21:07:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I wrote the following code:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">typedef</span> <span class="k1">struct</span> Point2d <span class="k2">{</span></td></tr><tr><td class="number">2</td><td>        </td></tr><tr><td class="number">3</td><td>    <span class="k1">float</span> x, y<span class="k2">;</span></td></tr><tr><td class="number">4</td><td>        </td></tr><tr><td class="number">5</td><td><span class="k2">}</span> Point2d<span class="k2">;</span></td></tr><tr><td class="number">6</td><td>&#160;</td></tr><tr><td class="number">7</td><td><span class="k1">float</span> dotProduct<span class="k2">(</span> Point2d p1, Point2d p2 <span class="k2">)</span></td></tr><tr><td class="number">8</td><td><span class="k2">{</span></td></tr><tr><td class="number">9</td><td>    <span class="k1">return</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_738.html" target="_blank">sqrt</a><span class="k2">(</span> p1.x <span class="k3">*</span> p2.x <span class="k3">+</span> p1.y <span class="k3">*</span> p2.y <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">10</td><td><span class="k2">}</span></td></tr><tr><td class="number">11</td><td>&#160;</td></tr><tr><td class="number">12</td><td>&#160;</td></tr><tr><td class="number">13</td><td><span class="k1">int</span> main<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">14</td><td>    </td></tr><tr><td class="number">15</td><td>    <span class="k1">float</span> len1, len2, mag<span class="k2">;</span></td></tr><tr><td class="number">16</td><td>    Point2d p1, p2, delta, normal<span class="k2">;</span></td></tr><tr><td class="number">17</td><td>    </td></tr><tr><td class="number">18</td><td>    p1.x <span class="k3">=</span> <span class="n">100</span><span class="k2">;</span> p1.y <span class="k3">=</span> <span class="n">100</span><span class="k2">;</span></td></tr><tr><td class="number">19</td><td>    p2.x <span class="k3">=</span> <span class="n">200</span><span class="k2">;</span> p2.y <span class="k3">=</span> <span class="n">200</span><span class="k2">;</span></td></tr><tr><td class="number">20</td><td>    </td></tr><tr><td class="number">21</td><td>    len1 <span class="k3">=</span> dotProduct<span class="k2">(</span> p1, p1 <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>    len2 <span class="k3">=</span> dotProduct<span class="k2">(</span> p1, p2 <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">23</td><td>&#160;</td></tr><tr><td class="number">24</td><td>    delta.x <span class="k3">=</span> p2.x <span class="k3">-</span> p1.x<span class="k2">;</span></td></tr><tr><td class="number">25</td><td>    delta.y <span class="k3">=</span> p2.y <span class="k3">-</span> p1.y<span class="k2">;</span></td></tr><tr><td class="number">26</td><td>&#160;</td></tr><tr><td class="number">27</td><td>    mag <span class="k3">=</span> dotProduct<span class="k2">(</span> delta, delta <span class="k2">)</span><span class="k2">;</span>    </td></tr><tr><td class="number">28</td><td>    </td></tr><tr><td class="number">29</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"l1: %f | l2: %f | l3: %f"</span>, len1, len2, mag<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">30</td><td>    </td></tr><tr><td class="number">31</td><td>    <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">32</td><td>    </td></tr><tr><td class="number">33</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

And got these results:</p><div class="source-code snippet"><div class="inner"><pre>l1: <span class="n">141</span>.<span class="n">421356</span> <span class="k3">|</span> l2: <span class="n">200</span>.<span class="n">000000</span> <span class="k3">|</span> l3: <span class="n">141</span>.<span class="n">421356</span>
</pre></div></div><p>

Am I on the right track, here?</p><p>EDIT: Just saw the new post, reading!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ngiacomelli)</author>
		<pubDate>Thu, 26 Oct 2006 21:28:14 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
return sqrt( p1.x * p2.x + p1.y * p2.y );
</p></div></div><p>That&#39;s not a dot product.  That&#39;s the square root of a dot product.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
len2 = dotProduct( p1, p2 );
</p></div></div><p>I&#39;m not sure why you think that&#39;s len2.  Did you mean dotProduct( p2, p2 )?</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Am I on the right track, here?
</p></div></div><p>Well, I have no idea what you&#39;re trying to do, here.  The dot product can give the squared magnitude of a vector, if you take the dot product of a vector and itself, because then the cos is equal to 1.  But that&#39;s not really how you&#39;re going to be using the dot product for collision detection and response.</p><p>edit: Oh ... was that code in response to DanielH&#39;s now-mysteriously-absent post?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Zaphos)</author>
		<pubDate>Thu, 26 Oct 2006 21:32:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I was just converting DanielH&#39;s equations to code, initially. I&#39;ll have to read through your post. I&#39;m terrible when it comes to math. This will take me a while.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ngiacomelli)</author>
		<pubDate>Thu, 26 Oct 2006 21:35:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I goofed and erased my goof. I was hoping it wasn&#39;t viewed before I erased it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DanielH)</author>
		<pubDate>Fri, 27 Oct 2006 01:31:18 +0000</pubDate>
	</item>
</rss>
