propane 0.5.0-java → 0.6.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +3 -1
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/examples/complete/bw_shader.rb +46 -0
- data/examples/complete/data/bwfrag.glsl +23 -0
- data/examples/complete/data/lachoy.jpg +0 -0
- data/examples/complete/data/landscape.glsl +352 -0
- data/examples/complete/data/monjori.glsl +30 -0
- data/examples/complete/data/moon.jpg +0 -0
- data/examples/complete/data/sea.jpg +0 -0
- data/examples/complete/edge_detection.rb +49 -0
- data/examples/complete/landscape.rb +32 -0
- data/examples/complete/linear_image.rb +51 -0
- data/examples/complete/monjori.rb +33 -0
- data/examples/regular/arcball_box.rb +3 -1
- data/examples/regular/arcball_constrain.rb +38 -0
- data/examples/regular/bezier_playground.rb +205 -0
- data/examples/regular/colors_two.rb +61 -0
- data/examples/regular/creating_colors.rb +10 -3
- data/examples/regular/elegant_ball.rb +1 -1
- data/examples/regular/fibonacci_sphere.rb +90 -0
- data/examples/regular/grapher.rb +39 -0
- data/examples/regular/gravity.rb +120 -0
- data/examples/regular/slider_demo.rb +60 -0
- data/examples/regular/slider_example.rb +53 -0
- data/examples/regular/slider_simple.rb +47 -0
- data/examples/regular/tree.rb +76 -0
- data/lib/propane/app.rb +1 -6
- data/lib/propane/helper_methods.rb +39 -10
- data/lib/propane/version.rb +1 -1
- data/library/slider/slider.rb +43 -0
- data/pom.rb +4 -4
- data/pom.xml +4 -4
- data/propane.gemspec +1 -1
- data/src/monkstone/ColorUtil.java +42 -9
- data/src/monkstone/slider/CustomHorizontalSlider.java +164 -0
- data/src/monkstone/slider/CustomVerticalSlider.java +178 -0
- data/src/monkstone/slider/SimpleHorizontalSlider.java +145 -0
- data/src/monkstone/slider/SimpleSlider.java +175 -0
- data/src/monkstone/slider/SimpleVerticalSlider.java +159 -0
- data/src/monkstone/slider/Slider.java +61 -0
- data/src/monkstone/slider/SliderBar.java +245 -0
- data/src/monkstone/slider/SliderGroup.java +56 -0
- data/src/monkstone/slider/WheelHandler.java +35 -0
- data/src/monkstone/vecmath/vec2/Vec2.java +3 -8
- data/src/monkstone/vecmath/vec3/Vec3.java +8 -13
- data/vendors/Rakefile +2 -2
- metadata +36 -6
- data/VERSION.txt +0 -4
@@ -0,0 +1,30 @@
|
|
1
|
+
#define PROCESSING_COLOR_SHADER
|
2
|
+
|
3
|
+
uniform vec2 resolution;
|
4
|
+
uniform float time;
|
5
|
+
|
6
|
+
void main(void) {
|
7
|
+
vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
|
8
|
+
float a = time*40.0;
|
9
|
+
float d,e,f,g=1.0/40.0,h,i,r,q;
|
10
|
+
e=400.0*(p.x*0.5+0.5);
|
11
|
+
f=400.0*(p.y*0.5+0.5);
|
12
|
+
i=200.0+sin(e*g+a/150.0)*20.0;
|
13
|
+
d=200.0+cos(f*g/2.0)*18.0+cos(e*g)*7.0;
|
14
|
+
r=sqrt(pow(i-e,2.0)+pow(d-f,2.0));
|
15
|
+
q=f/r;
|
16
|
+
e=(r*cos(q))-a/2.0;f=(r*sin(q))-a/2.0;
|
17
|
+
d=sin(e*g)*176.0+sin(e*g)*164.0+r;
|
18
|
+
h=((f+d)+a/2.0)*g;
|
19
|
+
i=cos(h+r*p.x/1.3)*(e+e+a)+cos(q*g*6.0)*(r+h/3.0);
|
20
|
+
h=sin(f*g)*144.0-sin(e*g)*212.0*p.x;
|
21
|
+
h=(h+(f-e)*q+sin(r-(a+h)/7.0)*10.0+i/4.0)*g;
|
22
|
+
i+=cos(h*2.3*sin(a/350.0-q))*184.0*sin(q-(r*4.3+a/12.0)*g)+tan(r*g+h)*184.0*cos(r*g+h);
|
23
|
+
i=mod(i/5.6,256.0)/64.0;
|
24
|
+
if(i<0.0) i+=4.0;
|
25
|
+
if(i>=2.0) i=4.0-i;
|
26
|
+
d=r/350.0;
|
27
|
+
d+=sin(d*d*8.0)*0.52;
|
28
|
+
f=(sin(a*g)+1.0)/2.0;
|
29
|
+
gl_FragColor=vec4(vec3(f*i/1.6,i/2.0+d/13.0,i)*d*p.x+vec3(i/1.3+d/8.0,i/2.0+d/18.0,i)*d*(1.0-p.x),1.0);
|
30
|
+
}
|
Binary file
|
Binary file
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'propane'
|
4
|
+
# Edge Detection.
|
5
|
+
#
|
6
|
+
# A high-pass filter sharpens an image. This program analyzes every
|
7
|
+
# pixel in an image in relation to the neighboring pixels to sharpen
|
8
|
+
# the image.
|
9
|
+
class EdgeDetection < Propane::App
|
10
|
+
KERNEL = [[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]].freeze
|
11
|
+
attr_reader :img
|
12
|
+
|
13
|
+
def setup
|
14
|
+
size(640, 360)
|
15
|
+
@img = load_image('moon.jpg') # Load the original image
|
16
|
+
no_loop
|
17
|
+
end
|
18
|
+
|
19
|
+
def draw
|
20
|
+
image(img, 0, 0) # Displays the image from point (0,0)
|
21
|
+
img.load_pixels
|
22
|
+
# Create an opaque image of the same size as the original
|
23
|
+
edge_img = create_image(img.width, img.height, RGB)
|
24
|
+
# Loop through every pixel in the image
|
25
|
+
(1...img.height - 1).each do |y|
|
26
|
+
(1...img.width - 1).each do |x|
|
27
|
+
sum = 0 # Kernel sum for this pixel
|
28
|
+
(-1..1).each do |ky|
|
29
|
+
(-1..1).each do |kx|
|
30
|
+
# Calculate the adjacent pixel for this kernel point
|
31
|
+
pos = (y + ky) * img.width + (x + kx)
|
32
|
+
# Image is grayscale, red/green/blue are identical
|
33
|
+
val = red(img.pixels[pos])
|
34
|
+
# Multiply adjacent pixels based on the kernel values
|
35
|
+
sum += KERNEL[ky + 1][kx + 1] * val
|
36
|
+
end
|
37
|
+
end
|
38
|
+
# For this pixel in the new image, set the gray value
|
39
|
+
# based on the sum from the kernel
|
40
|
+
edge_img.pixels[y * img.width + x] = color(sum, sum, sum)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# State that there are changes to edge_img.pixels[]
|
44
|
+
edge_img.update_pixels
|
45
|
+
image(edge_img, width / 2, 0) # Draw the new image
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
EdgeDetection.new title: 'Edge Detection'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'propane'
|
2
|
+
|
3
|
+
class Landscape < Propane::App
|
4
|
+
#
|
5
|
+
# Elevated
|
6
|
+
# https://www.shadertoy.com/view/MdX3Rr by inigo quilez
|
7
|
+
# Created by inigo quilez - iq/2013
|
8
|
+
# License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
|
9
|
+
# Processing port by Raphaël de Courville.
|
10
|
+
#
|
11
|
+
attr_reader :landscape
|
12
|
+
java_alias :background_int, :background, [Java::int]
|
13
|
+
|
14
|
+
def setup
|
15
|
+
size(640, 360, P2D)
|
16
|
+
no_stroke
|
17
|
+
# The code of this shader shows how to integrate shaders from shadertoy
|
18
|
+
# into Processing with minimal changes.
|
19
|
+
@landscape = load_shader('landscape.glsl')
|
20
|
+
landscape.set('resolution', width.to_f, height.to_f)
|
21
|
+
end
|
22
|
+
|
23
|
+
def draw
|
24
|
+
background_int 0
|
25
|
+
landscape.set('time', (millis/1000.0).to_f)
|
26
|
+
shader(landscape)
|
27
|
+
rect(0, 0, width, height)
|
28
|
+
frame.set_title("frame: #{frame_count} - fps: #{format('%0.2f', frame_rate)}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Landscape.new title: 'Landscape'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'propane'
|
4
|
+
# Linear Image.
|
5
|
+
#
|
6
|
+
# Click and drag mouse up and down to control the signal.
|
7
|
+
#
|
8
|
+
# Note in ruby-processing to access booleans use
|
9
|
+
# mouse_pressed? and key_pressed?
|
10
|
+
#
|
11
|
+
# Press and hold any key to view the image scanning
|
12
|
+
class LinearImage < Propane::App
|
13
|
+
attr_reader :signal, :img, :direction
|
14
|
+
|
15
|
+
def setup
|
16
|
+
size(640, 360)
|
17
|
+
stroke(255)
|
18
|
+
@img = loadImage('sea.jpg')
|
19
|
+
@direction = 1
|
20
|
+
@signal = 0
|
21
|
+
img.load_pixels
|
22
|
+
load_pixels
|
23
|
+
end
|
24
|
+
|
25
|
+
def draw
|
26
|
+
@direction = direction * -1 if signal > img.height - 1 || signal < 0
|
27
|
+
if mouse_pressed?
|
28
|
+
@signal = (mouse_y % img.height).abs
|
29
|
+
else
|
30
|
+
@signal += (0.3 * direction)
|
31
|
+
end
|
32
|
+
if key_pressed?
|
33
|
+
set(0, 0, img)
|
34
|
+
line(0, signal, img.width, signal)
|
35
|
+
else
|
36
|
+
signal_offset = signal.to_i * img.width
|
37
|
+
(0...img.height).each do |y|
|
38
|
+
java.lang.System.arraycopy(
|
39
|
+
img.pixels.to_java,
|
40
|
+
signal_offset,
|
41
|
+
pixels,
|
42
|
+
y * width,
|
43
|
+
img.width
|
44
|
+
)
|
45
|
+
end
|
46
|
+
update_pixels
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
LinearImage.new title: 'Linear Image'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'propane'
|
2
|
+
|
3
|
+
class Monjori < Propane::App
|
4
|
+
##
|
5
|
+
# Monjori.
|
6
|
+
#
|
7
|
+
# GLSL version of the 1k intro Monjori from the demoscene
|
8
|
+
# (http://www.pouet.net/prod.php?which=52761)
|
9
|
+
# Ported from the webGL version available in ShaderToy:
|
10
|
+
# http://www.iquilezles.org/apps/shadertoy/
|
11
|
+
# (Look for Monjori under the Plane Deformations Presets)
|
12
|
+
|
13
|
+
attr_reader :monjori
|
14
|
+
|
15
|
+
def setup
|
16
|
+
size(640, 360, P2D)
|
17
|
+
no_stroke
|
18
|
+
@monjori = load_shader('monjori.glsl')
|
19
|
+
monjori.set('resolution', width.to_f, height.to_f)
|
20
|
+
end
|
21
|
+
|
22
|
+
def draw
|
23
|
+
monjori.set('time', millis / 1000.0)
|
24
|
+
shader(monjori)
|
25
|
+
# This kind of effects are entirely implemented in the
|
26
|
+
# fragment shader, they only need a quad covering the
|
27
|
+
# entire view area so every pixel is pushed through the
|
28
|
+
# shader.
|
29
|
+
rect(0, 0, width, height)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Monjori.new title: 'Monjori'
|
@@ -1,8 +1,10 @@
|
|
1
|
+
!#/usr/bin/env jruby
|
2
|
+
|
1
3
|
require 'arcball'
|
2
4
|
|
3
5
|
############################
|
4
6
|
# Use mouse drag to rotate
|
5
|
-
#
|
7
|
+
# The arcball. Use mousewheel
|
6
8
|
# to zoom. Hold down x, y, z
|
7
9
|
# to constrain rotation axis.
|
8
10
|
############################
|
@@ -0,0 +1,38 @@
|
|
1
|
+
!#/usr/bin/env jruby
|
2
|
+
|
3
|
+
require 'arcball'
|
4
|
+
|
5
|
+
############################
|
6
|
+
# Use mouse drag to rotate
|
7
|
+
# the arcball. Use mousewheel
|
8
|
+
# to zoom. Custom constrain
|
9
|
+
# default is yaxis.
|
10
|
+
############################
|
11
|
+
|
12
|
+
require 'propane' # temporary local
|
13
|
+
|
14
|
+
# Include processing opengl classes that we'd like to use:
|
15
|
+
%w(PGL PGraphics3D PGraphicsOpenGL PShapeOpenGL Texture).each do |klass|
|
16
|
+
java_import "processing.opengl.#{klass}"
|
17
|
+
end
|
18
|
+
|
19
|
+
class ArcballBox < Propane::App
|
20
|
+
|
21
|
+
def setup
|
22
|
+
size(600, 600, P3D)
|
23
|
+
smooth(8)
|
24
|
+
Processing::ArcBall.constrain(self, :xaxis)
|
25
|
+
fill 180
|
26
|
+
end
|
27
|
+
|
28
|
+
def draw
|
29
|
+
background(50)
|
30
|
+
box(300, 300, 300)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
ArcballBox.new title: 'ArcBall Box'
|
36
|
+
|
37
|
+
|
38
|
+
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'propane'
|
2
|
+
|
3
|
+
X1, Y1, X2, Y2 = 50.0, 50.0, 250.0, 250.0
|
4
|
+
REDDISH = [250, 100, 100]
|
5
|
+
RADIUS = 7
|
6
|
+
|
7
|
+
module Olap
|
8
|
+
def self.overlaps(x, y, point_x, point_y)
|
9
|
+
Math.hypot(x - point_x, y - point_y) < RADIUS
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Curve
|
14
|
+
include Olap, Propane::Proxy
|
15
|
+
attr_accessor :x1, :y1, :c1x, :c1y, :c2x, :c2y, :x2, :y2
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@x1, @y1, @x2, @y2 = X1, Y1, X2, Y2
|
19
|
+
set_control_points(X1 + 30, Y1, X2 - 30, Y2)
|
20
|
+
end
|
21
|
+
|
22
|
+
def contains(x, y)
|
23
|
+
return :one if Olap.overlaps(x1, y1, x, y)
|
24
|
+
return :two if Olap.overlaps(x2, y2, x, y)
|
25
|
+
end
|
26
|
+
|
27
|
+
def all_points
|
28
|
+
return x1, y1, c1x, c1y, c2x, c2y, x2, y2
|
29
|
+
end
|
30
|
+
|
31
|
+
def control_points
|
32
|
+
return c1x, c1y, c2x, c2y
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_control_points(*points)
|
36
|
+
@c1x, @c1y, @c2x, @c2y = *points
|
37
|
+
end
|
38
|
+
|
39
|
+
def draw
|
40
|
+
bezier(*all_points)
|
41
|
+
ellipse x1, y1, 3, 3
|
42
|
+
ellipse x2, y2, 3, 3
|
43
|
+
end
|
44
|
+
|
45
|
+
def print_equation(id)
|
46
|
+
pt = all_points.map(&:to_i)
|
47
|
+
puts ''
|
48
|
+
puts format('*** line #%s ***', id)
|
49
|
+
xformat = 'x = (1-t)^3 %s + 3(1-t)^2 t%s + 3(1-t)t^2 %s + t^3 %s'
|
50
|
+
yformat = 'y = -1 * ((1-t)^3 %s + 3(1-t)^2 t%s + 3(1-t)t^2 %s + t^3 %s'
|
51
|
+
puts format(xformat, pt[0], pt[2], pt[4], pt[6])
|
52
|
+
puts format(yformat, pt[1], pt[3], pt[5], pt[7])
|
53
|
+
puts ''
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class BezierPlayground < Propane::App
|
58
|
+
# A Bezier playground. Click to shape the curve. Drag to move it.
|
59
|
+
# Arrows toggle between curves, delete removes them.
|
60
|
+
# You can print out the parametric equations for t = 0..1
|
61
|
+
|
62
|
+
attr_accessor :curves, :c1x, :c1y, :c2x, :c2y
|
63
|
+
attr_reader :panel, :hide
|
64
|
+
|
65
|
+
load_library :control_panel
|
66
|
+
include Olap
|
67
|
+
|
68
|
+
def setup
|
69
|
+
size 300, 300
|
70
|
+
@curves = []
|
71
|
+
@hide = false
|
72
|
+
control_panel do |c|
|
73
|
+
c.look_feel 'Nimbus'
|
74
|
+
c.button :new_curve
|
75
|
+
c.button :print_equations
|
76
|
+
@panel = c
|
77
|
+
end
|
78
|
+
generate_curve
|
79
|
+
end
|
80
|
+
|
81
|
+
def draw
|
82
|
+
unless hide
|
83
|
+
panel.visible = visible
|
84
|
+
@hide = true
|
85
|
+
end
|
86
|
+
background 50
|
87
|
+
draw_control_tangent_lines
|
88
|
+
draw_curves
|
89
|
+
draw_current_control_points
|
90
|
+
end
|
91
|
+
|
92
|
+
def print_equations
|
93
|
+
curves.each_with_index { |c, i| c.print_equation(i + 1) }
|
94
|
+
end
|
95
|
+
|
96
|
+
def control_points
|
97
|
+
return c1x, c1y, c2x, c2y
|
98
|
+
end
|
99
|
+
|
100
|
+
def set_control_points(*points)
|
101
|
+
@c1x, @c1y, @c2x, @c2y = points.any? ? points : [X1, Y1, X2, Y2]
|
102
|
+
end
|
103
|
+
|
104
|
+
def generate_curve
|
105
|
+
curves << current_curve = Curve.new
|
106
|
+
@current = curves.length - 1
|
107
|
+
set_control_points(*current_curve.control_points)
|
108
|
+
end
|
109
|
+
|
110
|
+
def current_curve
|
111
|
+
curves[@current]
|
112
|
+
end
|
113
|
+
|
114
|
+
def new_curve
|
115
|
+
current_curve.set_control_points(c1x, c1y, c2x, c2y)
|
116
|
+
generate_curve
|
117
|
+
end
|
118
|
+
|
119
|
+
def clicked_control_point?
|
120
|
+
x, y = mouse_x, mouse_y
|
121
|
+
return :one if Olap.overlaps(c1x, c1y, x, y)
|
122
|
+
return :two if Olap.overlaps(c2x, c2y, x, y)
|
123
|
+
end
|
124
|
+
|
125
|
+
def mouse_pressed
|
126
|
+
switch_curve_if_endpoint_clicked
|
127
|
+
@control = clicked_control_point?
|
128
|
+
return if @control
|
129
|
+
curve = curves.detect { |c| c.contains(mouse_x, mouse_y) }
|
130
|
+
@end_point = curve.contains(mouse_x, mouse_y) if curve
|
131
|
+
end
|
132
|
+
|
133
|
+
def mouse_released
|
134
|
+
@control, @end_point = nil, nil
|
135
|
+
@hide = false
|
136
|
+
end
|
137
|
+
|
138
|
+
def mouse_dragged
|
139
|
+
offs = compute_offsets
|
140
|
+
return if offs.map(&:abs).max > 100
|
141
|
+
return move_control_point(*offs) if @control
|
142
|
+
return move_end_point(*offs) && move_control_point(*offs) if @end_point
|
143
|
+
move_current_curve(*offs)
|
144
|
+
end
|
145
|
+
|
146
|
+
def switch_curve_if_endpoint_clicked
|
147
|
+
become = curves.detect { |c| c.contains(mouse_x, mouse_y) }
|
148
|
+
return unless become && become != current_curve
|
149
|
+
current_curve.set_control_points(*control_points)
|
150
|
+
self.set_control_points(*become.control_points)
|
151
|
+
@current = curves.index(become)
|
152
|
+
end
|
153
|
+
|
154
|
+
def move_current_curve(x_off, y_off)
|
155
|
+
@c1x += x_off; @c2x += x_off
|
156
|
+
@c1y += y_off; @c2y += y_off
|
157
|
+
current_curve.set_control_points(*control_points)
|
158
|
+
current_curve.x1 += x_off; current_curve.x2 += x_off
|
159
|
+
current_curve.y1 += y_off; current_curve.y2 += y_off
|
160
|
+
end
|
161
|
+
|
162
|
+
def move_control_point(x_off, y_off)
|
163
|
+
case @control || @end_point
|
164
|
+
when :one then @c1x += x_off and @c1y += y_off
|
165
|
+
when :two then @c2x += x_off and @c2y += y_off
|
166
|
+
end
|
167
|
+
current_curve.set_control_points(*control_points)
|
168
|
+
end
|
169
|
+
|
170
|
+
def move_end_point(x_off, y_off)
|
171
|
+
c = current_curve
|
172
|
+
case @end_point
|
173
|
+
when :one then c.x1 += x_off and c.y1 += y_off
|
174
|
+
when :two then c.x2 += x_off and c.y2 += y_off
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def compute_offsets
|
179
|
+
return mouse_x - pmouse_x, mouse_y - pmouse_y
|
180
|
+
end
|
181
|
+
|
182
|
+
def draw_curves
|
183
|
+
stroke 255
|
184
|
+
no_fill
|
185
|
+
stroke_width 2
|
186
|
+
curves.each(&:draw)
|
187
|
+
end
|
188
|
+
|
189
|
+
def draw_current_control_points
|
190
|
+
fill color(*REDDISH)
|
191
|
+
no_stroke
|
192
|
+
ellipse c1x, c1y, 5, 5
|
193
|
+
ellipse c2x, c2y, 5, 5
|
194
|
+
end
|
195
|
+
|
196
|
+
def draw_control_tangent_lines
|
197
|
+
c = current_curve
|
198
|
+
stroke color(*REDDISH)
|
199
|
+
stroke_width 1
|
200
|
+
line c1x, c1y, c.x1, c.y1
|
201
|
+
line c2x, c2y, c.x2, c.y2
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
BezierPlayground.new title: 'Bezier Playground'
|