Learning JRubyArt Here I will write about JRubyArt. https://monkstone.github.io/ Sat, 04 Dec 2021 07:02:05 +0000 Sat, 04 Dec 2021 07:02:05 +0000 Jekyll v3.9.0 Plans For Future Development <h4 id="subtle-changes-for-vec2d">Subtle Changes for Vec2D</h4> <p>Recent discussions about vectors and the py5 project persuaded me to prefer wedge product over cross product for 2D vectors (since by definition there is no such thing as cross product that returns a scalar). In the first instance I will keep the cross product in the api, but it will be deprecated in favor of the <code class="language-plaintext highlighter-rouge">^</code> (wedge product operator). See <a href="https://github.com/ruby-processing/picrate-examples/blob/master/demo/library/circle/lib/t_points.rb">PiCrate example</a> <code class="language-plaintext highlighter-rouge">:collinear?</code> method.</p> <h4 id="use-of-jdk17">Use of jdk17</h4> <p>Initially propane will be changed to require jdk17 (probably by xmas 2017), for JRubyArt and PiCrate, I will wait to see what processing.org and jruby.org do, there will be no going back otherwise the change will be pointless (since I am currently using jdk 17 to test and run both projects)!!!</p> Sat, 04 Dec 2021 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2021/12/04/Development-Plans.html https://monkstone.github.io/jruby_art/update/2021/12/04/Development-Plans.html jruby_art update Instance Of Pattern Matching <p>Recently I’ve been exploring the goodies to come when I upgrade my ruby-processing projects to jdk17 (might happen this christmas or before if vanilla processing gets there 1st). Since JRuby14 we have:-</p> <h4 id="pattern-matching-for-instanceof-in-java">Pattern Matching for instanceof in Java</h4> <p><strong>From my Vec2D implementation in java</strong></p> <p>See also <a href="https://blogs.oracle.com/javamagazine/post/pattern-matching-for-instanceof-in-java-14/">oracle tutorial</a></p> <p>Original:-</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">public</span> <span class="kt">double</span> <span class="n">jx</span><span class="o">;</span> <span class="cm">/** * * @param context ThreadContext * @param other IRubyObject * @return x IRubyObject */</span> <span class="nd">@JRubyMethod</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"x="</span><span class="o">)</span> <span class="kd">public</span> <span class="nc">IRubyObject</span> <span class="nf">setX</span><span class="o">(</span><span class="nc">ThreadContext</span> <span class="n">context</span><span class="o">,</span> <span class="nc">IRubyObject</span> <span class="n">other</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">other</span> <span class="k">instanceof</span> <span class="nc">RubyFloat</span><span class="o">)</span> <span class="o">{</span> <span class="n">jx</span> <span class="o">=</span> <span class="o">((</span><span class="nc">RubyFloat</span><span class="o">)</span> <span class="n">other</span><span class="o">).</span><span class="na">getValue</span><span class="o">();</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="n">jx</span> <span class="o">=</span> <span class="o">((</span><span class="nc">RubyFixnum</span><span class="o">)</span> <span class="n">other</span><span class="o">).</span><span class="na">getDoubleValue</span><span class="o">();</span> <span class="o">}</span> <span class="k">return</span> <span class="n">other</span><span class="o">;</span> <span class="o">}</span> </code></pre></div></div> <p>Since jdk14 looks safer, gets rid of ugly casting.</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/** * * @param context ThreadContext * @param other IRubyObject * @return y IRubyObject */</span> <span class="nd">@JRubyMethod</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"x="</span><span class="o">)</span> <span class="kd">public</span> <span class="nc">IRubyObject</span> <span class="nf">setY</span><span class="o">(</span><span class="nc">ThreadContext</span> <span class="n">context</span><span class="o">,</span> <span class="nc">IRubyObject</span> <span class="n">other</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">other</span> <span class="k">instanceof</span> <span class="nc">RubyFloat</span> <span class="n">rubyFloat</span><span class="o">)</span> <span class="o">{</span> <span class="n">jx</span> <span class="o">=</span> <span class="n">rubyFloat</span><span class="o">.</span><span class="na">getValue</span><span class="o">();</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">other</span> <span class="k">instanceof</span> <span class="nc">RubyFixnum</span> <span class="n">rubyFixnum</span><span class="o">)</span> <span class="o">{</span> <span class="n">jx</span> <span class="o">=</span> <span class="n">rubyFixnum</span><span class="o">.</span><span class="na">getDoubleValue</span><span class="o">();</span> <span class="o">}</span> <span class="k">return</span> <span class="n">other</span><span class="o">;</span> <span class="o">}</span> </code></pre></div></div> <p>Another attractive looking feature is switch expression which can be quite useful in simplifying code. <a href="https://docs.oracle.com/en/java/javase/15/language/switch-expressions.html">See oracle tutorial</a>, article to follow here.</p> Sat, 16 Oct 2021 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2021/10/16/PatternInstanceOf.html https://monkstone.github.io/jruby_art/update/2021/10/16/PatternInstanceOf.html jruby_art update Extending JRuby, Compile and Jar Java Extension Code <h2 id="do-you-want-to-create-a-jruby-extension">Do you want to create a JRuby extension?</h2> <p>Previously you may have seen guides by <a href="https://yokolet.blogspot.com/2011/06/extending-jruby-compile-and-jar-java.html">Yoko Harada (yokolet)</a> and <a href="https://blog.jcoglan.com/2012/08/02/your-first-ruby-native-extension-java/">James Coglan</a> which suggest you use the <a href="https://github.com/rake-compiler/rake-compiler">Rake-Compiler</a> to compile your code. However those recommendations were made before the <a href="https://github.com/takari/polyglot-maven">polyglot maven compiler</a> existed, which is now the recommended way to compile and jar your ruby code. You can now write your pom file in ruby (and get regular pom.xml emitted useful when working with a java ide such as netbeans). For a basic example see <a href="https://github.com/jruby/jruby-examples/tree/master/extensions/basic/jruby-ext">jruby-examples</a> which demonstrates how to create a ruby class and ruby module in java. The article by <a href="https://blog.jcoglan.com/2012/08/02/your-first-ruby-native-extension-java/">James Coglan</a> remains in interesting, as it shows how you should create a java extension of a gem with an existing MRI extension. The beauty of maven is that you can pull in jar dependencies from maven central including jruby-base.jar which is the recommended jruby dependency when compiling jruby extension (<em>was jruby.jar but that may cause dependency conflicts</em>).</p> <p>For a JRubyArt example see the <a href="https://github.com/ruby-processing/JRubyArt/blob/master/src/main/java/monkstone/vecmath/vec3/Vec3.java">Vec3D class</a>, you can use/abuse this class like any regular ruby class, it can be monkey-patched or refined like any other ruby class see a <a href="https://monkstone.github.io/jruby_art/update/2021/09/26/refinements.html">previous blog entry</a>. Another interesting example is the <a href="https://github.com/ruby-processing/JRubyArt/blob/master/src/main/java/monkstone/MathToolModule.java">MathTool module</a> in particular the <code class="language-plaintext highlighter-rouge">grid</code> and <code class="language-plaintext highlighter-rouge">mesh_grid</code> methods, which demonstrates how to create a method that takes a ruby block (uses yield).</p> <p>See also this <a href="https://github.com/jruby/jruby/wiki/Java-extensions-for-JRuby-using-polyglot-maven">jruby wiki entry</a>.</p> <h3 id="creating-a-maven-wrapper">Creating a maven wrapper</h3> <p>If you want to specify the a version of of maven used, or allow users to build your project without installing maven, you could add a maven wrapper, to do this run the following command in your project folder:-</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn <span class="nt">-N</span> io.takari:maven:wrapper <span class="nt">-Dmaven</span><span class="o">=</span>3.8.3 </code></pre></div></div> <p>Users are then able to build your project using the local maven wrapper command <code class="language-plaintext highlighter-rouge">mvnw</code> on unix based systems or <code class="language-plaintext highlighter-rouge">mvnw.cmd</code> on windows. In practice you will probably create a <code class="language-plaintext highlighter-rouge">Rakefile</code> at this stage, which will use the wrapper command to execute maven tasks in order. See for example <a href="https://github.com/ruby-processing/JRubyArt/blob/master/Rakefile">Rakefile</a> for JRubyArt.</p> Sat, 09 Oct 2021 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2021/10/09/JRubyExtension.html https://monkstone.github.io/jruby_art/update/2021/10/09/JRubyExtension.html jruby_art update Processing4 on RaspberryPI4 <p>Currently vanilla Processing4 does not support running on the RaspberryPI. Previously processing was restricted to running on Buster (now RaspbianOS) in 32 bit mode. For the future jdk17+ support is likely to be 64 bit mode. Thus there is strong case for using a 64 bit OS on RaspberryPI3 and RaspberryPI4, and I would recommend <a href="https://manjaro.org/downloads/arm/raspberry-pi-4/arm8-raspberry-pi-4-xfce/">ManjaroArm (XFCE)</a>.</p> <h4 id="create-and-run-processing-sketches-in-ruby-using-picrate-approximates-to-processing4">Create and run processing sketches in Ruby using PiCrate (approximates to processing4)</h4> <p>I’ve released a <a href="https://discourse.processing.org/t/new-release-of-picrate-for-raspberrypi/32424">new version</a> of <a href="https://ruby-processing.github.io/PiCrate/">PiCrate</a> which works on both RaspberryPI4 and RaspberryPI3B+ with both 32 bit (RaspbianOS) and 64 bit (Manjaro Arm) operating systems. However in the longterm I’m likely to be dropping 32 bit support.</p> <p><img src="/assets/steinberg.png" /></p> <p>This above sketch is using the regular processing video library and a USB camera, you should not need to use <a href="https://github.com/gohai/processing-glvideo">legacy driver</a>…</p> <h4 id="you-can-also-create-and-run-py5-sketches-on-manjaroarm-raspbianos-is-untested">You can also create and run py5 sketches on ManjaroArm (RaspbianOS is untested)</h4> <p>See processing <a href="https://discourse.processing.org/t/using-geany-ide-for-py5-on-raspberrypi/32236">forum</a></p> Fri, 08 Oct 2021 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2021/10/08/ManjaroArm.html https://monkstone.github.io/jruby_art/update/2021/10/08/ManjaroArm.html jruby_art update Refinements vs Monkey Patching <p>Since ruby-2.4.0 there is an alternative to monkey-patching. See Ribbon Doodle sketches.</p> <h3 id="monkey-patching">Monkey Patching</h3> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env jruby -w</span> <span class="c1"># frozen_string_literal: true</span> <span class="nb">require</span> <span class="s1">'picrate'</span> <span class="c1"># Adapted to use Processing Vec2D and Vec3D classes by Martin Prout</span> <span class="c1"># Use Face Struct triangle 'mesh'.</span> <span class="no">Face</span> <span class="o">=</span> <span class="no">Struct</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:a</span><span class="p">,</span> <span class="ss">:b</span><span class="p">,</span> <span class="ss">:c</span><span class="p">)</span> <span class="c1"># triangle mesh face</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">class_eval</span> <span class="k">do</span> <span class="c1"># re-open the Vec3D class to add rotation functionality</span> <span class="k">def</span> <span class="nf">rotate_y</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">co</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">si</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">xx</span> <span class="o">=</span> <span class="n">co</span> <span class="o">*</span> <span class="n">x</span> <span class="o">-</span> <span class="n">si</span> <span class="o">*</span> <span class="n">z</span> <span class="nb">self</span><span class="p">.</span><span class="nf">z</span> <span class="o">=</span> <span class="n">si</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="n">co</span> <span class="o">*</span> <span class="n">z</span> <span class="nb">self</span><span class="p">.</span><span class="nf">x</span> <span class="o">=</span> <span class="n">xx</span> <span class="nb">self</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">rotate_x</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">co</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">si</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">zz</span> <span class="o">=</span> <span class="n">co</span> <span class="o">*</span> <span class="n">z</span> <span class="o">-</span> <span class="n">si</span> <span class="o">*</span> <span class="n">y</span> <span class="nb">self</span><span class="p">.</span><span class="nf">y</span> <span class="o">=</span> <span class="n">si</span> <span class="o">*</span> <span class="n">z</span> <span class="o">+</span> <span class="n">co</span> <span class="o">*</span> <span class="n">y</span> <span class="nb">self</span><span class="p">.</span><span class="nf">z</span> <span class="o">=</span> <span class="n">zz</span> <span class="nb">self</span> <span class="k">end</span> <span class="k">end</span> <span class="k">class</span> <span class="nc">Doodle</span> <span class="o">&lt;</span> <span class="no">Processing</span><span class="o">::</span><span class="no">App</span> <span class="c1"># After a toxiclibs "MeshDoodle" sketch by Karsten Schmidt</span> <span class="c1"># Adapted to use JRubyArt Vec2D and Vec3D classes by Martin Prout</span> <span class="c1"># Note: The extension of Vec3D class to support rotations, and the ruby Struct</span> <span class="c1"># Face for triangle 'mesh'. Also an example of AppRenderer for Vec3D =&gt; vertex</span> <span class="nb">attr_reader</span> <span class="ss">:prev</span><span class="p">,</span> <span class="ss">:p</span><span class="p">,</span> <span class="ss">:q</span><span class="p">,</span> <span class="ss">:rotation</span><span class="p">,</span> <span class="ss">:faces</span><span class="p">,</span> <span class="ss">:pos</span><span class="p">,</span> <span class="ss">:weight</span> <span class="k">def</span> <span class="nf">settings</span> <span class="n">size</span><span class="p">(</span><span class="mi">600</span><span class="p">,</span> <span class="mi">600</span><span class="p">,</span> <span class="no">P3D</span><span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">setup</span> <span class="n">sketch_title</span> <span class="s1">'Ribbon Doodle'</span> <span class="vi">@weight</span> <span class="o">=</span> <span class="mi">0</span> <span class="vi">@prev</span> <span class="o">=</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span> <span class="vi">@p</span> <span class="o">=</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span> <span class="vi">@q</span> <span class="o">=</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span> <span class="vi">@rotation</span> <span class="o">=</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span> <span class="vi">@faces</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">draw</span> <span class="n">background</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="n">lights</span> <span class="n">translate</span><span class="p">(</span><span class="n">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="n">height</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="n">rotate_x</span><span class="p">(</span><span class="n">rotation</span><span class="p">.</span><span class="nf">x</span><span class="p">)</span> <span class="n">rotate_y</span><span class="p">(</span><span class="n">rotation</span><span class="p">.</span><span class="nf">y</span><span class="p">)</span> <span class="n">no_stroke</span> <span class="n">begin_shape</span><span class="p">(</span><span class="no">TRIANGLES</span><span class="p">)</span> <span class="c1"># iterate over all faces/triangles of the 'mesh'</span> <span class="n">faces</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="c1"># create vertices for each corner point</span> <span class="n">f</span><span class="p">.</span><span class="nf">a</span><span class="p">.</span><span class="nf">to_vertex</span><span class="p">(</span><span class="n">renderer</span><span class="p">)</span> <span class="n">f</span><span class="p">.</span><span class="nf">b</span><span class="p">.</span><span class="nf">to_vertex</span><span class="p">(</span><span class="n">renderer</span><span class="p">)</span> <span class="n">f</span><span class="p">.</span><span class="nf">c</span><span class="p">.</span><span class="nf">to_vertex</span><span class="p">(</span><span class="n">renderer</span><span class="p">)</span> <span class="k">end</span> <span class="n">end_shape</span> <span class="c1"># update rotation</span> <span class="vi">@rotation</span> <span class="o">+=</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mf">0.014</span><span class="p">,</span> <span class="mf">0.0237</span><span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">mouse_moved</span> <span class="c1"># get 3D rotated mouse position</span> <span class="vi">@pos</span> <span class="o">=</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">mouse_x</span> <span class="o">-</span> <span class="n">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="n">mouse_y</span> <span class="o">-</span> <span class="n">height</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="n">pos</span><span class="p">.</span><span class="nf">rotate_x</span><span class="p">(</span><span class="n">rotation</span><span class="p">.</span><span class="nf">x</span><span class="p">)</span> <span class="n">pos</span><span class="p">.</span><span class="nf">rotate_y</span><span class="p">(</span><span class="n">rotation</span><span class="p">.</span><span class="nf">y</span><span class="p">)</span> <span class="c1"># use distance to previous point as target stroke weight</span> <span class="vi">@weight</span> <span class="o">+=</span> <span class="p">(</span><span class="n">sqrt</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="nf">dist</span><span class="p">(</span><span class="n">prev</span><span class="p">))</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">-</span> <span class="n">weight</span><span class="p">)</span> <span class="o">*</span> <span class="mf">0.1</span> <span class="c1"># define offset points for the triangle strip</span> <span class="n">a</span> <span class="o">=</span> <span class="n">pos</span> <span class="o">+</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">weight</span><span class="p">)</span> <span class="n">b</span> <span class="o">=</span> <span class="n">pos</span> <span class="o">+</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="n">weight</span><span class="p">)</span> <span class="c1"># add 2 faces to the mesh</span> <span class="n">faces</span> <span class="o">&lt;&lt;</span> <span class="no">Face</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">p</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">q</span><span class="p">)</span> <span class="n">faces</span> <span class="o">&lt;&lt;</span> <span class="no">Face</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">p</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span> <span class="c1"># store current points for next iteration</span> <span class="vi">@prev</span> <span class="o">=</span> <span class="n">pos</span> <span class="vi">@p</span> <span class="o">=</span> <span class="n">a</span> <span class="vi">@q</span> <span class="o">=</span> <span class="n">b</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">renderer</span> <span class="vi">@renderer</span> <span class="o">||=</span> <span class="no">GfxRender</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">g</span><span class="p">)</span> <span class="k">end</span> <span class="k">end</span> <span class="no">Doodle</span><span class="p">.</span><span class="nf">new</span> </code></pre></div></div> <h3 id="refinement-alternative">Refinement Alternative</h3> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Use Face Struct triangle 'mesh'.</span> <span class="no">Face</span> <span class="o">=</span> <span class="no">Struct</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:a</span><span class="p">,</span> <span class="ss">:b</span><span class="p">,</span> <span class="ss">:c</span><span class="p">)</span> <span class="c1"># triangle mesh face</span> <span class="nb">require</span> <span class="s1">'picrate'</span> <span class="c1"># Using refinements with the Vec3D class to support rotations</span> <span class="k">module</span> <span class="nn">RotateVec3D</span> <span class="n">refine</span> <span class="no">Vec3D</span> <span class="k">do</span> <span class="k">def</span> <span class="nf">rotate_y!</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">co</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">si</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">xx</span> <span class="o">=</span> <span class="n">co</span> <span class="o">*</span> <span class="n">x</span> <span class="o">-</span> <span class="n">si</span> <span class="o">*</span> <span class="n">z</span> <span class="nb">self</span><span class="p">.</span><span class="nf">z</span> <span class="o">=</span> <span class="n">si</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="n">co</span> <span class="o">*</span> <span class="n">z</span> <span class="nb">self</span><span class="p">.</span><span class="nf">x</span> <span class="o">=</span> <span class="n">xx</span> <span class="nb">self</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">rotate_x!</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">co</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">si</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="n">zz</span> <span class="o">=</span> <span class="n">co</span> <span class="o">*</span> <span class="n">z</span> <span class="o">-</span> <span class="n">si</span> <span class="o">*</span> <span class="n">y</span> <span class="nb">self</span><span class="p">.</span><span class="nf">y</span> <span class="o">=</span> <span class="n">si</span> <span class="o">*</span> <span class="n">z</span> <span class="o">+</span> <span class="n">co</span> <span class="o">*</span> <span class="n">y</span> <span class="nb">self</span><span class="p">.</span><span class="nf">z</span> <span class="o">=</span> <span class="n">zz</span> <span class="nb">self</span> <span class="k">end</span> <span class="k">end</span> <span class="k">end</span> <span class="c1"># After a toxiclibs "MeshDoodle" sketch by Karsten Schmidt</span> <span class="k">class</span> <span class="nc">Doodle</span> <span class="o">&lt;</span> <span class="no">Processing</span><span class="o">::</span><span class="no">App</span> <span class="n">using</span> <span class="no">RotateVec3D</span> <span class="nb">attr_reader</span> <span class="ss">:prev</span><span class="p">,</span> <span class="ss">:p</span><span class="p">,</span> <span class="ss">:q</span><span class="p">,</span> <span class="ss">:rotation</span><span class="p">,</span> <span class="ss">:faces</span><span class="p">,</span> <span class="ss">:pos</span><span class="p">,</span> <span class="ss">:weight</span> <span class="k">def</span> <span class="nf">settings</span> <span class="n">size</span><span class="p">(</span><span class="mi">600</span><span class="p">,</span> <span class="mi">600</span><span class="p">,</span> <span class="no">P3D</span><span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">setup</span> <span class="n">sketch_title</span> <span class="s1">'Ribbon Doodle'</span> <span class="vi">@weight</span> <span class="o">=</span> <span class="mi">0</span> <span class="vi">@prev</span> <span class="o">=</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span> <span class="vi">@p</span> <span class="o">=</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span> <span class="vi">@q</span> <span class="o">=</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span> <span class="vi">@rotation</span> <span class="o">=</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span> <span class="vi">@faces</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">draw</span> <span class="n">background</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="n">lights</span> <span class="n">translate</span><span class="p">(</span><span class="n">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="n">height</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="n">rotate_x</span><span class="p">(</span><span class="n">rotation</span><span class="p">.</span><span class="nf">x</span><span class="p">)</span> <span class="n">rotate_y</span><span class="p">(</span><span class="n">rotation</span><span class="p">.</span><span class="nf">y</span><span class="p">)</span> <span class="n">no_stroke</span> <span class="n">begin_shape</span><span class="p">(</span><span class="no">TRIANGLES</span><span class="p">)</span> <span class="c1"># iterate over all faces/triangles of the 'mesh'</span> <span class="n">faces</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="c1"># create vertices for each corner point</span> <span class="n">f</span><span class="p">.</span><span class="nf">a</span><span class="p">.</span><span class="nf">to_vertex</span><span class="p">(</span><span class="n">renderer</span><span class="p">)</span> <span class="n">f</span><span class="p">.</span><span class="nf">b</span><span class="p">.</span><span class="nf">to_vertex</span><span class="p">(</span><span class="n">renderer</span><span class="p">)</span> <span class="n">f</span><span class="p">.</span><span class="nf">c</span><span class="p">.</span><span class="nf">to_vertex</span><span class="p">(</span><span class="n">renderer</span><span class="p">)</span> <span class="k">end</span> <span class="n">end_shape</span> <span class="c1"># update rotation</span> <span class="vi">@rotation</span> <span class="o">+=</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mf">0.014</span><span class="p">,</span> <span class="mf">0.0237</span><span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">mouse_moved</span> <span class="c1"># get 3D rotated mouse position</span> <span class="vi">@pos</span> <span class="o">=</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">mouse_x</span> <span class="o">-</span> <span class="n">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="n">mouse_y</span> <span class="o">-</span> <span class="n">height</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="n">pos</span><span class="p">.</span><span class="nf">rotate_x!</span><span class="p">(</span><span class="n">rotation</span><span class="p">.</span><span class="nf">x</span><span class="p">)</span> <span class="n">pos</span><span class="p">.</span><span class="nf">rotate_y!</span><span class="p">(</span><span class="n">rotation</span><span class="p">.</span><span class="nf">y</span><span class="p">)</span> <span class="c1"># use distance to previous point as target stroke weight</span> <span class="vi">@weight</span> <span class="o">+=</span> <span class="p">(</span><span class="n">sqrt</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="nf">dist</span><span class="p">(</span><span class="n">prev</span><span class="p">))</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">-</span> <span class="n">weight</span><span class="p">)</span> <span class="o">*</span> <span class="mf">0.1</span> <span class="c1"># define offset points for the triangle strip</span> <span class="n">a</span> <span class="o">=</span> <span class="n">pos</span> <span class="o">+</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">weight</span><span class="p">)</span> <span class="n">b</span> <span class="o">=</span> <span class="n">pos</span> <span class="o">+</span> <span class="no">Vec3D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="n">weight</span><span class="p">)</span> <span class="c1"># add 2 faces to the mesh</span> <span class="n">faces</span> <span class="o">&lt;&lt;</span> <span class="no">Face</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">p</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">q</span><span class="p">)</span> <span class="n">faces</span> <span class="o">&lt;&lt;</span> <span class="no">Face</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">p</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span> <span class="c1"># store current points for next iteration</span> <span class="vi">@prev</span> <span class="o">=</span> <span class="n">pos</span> <span class="vi">@p</span> <span class="o">=</span> <span class="n">a</span> <span class="vi">@q</span> <span class="o">=</span> <span class="n">b</span> <span class="k">end</span> <span class="c1"># An example of GfxRenderer usage for Vec3D =&gt; vertex conversion</span> <span class="k">def</span> <span class="nf">renderer</span> <span class="vi">@renderer</span> <span class="o">||=</span> <span class="no">GfxRender</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">g</span><span class="p">)</span> <span class="k">end</span> <span class="k">end</span> <span class="no">Doodle</span><span class="p">.</span><span class="nf">new</span> </code></pre></div></div> Sun, 26 Sep 2021 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2021/09/26/refinements.html https://monkstone.github.io/jruby_art/update/2021/09/26/refinements.html jruby_art update py5 feature envy <p>Recently I have been experimenting with <a href="http://py5.ixora.io/">py5</a> (an implementation of processing that can be run with native python-3.8+), previously there was <a href="https://github.com/jdf/processing.py#python-mode-for-processing">processing.py</a> (based on <a href="https://www.jython.org/">jython</a>, an implementation of python in java). In some ways ruby-processing projects are similar to processing.py except because of <a href="https://www.jruby.org/">jruby</a> they are somewhat closer to the the current native ruby than is jython that is currently stuck on python-2.7. The big frustration with processing.py and jython is the inability to use <a href="https://numpy.org/">numpy</a> and any other C library. This limitation similarly applies to my ruby-processing projects which are based on jruby, however thanks to its design it it is rather well integrated with java.</p> <h4 id="how-does-py5-manage-to-interoperate-with-native-python">How does py5 manage to interoperate with native python?</h4> <p>It does this by using <a href="https://github.com/jpype-project/jpype/">JPype</a>.</p> <blockquote> <p>JPype is a Python module to provide full access to Java from within Python. It allows Python to make use of Java only libraries, exploring and visualization of Java structures, development and testing of Java libraries, scientific computing, and much more. By gaining the best of both worlds using Python for rapid prototyping and Java for strong typed production code, JPype provides a powerful environment for engineering and code development.</p> </blockquote> <blockquote> <p>This is achieved not through re-implementing Python, as Jython has done, but rather through interfacing at the native level in both virtual machines. This shared memory based approach achieves decent computing performance, while providing the access to the entirety of CPython and Java libraries.</p> </blockquote> <h4 id="using-numpy-with-py5">Using numpy with py5</h4> <p>See my <a href="https://github.com/monkstone/py5-examples">experiments with py5</a>, where I found using numpy did indeed confer great performance benefits to sketches involving pixel manipulation.</p> <h4 id="unique-features-to-py5">Unique features to py5</h4> <p>Ability to integrate with <a href="https://jupyter.org/">jupyter notebooks</a></p> <h4 id="py5-generator">py5-generator</h4> <p>The hooking up of these features in py5 depends on the <a href="https://github.com/hx2A/py5generator">py5-generator</a>, which looks a bit complicated to to me, kudos to Jim Schmitz the creator of py5. Makes the meta programming used in ruby-processing projects look very straightforward.</p> Sat, 17 Jul 2021 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2021/07/17/py5-feature-envy.html https://monkstone.github.io/jruby_art/update/2021/07/17/py5-feature-envy.html jruby_art update Experimental Propane GEM <p>I have just released a pre-release <a href="https://ruby-processing.github.io/propane/">propane gem (3.7.0.pre)</a> with experimental ios-arm64 support requires testing.You probably should install <a href="https://adtmag.com/articles/2020/11/12/azul-supports-apple-silicon.aspx">azul jdk</a> for native mac support (otherwise you’ll be reliant Rosetta2 wrapper).</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jgem <span class="nb">install </span>propane <span class="nt">--pre</span> </code></pre></div></div> Sun, 24 Jan 2021 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2021/01/24/IOS-Arm64.html https://monkstone.github.io/jruby_art/update/2021/01/24/IOS-Arm64.html jruby_art update Experimenting With Graal on RaspberryPI4 <p>Recently I’ve been working on Newton Fractal Sketches using ruby Complex Math, which are quite testing for the RaspberryPI processor. Up till now I’d been reasonably happy with the performance of OpenJDK14 with my PiCrate sketches, but the Newton Fractal sketches run quite slowly (especially compared with processing.py and jython). So finally I bit the bullet and gave the latest GraalVM a go, which is now available for aarch64. Running on Manjaro ARM OS, I installed Graal on <code class="language-plaintext highlighter-rouge">/opt</code>, I then unset archlinux-java and used my <code class="language-plaintext highlighter-rouge">~/.bashrc</code> to control which jvm was used:-</p> <p><img src="/assets/bashrc.png" /></p> <p>Here is a test sketch</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># frozen_string_literal: true</span> <span class="nb">require</span> <span class="s1">'picrate'</span> <span class="k">class</span> <span class="nc">NewtonFractal</span> <span class="o">&lt;</span> <span class="no">Processing</span><span class="o">::</span><span class="no">App</span> <span class="no">IMGX</span> <span class="o">=</span> <span class="mi">512</span> <span class="no">IMGY</span> <span class="o">=</span> <span class="mi">512</span> <span class="no">MAXIT</span> <span class="o">=</span> <span class="mi">20</span> <span class="c1"># max iterations allowed</span> <span class="no">EPS</span> <span class="o">=</span> <span class="mf">1e-3</span> <span class="c1"># max error allowed</span> <span class="no">COMPLEX</span> <span class="o">=</span> <span class="no">Complex</span><span class="p">(</span><span class="mf">1e-6</span><span class="p">,</span> <span class="mf">1e-6</span><span class="p">)</span> <span class="c1"># step increment</span> <span class="nb">attr_reader</span> <span class="ss">:xa</span><span class="p">,</span> <span class="ss">:xb</span><span class="p">,</span> <span class="ss">:ya</span><span class="p">,</span> <span class="ss">:yb</span><span class="p">,</span> <span class="ss">:z</span><span class="p">,</span> <span class="ss">:img</span><span class="p">,</span> <span class="ss">:start</span> <span class="k">def</span> <span class="nf">settings</span> <span class="n">size</span><span class="p">(</span><span class="no">IMGX</span><span class="p">,</span> <span class="no">IMGY</span><span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">setup</span> <span class="n">sketch_title</span> <span class="s1">'Newton Fractal'</span> <span class="c1">#color_mode(HSB)</span> <span class="vi">@start</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="c1"># Drawing area</span> <span class="vi">@xa</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.0</span> <span class="vi">@xb</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="vi">@ya</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.0</span> <span class="vi">@yb</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="vi">@img</span> <span class="o">=</span> <span class="n">create_image</span><span class="p">(</span><span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">,</span> <span class="no">RGB</span><span class="p">).</span><span class="nf">tap</span> <span class="k">do</span> <span class="o">|</span><span class="n">image</span><span class="o">|</span> <span class="n">image</span><span class="p">.</span><span class="nf">load_pixels</span> <span class="n">grid</span><span class="p">(</span><span class="no">IMGY</span><span class="p">,</span> <span class="no">IMGX</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="o">|</span> <span class="n">zy</span> <span class="o">=</span> <span class="n">y</span> <span class="o">*</span> <span class="p">(</span><span class="n">yb</span> <span class="o">-</span> <span class="n">ya</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="no">IMGY</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">ya</span> <span class="n">zx</span> <span class="o">=</span> <span class="n">x</span> <span class="o">*</span> <span class="p">(</span><span class="n">xb</span> <span class="o">-</span> <span class="n">xa</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="no">IMGX</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">xa</span> <span class="vi">@z</span> <span class="o">=</span> <span class="no">Complex</span><span class="p">(</span><span class="n">zx</span><span class="p">,</span> <span class="n">zy</span><span class="p">)</span> <span class="p">(</span><span class="mi">0</span><span class="o">...</span><span class="no">MAXIT</span><span class="p">).</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="c1"># Newton iteration</span> <span class="n">z0</span> <span class="o">=</span> <span class="n">z</span> <span class="o">-</span> <span class="n">func</span><span class="p">(</span><span class="n">z</span><span class="p">)</span> <span class="o">/</span> <span class="p">((</span><span class="n">func</span><span class="p">(</span><span class="n">z</span> <span class="o">+</span> <span class="no">COMPLEX</span><span class="p">)</span> <span class="o">-</span> <span class="n">func</span><span class="p">(</span><span class="n">z</span><span class="p">))</span> <span class="o">/</span> <span class="no">COMPLEX</span><span class="p">)</span> <span class="k">break</span> <span class="k">if</span> <span class="p">(</span><span class="n">z0</span> <span class="o">-</span> <span class="n">z</span><span class="p">).</span><span class="nf">abs2</span> <span class="o">&lt;</span> <span class="no">EPS</span> <span class="o">*</span> <span class="no">EPS</span> <span class="vi">@z</span> <span class="o">=</span> <span class="n">z0</span> <span class="c1"># pixels[x + y * width] = color(i % 5 * 64, i % 17 * 16, i % 9 * 32)</span> <span class="n">image</span><span class="p">.</span><span class="nf">pixels</span><span class="p">[</span><span class="n">x</span> <span class="o">+</span> <span class="n">y</span> <span class="o">*</span> <span class="n">width</span><span class="p">]</span> <span class="o">=</span> <span class="n">color</span><span class="p">(</span><span class="n">i</span> <span class="o">%</span> <span class="mi">5</span> <span class="o">*</span> <span class="mi">64</span><span class="p">,</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">9</span> <span class="o">*</span> <span class="mi">32</span><span class="p">,</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">17</span> <span class="o">*</span> <span class="mi">16</span><span class="p">)</span> <span class="k">end</span> <span class="k">end</span> <span class="k">end</span> <span class="n">no_loop</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">draw</span> <span class="n">set</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">img</span><span class="p">)</span> <span class="nb">puts</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="n">start</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="n">z</span><span class="p">)</span> <span class="n">z</span><span class="o">**</span><span class="mf">3.0</span> <span class="o">-</span> <span class="mf">1.0</span> <span class="c1"># z**4 - 1.0</span> <span class="k">end</span> <span class="k">end</span> <span class="no">NewtonFractal</span><span class="p">.</span><span class="nf">new</span> </code></pre></div></div> <p>This sketch took over 2 minutes to develop on OpenJDK14 and less than a minute to develop on the GraalVM. Also I found a community PKGBUILD build, which require a <code class="language-plaintext highlighter-rouge">fakeroot</code>, install as follows (then you can use <code class="language-plaintext highlighter-rouge">archlinux-java</code> to switch <code class="language-plaintext highlighter-rouge">jvm</code>:-</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> fakeroot git clone https://aur.archlinux.org/jdk11-graalvm-bin.git <span class="nb">cd </span>jkd11-graalvm-bin makepkg <span class="nt">-si</span> </code></pre></div></div> Sun, 25 Oct 2020 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2020/10/25/GraalVM.html https://monkstone.github.io/jruby_art/update/2020/10/25/GraalVM.html jruby_art update Refinements in Ruby-Processing <p>Since ruby-2.4 there is a possibility of using refinements in ruby-processing projects, recently I’ve been working on sketches using complex numbers. It occurred to me I could use refinements (instead of monkey patching) to extend the Vec2D class support complex number operations, here is what I came up with:-</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">require</span> <span class="s1">'picrate'</span> <span class="k">module</span> <span class="nn">CVec2D</span> <span class="n">refine</span> <span class="no">Vec2D</span> <span class="k">do</span> <span class="k">def</span> <span class="nf">complex_mult</span><span class="p">(</span><span class="n">vec_b</span><span class="p">)</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span> <span class="nb">self</span><span class="p">.</span><span class="nf">x</span><span class="o">*</span><span class="n">vec_b</span><span class="p">.</span><span class="nf">x</span> <span class="o">-</span> <span class="nb">self</span><span class="p">.</span><span class="nf">y</span><span class="o">*</span><span class="n">vec_b</span><span class="p">.</span><span class="nf">y</span><span class="p">,</span> <span class="nb">self</span><span class="p">.</span><span class="nf">x</span><span class="o">*</span><span class="n">vec_b</span><span class="p">.</span><span class="nf">y</span> <span class="o">+</span> <span class="nb">self</span><span class="p">.</span><span class="nf">y</span><span class="o">*</span><span class="n">vec_b</span><span class="p">.</span><span class="nf">x</span> <span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">inverse</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">x</span><span class="p">,</span> <span class="o">-</span><span class="nb">self</span><span class="p">.</span><span class="nf">y</span><span class="p">)</span> <span class="o">/</span> <span class="nb">self</span><span class="p">.</span><span class="nf">dot</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">complex_divide</span><span class="p">(</span><span class="n">vec_b</span><span class="p">)</span> <span class="nb">self</span><span class="p">.</span><span class="nf">complex_mult</span><span class="p">(</span><span class="n">vec_b</span><span class="p">.</span><span class="nf">inverse</span><span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">complex_exp</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Math</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">x</span><span class="p">)</span> <span class="o">*</span> <span class="no">Math</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">y</span><span class="p">),</span> <span class="no">Math</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">x</span><span class="p">)</span> <span class="o">*</span> <span class="no">Math</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">y</span><span class="p">))</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">complex_log</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Math</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">mag</span><span class="p">),</span> <span class="no">Math</span><span class="p">.</span><span class="nf">atan2</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">y</span><span class="p">,</span> <span class="nb">self</span><span class="p">.</span><span class="nf">x</span><span class="p">));</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">complex_power</span><span class="p">(</span><span class="n">vec_b</span><span class="p">)</span> <span class="nb">self</span><span class="p">.</span><span class="nf">complex_log</span><span class="p">.</span><span class="nf">complex_mult</span><span class="p">(</span><span class="n">vec_b</span><span class="p">).</span><span class="nf">complex_exp</span> <span class="k">end</span> <span class="k">end</span> <span class="k">end</span> <span class="k">class</span> <span class="nc">RefineVec2D</span> <span class="n">using</span> <span class="no">CVec2D</span> <span class="nb">attr_reader</span> <span class="ss">:vec_a</span><span class="p">,</span> <span class="ss">:vec_b</span> <span class="k">def</span> <span class="nf">initialize</span> <span class="vi">@vec_a</span> <span class="o">=</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span> <span class="vi">@vec_b</span> <span class="o">=</span> <span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span> <span class="k">end</span> <span class="k">def</span> <span class="nf">test</span> <span class="nb">puts</span> <span class="n">vec_a</span><span class="p">.</span><span class="nf">complex_divide</span><span class="p">(</span><span class="n">vec_b</span><span class="p">)</span> <span class="nb">puts</span> <span class="n">vec_a</span><span class="p">.</span><span class="nf">complex_mult</span><span class="p">(</span><span class="n">vec_b</span><span class="p">)</span> <span class="nb">puts</span> <span class="n">vec_a</span><span class="p">.</span><span class="nf">inverse</span> <span class="nb">puts</span> <span class="n">vec_a</span><span class="p">.</span><span class="nf">complex_power</span><span class="p">(</span><span class="no">Vec2D</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="k">end</span> <span class="k">end</span> <span class="n">test_refine</span> <span class="o">=</span> <span class="no">RefineVec2D</span><span class="p">.</span><span class="nf">new</span> <span class="n">test_refine</span><span class="p">.</span><span class="nf">test</span> </code></pre></div></div> <p>Here is the output:-</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Vec2D<span class="o">(</span>x <span class="o">=</span> 0.6393, y <span class="o">=</span> 0.0328<span class="o">)</span> Vec2D<span class="o">(</span>x <span class="o">=</span> <span class="nt">-9</span>.0000, y <span class="o">=</span> 38.0000<span class="o">)</span> Vec2D<span class="o">(</span>x <span class="o">=</span> 0.1200, y <span class="o">=</span> <span class="nt">-0</span>.1600<span class="o">)</span> Vec2D<span class="o">(</span>x <span class="o">=</span> <span class="nt">-117</span>.0000, y <span class="o">=</span> 44.0000<span class="o">)</span> </code></pre></div></div> Fri, 02 Oct 2020 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2020/10/02/Refinements.html https://monkstone.github.io/jruby_art/update/2020/10/02/Refinements.html jruby_art update 64 Bit OS RaspberryPI4 <p>Although RaspberryPI foundation are working on a 64 bit (RaspberryPI OS) it is very much beta, and the only thing that seems to have spurred them to it, is the release of the 8gb version of the RaspberryPI4. However Archlinux ARM is now exclusively 64 bit and my opinion very much ready to go (and I’m sure they’ll take advantage of RaspberryPI foundations work). Recently I released a version of PiCrate that is compatible with both 32 bit and 64 bit distros.</p> Wed, 06 May 2020 06:00:00 +0000 https://monkstone.github.io/jruby_art/update/2020/05/06/Archlinux_ARM.html https://monkstone.github.io/jruby_art/update/2020/05/06/Archlinux_ARM.html jruby_art update