propane 0.5.0-java → 0.6.0-java
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|