tag:blogger.com,1999:blog-36085662474382429482018-08-29T06:57:16.520-04:00Damons Laboratory NotebookThis is the online laboratory notebook of Damon Bruccoleri.Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-3608566247438242948.post-87018472916720666442018-08-04T22:46:00.000-04:002018-08-04T22:57:19.738-04:00Cross Checking Systems<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody><tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-i_dfHSrD6aY/W2ZgRhdwsLI/AAAAAAAAVAg/ry8PAyem960NQWsZ37ZTKlbM1P7kr-3hwCK4BGAYYCw/s1600/crosschecking.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://3.bp.blogspot.com/-i_dfHSrD6aY/W2ZgRhdwsLI/AAAAAAAAVAg/ry8PAyem960NQWsZ37ZTKlbM1P7kr-3hwCK4BGAYYCw/s400/crosschecking.jpg" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Figure 1 - Typical Cross checking system.</td></tr></tbody></table> An interesting type of redundant system is the cross checking system. Cross checking systems increase the system <i>integrity.</i> In this system two identical computer systems run the processing in parallel. If the processing does not exactly match, a system fail is initiated. Cross checking systems are one way systems are designed to protect against single bit errors.<br /> The block diagram to the left depicts a typical system. Here are two processors, the control and the monitor processors. The system inputs must be identically applied to both processor. They may be sensor inputs, inputs for control, clocking,... In a deterministic system, both of these processors should have identical outputs for identical inputs. Both processors should calculate the same exact system output. Both processors monitor the other processors system output. Both processors compare their calculated output to the other processors output. If they do not match, the output line 'Mismatch' is asserted. The "System Fail" output is asserted if either processor declares a mismatch. There are two interesting things to note with this system. First is that only the output from the Control processor is actually used. The second is that although system integrity is increased, system reliability (which is measured in FIT or MTBF) will decrease. This is because if either processor fails, then the system fails. Although MTBF decreases, what is gained is the <i>knowledge</i> that the system has failed.<br /> In applications such as safety where integrity is important, cross checking systems are a very practical design possibility.Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.com0tag:blogger.com,1999:blog-3608566247438242948.post-78793720526455005062018-06-23T08:52:00.000-04:002018-07-15T21:43:26.722-04:00Byzantine networks and the Byzantine Generals ProblemIn some applications, networks and computer systems must be safe. Typically what we do is to use redundancy to protect against failures. If one component fails, another one takes over. As the tolerance for failure decreases, the cost and complexity of some of these systems increase. Byzantine networks study what happens when we have very little tolerance for failure. In fact, they consider what happens when one component does not just fail, but that component is malicious and tries to make the whole system fail.<br /><br />The Byzantine Generals are a metaphor for a distributed network. In this metaphor the Generals are each computers networked together, each giving orders to their connected components. What happens when one General is 'malicious'. I.e. it fails in a way that it tries to take down other generals? What protocol should the generals adhere to so they don't follow a malicious generals? So the rest of the system operates normally. <br /><br />Other than Byzantine networks there are other, less stringent architectures to protect against failures. These other solutions, such as redundancy and voting, relax the constraint of failure in various ways. <br /><br />Following is a Link for a proposal to identify malicious players in Byzantine Network. This proposal assumes the network is a modern TCP/IP network, so 'omission' faults are identified by the underlying network. <a href="https://damon-bruccoleri.github.io/three/CISD%20799%20ASS2%20PROPOSAL%202%20Damon%20Bruccoleri.pdf" target="_blank"> Click here to read the research proposal.</a>.Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.com0tag:blogger.com,1999:blog-3608566247438242948.post-60524531798237536032016-03-05T22:48:00.000-05:002016-03-06T07:59:44.825-05:00Interesting Circuit ProblemA while back I ran across a circuitry problem that may interest those with a little electronics knowledge. We were getting failures on a high percentage of new product, but not on all of them. The product was warning that its internal -15v supply was out of tolerance (and faulting). A manual check with a voltmeter showed the -15v supply was within the required +/-10% tolerance. Other internal supplies were monitored as well by the computer and they never exhibited this issue.<br /><br />Below is a schematic of the components involved, what I found, and the interesting solution. What this schematic is showing is three resistor divider circuits that divide down the +15, +5v and the -15 volt supplies to feed the A/D converter inputs (there is some additional filtering and protection not shown). <br /><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody><tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-EMnymZszhRM/Vtund4u-AfI/AAAAAAAALrU/SZ8glRtnTvc/s1600/Circuit2.JPG" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://1.bp.blogspot.com/-EMnymZszhRM/Vtund4u-AfI/AAAAAAAALrU/SZ8glRtnTvc/s1600/Circuit2.JPG" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Scaling Circuitry</td><td class="tr-caption" style="text-align: center;"><br /></td></tr></tbody></table>This A/D converter can resolve a range of 0v to +3v signal thus the need to divide down the voltages before conversion. Additionally the -15v rail voltage is 'translated' to a positive voltage by raising it with the +5V. The code in the computer then reads the A/D converter and looks to see if the value read is out of +/-10% tolerance.<br /><br />There is a problem though with the -15v divider circuit. Do you see it? The -15v circuit is dependent on the +5v voltage as well. So for instance if the +5v rail is 8% too high (within spec), and the -15v signal is 8% too low (also within spec), the resulting divided/translated voltage may be more than 10% out of whack (this is a highly technical term). The unit might then erroneously fault. I found a simple software change that put this issue to rest. We need to first read the +5 rail voltage. Then the -15v rail voltage is read and we subtract out the component of +5v rail voltage from the -15v reading. To do this requires some math and Kirchoff's voltage law.<br /><br /><div style="text-align: center;">V<sub>AD3</sub> = V<sub>+5v</sub> - ( V<sub>+5v</sub> - V<sub>-15v</sub>) R<sub>5</sub> /( R<sub>5</sub> + R<sub>6</sub>) </div><br />One note on the expression parameters, <span style="text-align: center;">V</span><sub style="text-align: center;">+5v</sub><span style="text-align: center;"> is the actual measured voltage of the +5V supply. This is obtained by reading the </span><span style="text-align: center;">V</span><sub style="text-align: center;">AD2</sub><span style="text-align: center;"> voltage first and calculating the +5V actual voltage. </span>Next we have to solve the equation for the unknown voltage, V<sub>-15</sub> :<br /><div style="text-align: center;"><br /></div><div style="text-align: center;">V<sub>-15v</sub> = (V<sub>+5v</sub> - V<sub>AD3</sub>)(R<sub>5</sub> + R<sub>6</sub>)/R<sub>5</sub> + V<sub>+5v</sub> </div><br />Everything on the right hand side is known. I implemented this equation in the firmware of the computer and it worked like a charm! I implemented it, but did not consider this solution to be optimal. In subsequent designs I made sure we did not use the +5v supply to translate the -15v supply voltage, but for this product this software solution had several benefits:<br /><br /><ul><li>Easy fix for units already in field. No recall. </li><li>No waste for already manufactured inventory. We can use existing stuffed pcb's. </li><li>We did not need to delay an already delayed product. </li><li>No additional cost for the pcb NRE.</li></ul>There were some other issues with this solution, scaling issues and floating point issues, but those are for another lab note.<br /><br />Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.com0tag:blogger.com,1999:blog-3608566247438242948.post-31230451437358852272016-02-20T18:54:00.000-05:002016-02-20T18:59:15.794-05:00Why is aliasing important to A/D converters?To minimize aliasing an anti-aliasing filter is needed before an A/D converter. How do you design this pre-filter? What is this aliasing? Shannon, and Nyquist later, said that the maximum signal we can reconstruct is half of the sampling rate. If the signal we sample has components higher than 1/2 sampling rate then we get a phenomena called 'aliasing. If I were to send an aliased signal back out of a computer to a D/A converter it would look like the signal was 'shifted' in frequency. <br /><br />Suppose a signal of F<sub>s</sub> was put into an A/D converter and the sampling rate was F<sub>s</sub>. It might appear on a D/A converter as a DC signal .<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-bC1iF_zMJmo/Vsj7Cd3PreI/AAAAAAAALbk/GDurhG74NUo/s1600/Sampled%2BImage.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://1.bp.blogspot.com/-bC1iF_zMJmo/Vsj7Cd3PreI/AAAAAAAALbk/GDurhG74NUo/s200/Sampled%2BImage.jpg" width="200" /></a></div>As an everyday example of aliasing, have you ever seen a moving fan appear still under a strobe light? When the strobe is blinking at the same rpm's as the fans rotational speed, the fan will appear motionless. The aliasing phenomena can occur if the sampled signal is at or above 1/2 the sampling rate OR IF IT HAS (Fourier) COMPONENTS AT OR ABOVE THIS RATE. In this case just those components above the Nyquist rate would be aliased, but the total signal, if reconstructed, will be distorted.<br /><br />How do we design to this? Typically we use an anti-aliasing filter on the front end of the A/D. This filter is designed to attenuate signal above the Nyquist rate to below some noise level. It might be as simple as an RC or more complicated as a multi-pole active filter in a Chebychev or Butterworth configuration. The key is to understand how much attenuation we need at the stop band. Suppose our A/D is 12 bits. The ideal SNR is 72dB (= 20* log(4096)). The filter should be designed to provide 72 db of attenuation at the stop band. Now we note that a single pole filter provides 6db per octave of attenuation.<br /><br />A single pole low pass filter designed to attenuate a signal to this noise specification would be designed to have a cutoff 12 octaves below half the A/D sampling rate!Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.com0tag:blogger.com,1999:blog-3608566247438242948.post-27122241396781429862016-02-14T22:46:00.001-05:002016-03-05T22:56:29.014-05:00How to find a short on a PCB<div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-uBWoQl2mjPU/VsFJmqgGBoI/AAAAAAAALZw/1wL-GXx59qw/s1600/PCB_complete_sm.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="191" src="https://3.bp.blogspot.com/-uBWoQl2mjPU/VsFJmqgGBoI/AAAAAAAALZw/1wL-GXx59qw/s200/PCB_complete_sm.jpg" width="200" /></a></div>When I am troubleshooting new PCB's I have a unique technique for finding shorts on PCB's. I actually have to hand the credit for this technique to a business partner, Dr. Ed Kafrissen. He came up with this idea. So let me set up a scenario for you, and then show you Ed's solution. Suppose you have a client and you need to deliver 100 PCB's to him/her quickly. You have someone stuff the boards for you, now you have to verify they work.<br /><br />One of the first tests we would do is to apply power to the new PCB and bring the voltage up slowly. Perhaps without any chips installed. If the power supplies load down, then you got a problem to solve. You got a short on the PCB.<br /><br /><a href="https://1.bp.blogspot.com/-t8kwxlY8aak/VsFJQNirmNI/AAAAAAAALZs/6EI3j6DRpaM/s1600/Imaging%2BThermometer.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://1.bp.blogspot.com/-t8kwxlY8aak/VsFJQNirmNI/AAAAAAAALZs/6EI3j6DRpaM/s200/Imaging%2BThermometer.jpg" width="200" /></a>Ed came up with simple and unique solution. He would current limit a power supply to some small current, and at the rated voltage of the pcb. Ed would then hook up the PCB, which immediately loaded down the current limited supply. He would turn up the current on the supply as he felt on the PCB for a hot spot! Invariably some IC would be stuffed in backwards that our visual inspection did not find, or we would get a PCB which was not completely etched. Alternatively, you can use a handheld IR imaging thermometer to pinpoint the hot-spot.<br /><br /><br />Anyway, that was Ed's solution to quickly find shorts on a PCB...and it worked well as long as you were careful enough to not burn yourself! Yeow!Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.com0tag:blogger.com,1999:blog-3608566247438242948.post-59335371181320994162016-02-07T14:58:00.001-05:002016-02-07T15:00:30.428-05:00The Exponential Digital Lowpass FilterIn the last lab note we looked at the boxcar filter structure. That was an example of an FIR filter. The exponential filter is an IIR filter. If I need a little filtering I usually use this filter structure. In a simple implementation of this filter we calculate the filter output by taking the current sample, adding it to the previous output then dividing by 2. Mathematically y=(x+yz<sup>-1</sup>) ; where y is the current output, x is the current input, and yz<sup>-1</sup>is the previous output. The z<sup>-1</sup> term shifts back in time 1 sample period. Since the output is a function of the previous output this is an Infinite Impulse Response filter, or IIR filter.<br /><br />In a typical embedded system we work with a fixed point math.<br /><br />For the above function the characteristic equation is H(z) = Y/X = 1/(2-z<sup>-1</sup>)= z/(2z<sup>-1</sup>); There is a zero at 0 and a single pole at z=1/2. This is within the unit circle, thus the filter is stable. To plot the frequency response we set z=e<sup>jωT</sup>. Then we normalize by setting T=1. <a href="http://www.wolframalpha.com/input/?i=log+plot+abs%28+1%2F%282-exp%28-2PI*iw%29%29%29+between+0+and+1" target="_blank">We can use Wolfram Alpha to plot the equation H(ω) = 1/(2-e<sup>-jω</sup>) . Click this link to see plot.</a> I copied the plot here for convenience.<br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-3ABeBXY22c0/Vref7AjCyFI/AAAAAAAALXU/G_JU6ibvyjY/s1600/plot%2B1.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="157" src="https://1.bp.blogspot.com/-3ABeBXY22c0/Vref7AjCyFI/AAAAAAAALXU/G_JU6ibvyjY/s320/plot%2B1.gif" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Exponential Lowpass Filter response.</td></tr></tbody></table><br />Here the horizontal axis is in Hz This filter attenuates to 0.7 at a frequency of 0.14Hz (remember this equation is normalized to a sampling frequency of 1 Hz).<br /><br />If this is too much filtering, or too little filtering you can try adjusting the weighting of the two terms in the exponential filter. For instance, what if you choose the weighting y = ¼ (3x + yz<sup>-2</sup>)? Here I tried to use a power of 2 divisor to make the math dead nuts simple to implement on a fixed point processor. On an FPGA you would not even need to divide or shift, just pick off the right bits. The FPGA would need just two 'add' operations. Can you calculate the frequency domain function and plot it?<br /><br />If you have any other common filter questions, leave a comment for future discussion.Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.com0tag:blogger.com,1999:blog-3608566247438242948.post-27803885569052584012016-01-31T22:01:00.004-05:002016-02-07T14:58:24.507-05:00The Boxcar Digital Lowpass FilterIn embedded systems it is quite common to need a little bit of filtering on analog quantities. Programmers sometimes feel they need the filtering to help smooth any analog conversion noise. Two type of filters commonly used are the Boxcar and the Exponential filter. Both are simple to implement. Its important to understand the impact these filters have on delay and frequency response, and to evaluate their comparative effectiveness.<br /><br />The Boxcar filter is a simple averaging filter. Technically it is an FIR filter. Typically you would obtain your next analog value, add it to the last n-1 values read, then divide by n. It's just a simple average of the last few values read.<br /><br />A common value for n is 4. The Z transform of a filter with n=4 is H(z) = ¼ (z<sup>3</sup>+z<sup>2</sup>+z+1)/(z<sup>3</sup>) . There are three poles at the origin in the Z domain. Thus this filter is stable. There is one real zero at -1, and two complex conjugate zero's at +i and -i. The (normalized) frequency response is given by <a href="http://www.wolframalpha.com/input/?i=log+plot+abs%281%2F4%2B+1%2F4*exp%28-2PI*iw%29+%2B+1%2F4*exp%28-2PI*2iw%29%2B1%2F4*exp%28-2PI*3iw%29%29+between+0+and+1%22" target="_blank">H(e<sup>jω</sup>) = magnitude(¼ + ¼e<sup>-jω</sup>+ ¼e<sup>-j2ω</sup>+¼e<sup>-j3ω</sup>)</a>.<br />Click on the link to use Wolfram-Alpha to plot this function. In the following image (copied from Wolfram) we see several cycles of normalized frequency response including mirroring above half the sample rate. The mirroring is how aliasing shows up in the frequency response.<br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="http://www.wolframalpha.com/input/?i=log+plot+abs%281%2F4%2B+1%2F4*exp%28-2PI*iw%29+%2B+1%2F4*exp%28-2PI*2iw%29%2B1%2F4*exp%28-2PI*3iw%29%29+between+0+and+1" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"><img alt="" border="0" height="192" src="https://4.bp.blogspot.com/-ATHGHmtD5Ts/Vq7F9XBPP8I/AAAAAAAALBI/B63Ux5jXqW4/s400/plot2.gif" title="Boxcar filter response" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><a href="http://www.wolframalpha.com/input/?i=log+plot+abs%281%2F4%2B+1%2F4*exp%28-2PI*iw%29+%2B+1%2F4*exp%28-2PI*2iw%29%2B1%2F4*exp%28-2PI*3iw%29%29+between+0+and+1" target="_blank">Box Car Filter Normalized Response. N=4.</a></td></tr></tbody></table><br />Note that the horizontal axis is in Hz. The sampling frequency is 1Hz. (The response is normalized to 1 Hz.) One half the sample rate is 0.5Hz - the Nyquist rate. What you are seeing above 0.5Hz is a periodic mirror of the response. But lets focus on the response below 0.5 Hz. How UGLY for a low pass response. Lets try to plot the response for n=2. With this filter all we do is add the current and previous samples and divide by 2. The characteristic equation is Y = ½(X + Xz<sup>-1</sup>) . The transfer function is H(z) = ½(1+z<sup>-1</sup>) = ½(1+z)/z . This has a single pole at 0 and a zero at -1. Thus its stable. The normalized frequency domain function H(e<sup>jω</sup>) = ½(1+e<sup>-jω</sup>). Its normalized for a sample time of 1sec. <a href="http://www.wolframalpha.com/input/?i=log+plot+abs%281%2F2%281%2Bexp%28-2*i*w*pi%29%29%29+between+0+and+1" target="_blank">Click here to have Wolfram Alpha plot the response.</a><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="http://www.wolframalpha.com/input/?i=log+plot+abs%281%2F2%281%2Bexp%28-2*i*w*pi%29%29%29+between+0+and+1" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"><img border="0" height="192" src="https://2.bp.blogspot.com/-LNuN0uncFIc/Vq7KBJAyW3I/AAAAAAAALBU/220ndSkZQ7U/s400/plot%2B3.gif" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><a href="http://www.wolframalpha.com/input/?i=log+plot+abs%281%2F2%281%2Bexp%28-2*i*w*pi%29%29%29+between+0+and+1" target="_blank">Box Car Filter Normalized Response. N=2.</a></td><td class="tr-caption" style="text-align: center;"><a href="http://www.wolframalpha.com/input/?i=log+plot+abs%281%2F2%281%2Bexp%28-2*i*w*pi%29%29%29+between+0+and+1" target="_blank"><br /></a></td></tr></tbody></table> This looks more like a low pass response. Note that the horizontal axis this time is in Hz. Since the sample time is a normalized 1second, then the sample frequency is 1.0 Hz, and the Nyquist frequency is 0.5 Hz.<br /><br />In my next Laboratory Note we will look at the Exponential Filter. This is actually my favorite and I will show you why!Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.com0tag:blogger.com,1999:blog-3608566247438242948.post-46525598445258824942016-01-24T08:32:00.000-05:002018-07-13T05:52:15.364-04:003D web graphics.A new feature of modern web browsers is web.gl. This language allows browsers to take advantage of the hardware graphics acceleration in your computer. Its a little awkward to program in so the three.js library was born. Its an open source project. To learn this framework I created some experiments. Please click on the links below. The images can be rotated and panned with your mouse.<br /><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass1/OT1.js" target="_blank">A starburst pattern</a> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass1/OT2.js" target="_blank">A cylinder made of lines</a><br /> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass1/ST1.js" target="_blank">A flat Square </a> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass1/ST2.js" target="_blank">An open cube with shading </a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass1/ST3.js" target="_blank">Polygon with gradient coloring</a> - these were some simple, first experiments<br /><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass2/HGG1.js" target="_blank">Stairway with Shading</a> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass2/HGG2.js" target="_blank">Mesh a Cylinder </a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass2/HGG3.js" target="_blank">Mesh a segmented Cylinder</a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass2/HGG4.js" target="_blank">Mesh a Cylinder turned into a vase</a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass2/HGG5.js" target="_blank">Mesh a Cylinder turned into a torus</a> - these are meshed from many tiny, individual<br />triangles. They do not use the Three.js premeshed objects.<br /><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass4/ba1.js" target="_blank">Cube matrix with animated color</a> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass4/ba2.js" target="_blank">An animated solar system</a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass3/MC1.js" target="_blank">Bunch of Boxes </a> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass3/MC2.js" target="_blank">A ziggurat</a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass3/MC3.js" target="_blank">A ziggurat with controls</a> <br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass3/MC4.js" target="_blank">A helix of objects</a> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass3/MC5.js" target="_blank">A helix of any 'ole object</a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass1/OT2.js" target="_blank"></a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass4/c1.js" target="_blank">Citi-scape</a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass4/ba1.js" target="_blank">Cubes changing color</a> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass4/ba2.js" target="_blank">A tiny solar system</a><br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=ass3/SG1.js" target="_blank">A torus explorer</a> <a href="https://damon-bruccoleri.github.io/three/index.html?load=ass4/mfwa1.js" target="_blank">Click square to make wave</a><br /><br />Finally, these are some water simulations. Click on the water to make waves.:<br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=Project%20Hugo%20Elias.js" target="_blank">Hugo Elias Algorithm</a> - makes multiple waves with interference at edges<br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=Project%20Transverse%20Wave.js" target="_blank">Transverse Wave Algorithm</a> - can make 1 wave at a time.<br /><a href="https://damon-bruccoleri.github.io/three/index.html?load=mfwa1.js" target="_blank">Another algorithm</a>Damonhttp://www.blogger.com/profile/11196987084860577646noreply@blogger.com0