Skip to content

Instantly share code, notes, and snippets.

@monkstone
Created November 19, 2015 11:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monkstone/1620da6a63cba504931b to your computer and use it in GitHub Desktop.
Save monkstone/1620da6a63cba504931b to your computer and use it in GitHub Desktop.
Monkey Patching in JRubyArt
# Java::OrgJrubyExceptions::RaiseException
# (ArgumentError) wrong number of arguments calling `initialize` (3 for 0)
# RUBY.mouse_moved(mesh_doodle.rb:62)
attr_reader :prev, :p, :q, :rotation, :faces, :pos, :weight, :renderer
Face = Struct.new(:a, :b, :c)
class Vec3D # re-open the Vec3D class to add rotation functionality
def rotate_y(theta)
co = Math.cos(theta)
si = Math.sin(theta)
xx = co * x - si * z
self.z = si * x + co * z
self.x = xx
self
end
def rotate_x(theta)
co = Math.cos(theta)
si = Math.sin(theta)
zz = co * z - si * y
self.y = si * z + co * y
self.z = zz
self
end
end
def settings
size(600, 600, P3D)
end
def setup
sketch_title 'Ribbon Doodle'
@renderer = AppRender.new(self)
@weight = 0
@prev = Vec3D.new
@p = Vec3D.new
@q = Vec3D.new
@rotation = Vec2D.new
@faces = []
end
def draw
background(0)
lights
translate(width / 2, height / 2, 0)
rotate_x(rotation.x)
rotate_y(rotation.y)
no_stroke
begin_shape(TRIANGLES)
# iterate over all faces/triangles of the 'mesh'
faces.each do |f|
# create vertices for each corner point
f.a.to_vertex(renderer)
f.b.to_vertex(renderer)
f.c.to_vertex(renderer)
end
end_shape
# update rotation
@rotation += Vec2D.new(0.014, 0.0237)
end
def mouse_moved
# get 3D rotated mouse position
@pos = Vec3D.new(mouse_x - width / 2, mouse_y - height / 2, 0)
pos.rotate_x(rotation.x)
pos.rotate_y(rotation.y)
# use distance to previous point as target stroke weight
@weight += (sqrt(pos.dist(prev)) * 2 - weight) * 0.1
# define offset points for the triangle strip
a = pos + Vec3D.new(0, 0, weight)
b = pos + Vec3D.new(0, 0, -weight)
# add 2 faces to the mesh
faces << Face.new(p, b, q)
faces << Face.new(p, a, b)
# store current points for next iteration
@prev = pos
@p = a
@q = b
end
class Numeric #:nodoc:
def degrees
self * 180 / Math::PI
end
def radians
self * Math::PI / 180
end
end
# After a toxiclibs "MeshDoodle" sketch by Karsten Schmidt
# Adapted to use JRubyArt Vec2D and Vec3D classes by Martin Prout
# Note: The extension Vec3D class to support rotations and use of a Struct
# for triangle 'mesh' Face. Also use of AppRenderer for Vec3D => vertex
# Vec3D and Vec2D are jruby extensions ie written in java.
attr_reader :prev, :p, :q, :rotation, :faces, :pos, :weight, :renderer
Face = Struct.new(:a, :b, :c)
Vec3D.class_eval do # re-open the Vec3D class to add rotation functionality
def rotate_y(theta)
co = Math.cos(theta)
si = Math.sin(theta)
xx = co * x - si * z
self.z = si * x + co * z
self.x = xx
self
end
def rotate_x(theta)
co = Math.cos(theta)
si = Math.sin(theta)
zz = co * z - si * y
self.y = si * z + co * y
self.z = zz
self
end
end
def settings
size(600, 600, P3D)
end
def setup
sketch_title 'Ribbon Doodle'
@renderer = AppRender.new(self)
@weight = 0
@prev = Vec3D.new
@p = Vec3D.new
@q = Vec3D.new
@rotation = Vec2D.new
@faces = []
end
def draw
background(0)
lights
translate(width / 2, height / 2, 0)
rotate_x(rotation.x)
rotate_y(rotation.y)
no_stroke
begin_shape(TRIANGLES)
# iterate over all faces/triangles of the 'mesh'
faces.each do |f|
# create vertices for each corner point
f.a.to_vertex(renderer)
f.b.to_vertex(renderer)
f.c.to_vertex(renderer)
end
end_shape
# update rotation
@rotation += Vec2D.new(0.014, 0.0237)
end
def mouse_moved
# get 3D rotated mouse position
@pos = Vec3D.new(mouse_x - width / 2, mouse_y - height / 2, 0)
pos.rotate_x(rotation.x)
pos.rotate_y(rotation.y)
# use distance to previous point as target stroke weight
@weight += (sqrt(pos.dist(prev)) * 2 - weight) * 0.1
# define offset points for the triangle strip
a = pos + Vec3D.new(0, 0, weight)
b = pos + Vec3D.new(0, 0, -weight)
# add 2 faces to the mesh
faces << Face.new(p, b, q)
faces << Face.new(p, a, b)
# store current points for next iteration
@prev = pos
@p = a
@q = b
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment