propane 0.7.0-java → 0.8.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -3
- data/CHANGELOG.md +2 -0
- data/README.md +3 -5
- data/examples/{complete → data_path}/Rakefile +2 -2
- data/examples/{complete → data_path}/bw_shader.rb +7 -6
- data/examples/{complete → data_path}/data/Texture01.jpg +0 -0
- data/examples/{complete → data_path}/data/Texture02.jpg +0 -0
- data/examples/{complete → data_path}/data/Univers45.vlw +0 -0
- data/examples/{complete → data_path}/data/bwfrag.glsl +0 -0
- data/examples/{complete → data_path}/data/displaceFrag.glsl +0 -0
- data/examples/{complete → data_path}/data/displaceVert.glsl +0 -0
- data/examples/{complete → data_path}/data/lachoy.jpg +0 -0
- data/examples/{complete → data_path}/data/landscape.glsl +0 -0
- data/examples/{complete → data_path}/data/monjori.glsl +0 -0
- data/examples/{complete → data_path}/data/moon.jpg +0 -0
- data/examples/{complete → data_path}/data/sea.jpg +0 -0
- data/examples/{complete → data_path}/edge_detection.rb +2 -2
- data/examples/{complete → data_path}/glsl_heightmap_noise.rb +9 -5
- data/examples/{complete → data_path}/kinetic_type.rb +5 -5
- data/examples/{complete → data_path}/landscape.rb +11 -9
- data/examples/{complete → data_path}/linear_image.rb +2 -2
- data/examples/{complete → data_path}/monjori.rb +7 -5
- data/examples/regular/arcball_box.rb +3 -13
- data/examples/regular/arcball_constrain.rb +12 -21
- data/examples/regular/bezier_playground.rb +32 -31
- data/examples/regular/circle_collision.rb +9 -9
- data/examples/regular/colors_two.rb +2 -1
- data/examples/regular/creating_colors.rb +2 -2
- data/examples/regular/drawolver.rb +1 -0
- data/examples/regular/elegant_ball.rb +1 -1
- data/examples/regular/empathy.rb +11 -10
- data/examples/regular/fern.rb +1 -0
- data/examples/regular/fibonacci_sphere.rb +1 -0
- data/examples/regular/flight_patterns.rb +6 -5
- data/examples/regular/fractions.rb +1 -0
- data/examples/regular/grapher.rb +6 -5
- data/examples/regular/gravity.rb +17 -17
- data/examples/regular/grey_circles.rb +2 -2
- data/examples/regular/jwishy.rb +5 -6
- data/examples/regular/letters.rb +19 -19
- data/examples/regular/liquidy.rb +5 -4
- data/examples/regular/mouse_button_demo.rb +5 -7
- data/examples/regular/polyhedrons.rb +1 -0
- data/examples/regular/raining.rb +6 -5
- data/examples/regular/ribbon_doodle.rb +1 -1
- data/examples/regular/select_file.rb +32 -0
- data/examples/regular/select_image.rb +40 -0
- data/examples/regular/slider_demo.rb +2 -1
- data/examples/regular/slider_example.rb +1 -1
- data/examples/regular/slider_simple.rb +1 -1
- data/examples/regular/tree.rb +7 -6
- data/lib/propane/creators/sketch_writer.rb +66 -0
- data/lib/propane/library_loader.rb +1 -5
- data/lib/propane/runner.rb +4 -3
- data/lib/propane/version.rb +1 -1
- data/library/file_chooser/chooser.rb +20 -0
- data/library/file_chooser/file_chooser.rb +20 -0
- data/pom.rb +1 -1
- data/pom.xml +1 -1
- data/propane.gemspec +1 -1
- data/src/monkstone/MathToolModule.java +63 -47
- data/src/monkstone/filechooser/Chooser.java +44 -0
- data/test/create_test.rb +48 -0
- metadata +30 -23
- data/lib/propane/creators/creator.rb +0 -136
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25e44d0b96666b6c45b686f6ae303be7283a795a
|
4
|
+
data.tar.gz: e5f305b7cffdc904312fe7ad21f47017d5ca7db0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac4bf37b116eed1296a1023cff3ae9c6eb8b59db426085801e30e696e6592057d4f7d8f24c75536e0e61f8b82d29c7096f599a44b36b04fb199f276110923fca
|
7
|
+
data.tar.gz: c5a4797c0d6b96ff95083f840d9e3805437581c7beb0983473cfdd0a9ebe76d9b08a62a37824fbb850c15b7c16f325885e42118aa9f7119ca1e992c6dd739f3c
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
**v0.8.0** Complete samples refactored to `data_path` folder, no longer require jruby-complete to run because we provide an absolute path to `data` folder, but it still probably requires that you run the sketch from the directory. Future direction might be to create a `~/.propane` folder, which would support additionalvanilla processing libraries, also integration with `atom` editor.
|
2
|
+
|
1
3
|
**v0.7.0** Update to JRuby-Complete-9.1.2.0.
|
2
4
|
|
3
5
|
**v0.6.0** Includes a sketch creator utility 3D still only for linux64 and macosx, any Windows developers are welcome to extend to windows (should be easy), includes slider in sketch library, change to requiring jdk8. Update to JRuby-Complete-9.1.0.0, request updated arcball (to run samples).
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Propane
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/propane.svg)](https://badge.fury.io/rb/propane)
|
3
3
|
|
4
|
-
A slim layer to communicate with Processing from JRuby, features a polyglot maven build, this started out as a non serious project by Phillip Cunningam called ribiprocessing. It has now morphed into an experimental project for ruby-processing so we can now "Cook with Gas". We have created a configuration free version of ruby processing, albeit tied to processing-2.2.1, where we get processing core from maven central (and opengl currently testing on linux64/mac). These jars are small enough to include in the gem distribution, and hence we should not require configuration. This has created a
|
4
|
+
A slim layer to communicate with Processing from JRuby, features a polyglot maven build, this started out as a non serious project by Phillip Cunningam called ribiprocessing. It has now morphed into an experimental project for ruby-processing so we can now "Cook with Gas". We have created a configuration free version of ruby processing, albeit tied to processing-2.2.1, where we get processing core from maven central (and opengl currently testing on linux64/mac). These jars are small enough to include in the gem distribution, and hence we should not require configuration. This has created a scriptable version, ie files get run direct from jruby, but you could use jruby-complete if you used the propane script (avoids need to give the absolute data path for the data folder, but would also be needed for a watch mode).
|
5
5
|
## Requirements
|
6
6
|
|
7
7
|
- jdk8+ since version 0.6.0
|
8
|
-
- jruby-9.
|
8
|
+
- jruby-9.1.2.0+
|
9
9
|
- mvn-3.3.1+ (development only)
|
10
10
|
|
11
11
|
## Building and testing
|
@@ -19,7 +19,7 @@ rake javadoc
|
|
19
19
|
## Installation
|
20
20
|
```bash
|
21
21
|
jgem install propane-{version}-java.gem # local install
|
22
|
-
jgem install propane
|
22
|
+
jgem install propane # from rubygems.org
|
23
23
|
```
|
24
24
|
|
25
25
|
## Usage
|
@@ -67,8 +67,6 @@ There is a handy sketch creator tool
|
|
67
67
|
propane -c my_sketch 200 200 # for default renderer
|
68
68
|
propane -c my_sketch 200 200 p2d # for opengl 2D renderer
|
69
69
|
propane -c my_sketch 200 200 p3d # for opengl 3D renderer
|
70
|
-
```
|
71
|
-
NB: will not overwrite existing sketch with the same name eg `my_sketch.rb` above
|
72
70
|
|
73
71
|
To run sketches using the installed jruby-complete, you can also use shortform `-r`
|
74
72
|
```bash
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
# Simple demo Rakefile to autorun samples in current directory
|
4
|
-
#
|
4
|
+
# NB: If using atom install build and build-rake packages to run from atom
|
5
5
|
|
6
6
|
SAMPLES_DIR = './'
|
7
7
|
|
@@ -24,7 +24,7 @@ end
|
|
24
24
|
|
25
25
|
def run_sample(sample_name)
|
26
26
|
puts "Running #{sample_name}...quit to run next sample"
|
27
|
-
open("|jruby
|
27
|
+
open("|jruby #{sample_name}", 'r') do |io|
|
28
28
|
while l = io.gets
|
29
29
|
puts(l.chop)
|
30
30
|
end
|
@@ -1,19 +1,20 @@
|
|
1
|
+
#!/usr/bin/env jruby -v -W2
|
1
2
|
require 'propane'
|
2
3
|
|
3
4
|
class BwShader < Propane::App
|
4
5
|
# Texture from Jason Liebig's FLICKR collection of vintage labels and wrappers:
|
5
6
|
# http://www.flickr.com/photos/jasonliebigstuff/3739263136/in/photostream/
|
6
|
-
|
7
|
+
|
7
8
|
attr_reader :label, :can, :angle, :bw_shader
|
8
|
-
|
9
|
+
|
9
10
|
def setup
|
10
11
|
size(640, 360, P3D)
|
11
|
-
@label = load_image('lachoy.jpg')
|
12
|
+
@label = load_image(File.expand_path('./data/lachoy.jpg'))
|
12
13
|
@can = create_can(100, 200, 32, label)
|
13
|
-
@bw_shader = load_shader('bwfrag.glsl')
|
14
|
+
@bw_shader = load_shader(File.expand_path('./data/bwfrag.glsl'))
|
14
15
|
@angle = 0
|
15
16
|
end
|
16
|
-
|
17
|
+
|
17
18
|
def draw
|
18
19
|
background(0)
|
19
20
|
shader(bw_shader)
|
@@ -22,7 +23,7 @@ class BwShader < Propane::App
|
|
22
23
|
shape(can)
|
23
24
|
@angle += 0.01
|
24
25
|
end
|
25
|
-
|
26
|
+
|
26
27
|
def create_can(r, h, detail, tex)
|
27
28
|
texture_mode(NORMAL)
|
28
29
|
sh = create_shape
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env jruby -v -W2
|
2
2
|
# frozen_string_literal: true
|
3
3
|
require 'propane'
|
4
4
|
# Edge Detection.
|
@@ -12,7 +12,7 @@ class EdgeDetection < Propane::App
|
|
12
12
|
|
13
13
|
def setup
|
14
14
|
size(640, 360)
|
15
|
-
@img = load_image('moon.jpg') # Load the original image
|
15
|
+
@img = load_image(File.expand_path('./data/moon.jpg')) # Load the original image
|
16
16
|
no_loop
|
17
17
|
end
|
18
18
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env jruby -v -W2
|
2
2
|
# frozen_string_literal: true
|
3
3
|
# Noise-Based GLSL Heightmap by Amnon Owed (May 2013)
|
4
4
|
# https://github.com/AmnonOwed
|
@@ -8,14 +8,16 @@
|
|
8
8
|
#
|
9
9
|
# c = cycle through the color maps
|
10
10
|
#
|
11
|
-
# Tested with propane-0.
|
11
|
+
# Tested with propane-0.8.0
|
12
12
|
#
|
13
13
|
# Photographs by Folkert Gorter (@folkertgorter / http://superfamous.com/) made available under a CC Attribution 3.0 license.
|
14
14
|
|
15
|
-
require 'propane'
|
15
|
+
require 'propane'
|
16
16
|
|
17
17
|
class HeightMap < Propane::App
|
18
18
|
include Propane::Render
|
19
|
+
SHADERS = %w(displaceFrag.glsl displaceVert.glsl).freeze
|
20
|
+
SHADER_NAME = %i(frag vert).freeze
|
19
21
|
DIM = 300 # the grid dimensions of the heightmap
|
20
22
|
attr_reader :blur_factor # the blur for the displacement map
|
21
23
|
attr_reader :resize_factor # the resize factor for the displacement map
|
@@ -34,10 +36,12 @@ class HeightMap < Propane::App
|
|
34
36
|
displace_strength = 0.25 # the displace strength of the GLSL shader displacement effect
|
35
37
|
# load the images from the _Images folder (relative path from this sketch's folder)
|
36
38
|
textures = %w(Texture01.jpg Texture02.jpg)
|
37
|
-
|
39
|
+
glsl_files = SHADERS.map { |shade| File.expand_path("./data/#{shade}") }
|
40
|
+
shaders = SHADER_NAME.zip(glsl_files.to_java(:string)).to_h
|
41
|
+
@images = textures.map { |texture| load_image(File.expand_path("./data/#{texture}")) }
|
38
42
|
@color_map = 0
|
39
43
|
# load the PShader with a fragment and a vertex shader
|
40
|
-
@displace = load_shader(
|
44
|
+
@displace = load_shader(shaders[:frag], shaders[:vert])
|
41
45
|
displace.set('displaceStrength', displace_strength) # set the displace_strength
|
42
46
|
displace.set('colorMap', images[color_map]) # set the initial colorMap
|
43
47
|
# create the heightmap PShape (see custom creation method) and put it in the global height_map reference
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env jruby -v -W2
|
2
2
|
# frozen_string_literal: true
|
3
3
|
# From the Processing Examples
|
4
4
|
# by Zach Lieberman
|
@@ -11,18 +11,18 @@ WORDS = %w(sometimes\ it's\ like the\ lines\ of\ text are\ so\ happy
|
|
11
11
|
require 'propane' # temporary local
|
12
12
|
|
13
13
|
# dispay them 'words'
|
14
|
-
class KineticType < Propane::App
|
15
|
-
|
14
|
+
class KineticType < Propane::App
|
15
|
+
|
16
16
|
def setup
|
17
17
|
size(200, 200, P3D)
|
18
18
|
frame_rate 30
|
19
19
|
# Load the font from the sketch's data directory.
|
20
|
-
text_font load_font(
|
20
|
+
text_font load_font(File.expand_path('./data/Univers45.vlw')), 1.0
|
21
21
|
fill 255
|
22
22
|
# Creating the line objects
|
23
23
|
@lines = WORDS.map.with_index { |word, i| Line.new(self, word, 0, i * 70) }
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def draw
|
27
27
|
background 0
|
28
28
|
translate(-240, -120, -450)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env jruby -v -W2
|
2
|
+
# frozen_string_literal: true
|
1
3
|
require 'propane'
|
2
4
|
|
3
5
|
class Landscape < Propane::App
|
@@ -7,26 +9,26 @@ class Landscape < Propane::App
|
|
7
9
|
# Created by inigo quilez - iq/2013
|
8
10
|
# License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
|
9
11
|
# Processing port by Raphaël de Courville.
|
10
|
-
#
|
11
|
-
attr_reader :landscape
|
12
|
+
#
|
13
|
+
attr_reader :landscape
|
12
14
|
java_alias :background_int, :background, [Java::int]
|
13
|
-
|
15
|
+
|
14
16
|
def setup
|
15
17
|
size(640, 360, P2D)
|
16
|
-
no_stroke
|
18
|
+
no_stroke
|
17
19
|
# The code of this shader shows how to integrate shaders from shadertoy
|
18
20
|
# into Processing with minimal changes.
|
19
|
-
@landscape = load_shader(
|
21
|
+
@landscape = load_shader(File.expand_path('./data/landscape.glsl'))
|
20
22
|
landscape.set('resolution', width.to_f, height.to_f)
|
21
23
|
end
|
22
|
-
|
24
|
+
|
23
25
|
def draw
|
24
|
-
background_int 0
|
26
|
+
background_int 0
|
25
27
|
landscape.set('time', (millis/1000.0).to_f)
|
26
28
|
shader(landscape)
|
27
|
-
rect(0, 0, width, height)
|
29
|
+
rect(0, 0, width, height)
|
28
30
|
frame.set_title("frame: #{frame_count} - fps: #{format('%0.2f', frame_rate)}")
|
29
|
-
end
|
31
|
+
end
|
30
32
|
end
|
31
33
|
|
32
34
|
Landscape.new title: 'Landscape'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env jruby -v -W2
|
2
2
|
# frozen_string_literal: true
|
3
3
|
require 'propane'
|
4
4
|
# Linear Image.
|
@@ -15,7 +15,7 @@ class LinearImage < Propane::App
|
|
15
15
|
def setup
|
16
16
|
size(640, 360)
|
17
17
|
stroke(255)
|
18
|
-
@img =
|
18
|
+
@img = load_image(File.expand_path('./data/sea.jpg'))
|
19
19
|
@direction = 1
|
20
20
|
@signal = 0
|
21
21
|
img.load_pixels
|
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env jruby -v -W2
|
2
|
+
# frozen_string_literal: true
|
1
3
|
require 'propane'
|
2
4
|
|
3
5
|
class Monjori < Propane::App
|
@@ -9,16 +11,16 @@ class Monjori < Propane::App
|
|
9
11
|
# Ported from the webGL version available in ShaderToy:
|
10
12
|
# http://www.iquilezles.org/apps/shadertoy/
|
11
13
|
# (Look for Monjori under the Plane Deformations Presets)
|
12
|
-
|
14
|
+
|
13
15
|
attr_reader :monjori
|
14
|
-
|
16
|
+
|
15
17
|
def setup
|
16
18
|
size(640, 360, P2D)
|
17
19
|
no_stroke
|
18
|
-
@monjori = load_shader('monjori.glsl')
|
20
|
+
@monjori = load_shader(File.expand_path('./data/monjori.glsl'))
|
19
21
|
monjori.set('resolution', width.to_f, height.to_f)
|
20
22
|
end
|
21
|
-
|
23
|
+
|
22
24
|
def draw
|
23
25
|
monjori.set('time', millis / 1000.0)
|
24
26
|
shader(monjori)
|
@@ -27,7 +29,7 @@ class Monjori < Propane::App
|
|
27
29
|
# entire view area so every pixel is pushed through the
|
28
30
|
# shader.
|
29
31
|
rect(0, 0, width, height)
|
30
|
-
end
|
32
|
+
end
|
31
33
|
end
|
32
34
|
|
33
35
|
Monjori.new title: 'Monjori'
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#!/usr/bin/env jruby -v -w
|
3
2
|
require 'arcball'
|
3
|
+
require 'propane'
|
4
4
|
|
5
5
|
############################
|
6
6
|
# Use mouse drag to rotate
|
@@ -9,13 +9,6 @@ require 'arcball'
|
|
9
9
|
# to constrain rotation axis.
|
10
10
|
############################
|
11
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
12
|
class ArcballBox < Propane::App
|
20
13
|
|
21
14
|
def setup
|
@@ -26,13 +19,10 @@ def setup
|
|
26
19
|
end
|
27
20
|
|
28
21
|
def draw
|
29
|
-
background(50)
|
22
|
+
background(50)
|
30
23
|
box(300, 300, 300)
|
31
24
|
end
|
32
25
|
|
33
26
|
end
|
34
27
|
|
35
28
|
ArcballBox.new title: 'ArcBall Box'
|
36
|
-
|
37
|
-
|
38
|
-
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin//env jruby -v -w
|
2
2
|
|
3
|
+
require 'propane'
|
3
4
|
require 'arcball'
|
4
5
|
|
5
6
|
############################
|
@@ -9,30 +10,20 @@ require 'arcball'
|
|
9
10
|
# default is yaxis.
|
10
11
|
############################
|
11
12
|
|
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
13
|
class ArcballBox < Propane::App
|
20
14
|
|
21
|
-
def setup
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
15
|
+
def setup
|
16
|
+
size(600, 600, P3D)
|
17
|
+
smooth(8)
|
18
|
+
Processing::ArcBall.constrain(self, :xaxis)
|
19
|
+
fill 180
|
20
|
+
end
|
27
21
|
|
28
|
-
def draw
|
29
|
-
|
30
|
-
|
31
|
-
end
|
22
|
+
def draw
|
23
|
+
background(50)
|
24
|
+
box(300, 300, 300)
|
25
|
+
end
|
32
26
|
|
33
27
|
end
|
34
28
|
|
35
29
|
ArcballBox.new title: 'ArcBall Box'
|
36
|
-
|
37
|
-
|
38
|
-
|
@@ -1,3 +1,4 @@
|
|
1
|
+
#!/usr/bin/env jruby -v -w
|
1
2
|
require 'propane'
|
2
3
|
|
3
4
|
X1, Y1, X2, Y2 = 50.0, 50.0, 250.0, 250.0
|
@@ -13,35 +14,35 @@ end
|
|
13
14
|
class Curve
|
14
15
|
include Olap, Propane::Proxy
|
15
16
|
attr_accessor :x1, :y1, :c1x, :c1y, :c2x, :c2y, :x2, :y2
|
16
|
-
|
17
|
+
|
17
18
|
def initialize
|
18
19
|
@x1, @y1, @x2, @y2 = X1, Y1, X2, Y2
|
19
20
|
set_control_points(X1 + 30, Y1, X2 - 30, Y2)
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
def contains(x, y)
|
23
24
|
return :one if Olap.overlaps(x1, y1, x, y)
|
24
25
|
return :two if Olap.overlaps(x2, y2, x, y)
|
25
26
|
end
|
26
|
-
|
27
|
+
|
27
28
|
def all_points
|
28
29
|
return x1, y1, c1x, c1y, c2x, c2y, x2, y2
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
def control_points
|
32
33
|
return c1x, c1y, c2x, c2y
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
def set_control_points(*points)
|
36
37
|
@c1x, @c1y, @c2x, @c2y = *points
|
37
38
|
end
|
38
|
-
|
39
|
+
|
39
40
|
def draw
|
40
41
|
bezier(*all_points)
|
41
42
|
ellipse x1, y1, 3, 3
|
42
43
|
ellipse x2, y2, 3, 3
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
def print_equation(id)
|
46
47
|
pt = all_points.map(&:to_i)
|
47
48
|
puts ''
|
@@ -58,13 +59,13 @@ class BezierPlayground < Propane::App
|
|
58
59
|
# A Bezier playground. Click to shape the curve. Drag to move it.
|
59
60
|
# Arrows toggle between curves, delete removes them.
|
60
61
|
# You can print out the parametric equations for t = 0..1
|
61
|
-
|
62
|
+
|
62
63
|
attr_accessor :curves, :c1x, :c1y, :c2x, :c2y
|
63
|
-
attr_reader :panel, :hide
|
64
|
-
|
64
|
+
attr_reader :panel, :hide
|
65
|
+
|
65
66
|
load_library :control_panel
|
66
67
|
include Olap
|
67
|
-
|
68
|
+
|
68
69
|
def setup
|
69
70
|
size 300, 300
|
70
71
|
@curves = []
|
@@ -77,7 +78,7 @@ class BezierPlayground < Propane::App
|
|
77
78
|
end
|
78
79
|
generate_curve
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
def draw
|
82
83
|
unless hide
|
83
84
|
panel.visible = visible
|
@@ -88,40 +89,40 @@ class BezierPlayground < Propane::App
|
|
88
89
|
draw_curves
|
89
90
|
draw_current_control_points
|
90
91
|
end
|
91
|
-
|
92
|
+
|
92
93
|
def print_equations
|
93
94
|
curves.each_with_index { |c, i| c.print_equation(i + 1) }
|
94
95
|
end
|
95
|
-
|
96
|
+
|
96
97
|
def control_points
|
97
98
|
return c1x, c1y, c2x, c2y
|
98
99
|
end
|
99
|
-
|
100
|
+
|
100
101
|
def set_control_points(*points)
|
101
102
|
@c1x, @c1y, @c2x, @c2y = points.any? ? points : [X1, Y1, X2, Y2]
|
102
103
|
end
|
103
|
-
|
104
|
+
|
104
105
|
def generate_curve
|
105
106
|
curves << current_curve = Curve.new
|
106
107
|
@current = curves.length - 1
|
107
108
|
set_control_points(*current_curve.control_points)
|
108
109
|
end
|
109
|
-
|
110
|
+
|
110
111
|
def current_curve
|
111
112
|
curves[@current]
|
112
113
|
end
|
113
|
-
|
114
|
+
|
114
115
|
def new_curve
|
115
116
|
current_curve.set_control_points(c1x, c1y, c2x, c2y)
|
116
117
|
generate_curve
|
117
118
|
end
|
118
|
-
|
119
|
+
|
119
120
|
def clicked_control_point?
|
120
121
|
x, y = mouse_x, mouse_y
|
121
122
|
return :one if Olap.overlaps(c1x, c1y, x, y)
|
122
123
|
return :two if Olap.overlaps(c2x, c2y, x, y)
|
123
124
|
end
|
124
|
-
|
125
|
+
|
125
126
|
def mouse_pressed
|
126
127
|
switch_curve_if_endpoint_clicked
|
127
128
|
@control = clicked_control_point?
|
@@ -129,12 +130,12 @@ class BezierPlayground < Propane::App
|
|
129
130
|
curve = curves.detect { |c| c.contains(mouse_x, mouse_y) }
|
130
131
|
@end_point = curve.contains(mouse_x, mouse_y) if curve
|
131
132
|
end
|
132
|
-
|
133
|
+
|
133
134
|
def mouse_released
|
134
135
|
@control, @end_point = nil, nil
|
135
136
|
@hide = false
|
136
137
|
end
|
137
|
-
|
138
|
+
|
138
139
|
def mouse_dragged
|
139
140
|
offs = compute_offsets
|
140
141
|
return if offs.map(&:abs).max > 100
|
@@ -142,7 +143,7 @@ class BezierPlayground < Propane::App
|
|
142
143
|
return move_end_point(*offs) && move_control_point(*offs) if @end_point
|
143
144
|
move_current_curve(*offs)
|
144
145
|
end
|
145
|
-
|
146
|
+
|
146
147
|
def switch_curve_if_endpoint_clicked
|
147
148
|
become = curves.detect { |c| c.contains(mouse_x, mouse_y) }
|
148
149
|
return unless become && become != current_curve
|
@@ -150,7 +151,7 @@ class BezierPlayground < Propane::App
|
|
150
151
|
self.set_control_points(*become.control_points)
|
151
152
|
@current = curves.index(become)
|
152
153
|
end
|
153
|
-
|
154
|
+
|
154
155
|
def move_current_curve(x_off, y_off)
|
155
156
|
@c1x += x_off; @c2x += x_off
|
156
157
|
@c1y += y_off; @c2y += y_off
|
@@ -158,7 +159,7 @@ class BezierPlayground < Propane::App
|
|
158
159
|
current_curve.x1 += x_off; current_curve.x2 += x_off
|
159
160
|
current_curve.y1 += y_off; current_curve.y2 += y_off
|
160
161
|
end
|
161
|
-
|
162
|
+
|
162
163
|
def move_control_point(x_off, y_off)
|
163
164
|
case @control || @end_point
|
164
165
|
when :one then @c1x += x_off and @c1y += y_off
|
@@ -166,7 +167,7 @@ class BezierPlayground < Propane::App
|
|
166
167
|
end
|
167
168
|
current_curve.set_control_points(*control_points)
|
168
169
|
end
|
169
|
-
|
170
|
+
|
170
171
|
def move_end_point(x_off, y_off)
|
171
172
|
c = current_curve
|
172
173
|
case @end_point
|
@@ -174,32 +175,32 @@ class BezierPlayground < Propane::App
|
|
174
175
|
when :two then c.x2 += x_off and c.y2 += y_off
|
175
176
|
end
|
176
177
|
end
|
177
|
-
|
178
|
+
|
178
179
|
def compute_offsets
|
179
180
|
return mouse_x - pmouse_x, mouse_y - pmouse_y
|
180
181
|
end
|
181
|
-
|
182
|
+
|
182
183
|
def draw_curves
|
183
184
|
stroke 255
|
184
185
|
no_fill
|
185
186
|
stroke_width 2
|
186
187
|
curves.each(&:draw)
|
187
188
|
end
|
188
|
-
|
189
|
+
|
189
190
|
def draw_current_control_points
|
190
191
|
fill color(*REDDISH)
|
191
192
|
no_stroke
|
192
193
|
ellipse c1x, c1y, 5, 5
|
193
194
|
ellipse c2x, c2y, 5, 5
|
194
195
|
end
|
195
|
-
|
196
|
+
|
196
197
|
def draw_control_tangent_lines
|
197
198
|
c = current_curve
|
198
199
|
stroke color(*REDDISH)
|
199
200
|
stroke_width 1
|
200
201
|
line c1x, c1y, c.x1, c.y1
|
201
202
|
line c2x, c2y, c.x2, c.y2
|
202
|
-
end
|
203
|
+
end
|
203
204
|
end
|
204
205
|
|
205
206
|
BezierPlayground.new title: 'Bezier Playground'
|