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:-

require 'picrate'

module CVec2D
refine Vec2D do
def complex_mult(vec_b)
Vec2D.new(
self.x*vec_b.x - self.y*vec_b.y, self.x*vec_b.y + self.y*vec_b.x
)
end

def inverse
Vec2D.new(self.x, -self.y) / self.dot(self)
end

def complex_divide(vec_b)
self.complex_mult(vec_b.inverse)
end

def complex_exp
Vec2D.new(Math.exp(self.x) * Math.cos(self.y), Math.exp(self.x) * Math.sin(self.y))
end

def complex_log
Vec2D.new(Math.log(self.mag), Math.atan2(self.y, self.x));
end

def complex_power(vec_b)
self.complex_log.complex_mult(vec_b).complex_exp
end
end
end

class RefineVec2D
using CVec2D

def initialize
@vec_a = Vec2D.new(3, 4)
@vec_b = Vec2D.new(5, 6)
end

def test
puts vec_a.complex_divide(vec_b)
puts vec_a.complex_mult(vec_b)
puts vec_a.inverse
puts vec_a.complex_power(Vec2D.new(3, 0))
end
end

test_refine = RefineVec2D.new
test_refine.test

Here is the output:-

Vec2D(x = 0.6393, y = 0.0328)
Vec2D(x = -9.0000, y = 38.0000)
Vec2D(x = 0.1200, y = -0.1600)
Vec2D(x = -117.0000, y = 44.0000)