Skip to content

Commit a6a0fae

Browse files
committed
More pdf export examples
1 parent 3916631 commit a6a0fae

File tree

11 files changed

+333
-1
lines changed

11 files changed

+333
-1
lines changed

processing_app/library/pdf/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pdf

processing_app/library/pdf/complex_3D.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
class Complex3D < Propane::App
1010
load_library :pdf
11-
include_package 'processing.pdf'
1211
attr_reader :num, :pt, :style, :dosave
1312

1413
def setup
Binary file not shown.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
require 'propane'
2+
3+
class LargePage < Propane::App
4+
#
5+
# Large Page.
6+
#
7+
# Saves one frame as a PDF with a size larger
8+
# than the screen. When PDF is used as the renderer
9+
# (the third parameter of size) the display window
10+
# does not open. The file is saved to the sketch folder.
11+
load_libraries 'pdf'
12+
include_package 'processing.pdf'
13+
14+
def setup
15+
sketch_title 'Large Page'
16+
end
17+
18+
def draw
19+
background(255)
20+
stroke(0, 20)
21+
strokeWeight(20.0)
22+
line(200, 0, width / 2, height)
23+
exit # Quit the program
24+
end
25+
26+
def settings
27+
size(2000, 2000, PDF, data_path('Line.pdf'))
28+
end
29+
end
30+
LargePage.new
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
############################
4+
# Simple lsystem grammar
5+
############################
6+
class Grammar
7+
attr_reader :axiom, :rules
8+
def initialize(axiom, rules)
9+
@axiom = axiom
10+
@rules = rules
11+
end
12+
13+
def apply_rules(prod)
14+
prod.gsub(/./) { |token| rules.fetch(token, token) }
15+
end
16+
17+
def generate(gen)
18+
return axiom if gen.zero?
19+
20+
prod = axiom
21+
gen.times do
22+
prod = apply_rules(prod)
23+
end
24+
prod
25+
end
26+
end
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# frozen_string_literal: true
2+
3+
Pen = Struct.new(:x, :y, :angle, :color)
4+
5+
#############################
6+
# PenroseColored class
7+
#############################
8+
class PenroseColored
9+
include Propane::Proxy
10+
11+
attr_reader :axiom, :grammar, :start_length, :theta, :production,
12+
:draw_length, :repeats, :xpos, :ypos
13+
14+
DELTA = 36 # degrees
15+
RED = 70 << 24 | 200 << 16 | 0 << 8 | 0 # using bit operations to set color int
16+
BLUE = 70 << 24 | 0 << 16 | 0 << 8 | 200
17+
18+
def initialize(xpos, ypos) # Note use of abbreviated grammar
19+
@axiom = '[X]2+[X]2+[X]2+[X]2+[X]' # nos, used to indicate repeats
20+
@grammar = Grammar.new(
21+
axiom,
22+
'F' => '', # a so called deletion rule
23+
'W' => 'YBF2+ZRF4-XBF[-YBF4-WRF]2+',
24+
'X' => '+YBF2-ZRF[3-WRF2-XBF]+',
25+
'Y' => '-WRF2+XBF[3+YBF2+ZRF]-',
26+
'Z' => '2-YBF4+WRF[+ZRF4+XBF]2-XBF'
27+
)
28+
@start_length = 1000.0
29+
@theta = 0
30+
@xpos = xpos
31+
@ypos = ypos
32+
@production = axiom.split('')
33+
@draw_length = start_length
34+
end
35+
36+
##############################################################################
37+
# Not strictly in the spirit of either processing in my render
38+
# function I have ignored the processing translate/rotate functions in favour
39+
# of the direct calculation of the new x and y positions, thus avoiding such
40+
# affine transformations.
41+
##############################################################################
42+
43+
def render
44+
repeats = 1
45+
ignored = %w[W X Y Z]
46+
repeated = %w[1 2 3 4]
47+
pen = Pen.new(xpos, ypos, theta, :R) # simple Struct for pen, symbol :R = red
48+
stack = [] # simple array for stack
49+
production.scan(/./) do |element|
50+
case element
51+
when 'F'
52+
pen = draw_line(pen, draw_length)
53+
when '+'
54+
pen.angle += DELTA * repeats
55+
repeats = 1
56+
when '-'
57+
pen.angle -= DELTA * repeats
58+
repeats = 1
59+
when '['
60+
stack << pen.dup # push a copy current pen to stack
61+
when ']'
62+
pen = stack.pop # assign current pen to instance off the stack
63+
when 'R', 'B'
64+
pen.color = element.to_sym # set pen color as symbol
65+
when *ignored
66+
when *repeated
67+
repeats = element.to_i
68+
else puts format('Character %<ch>s not in grammar', ch: element)
69+
end
70+
end
71+
end
72+
#####################################################
73+
# create grammar from axiom and # rules (adjust scale)
74+
#####################################################
75+
76+
def create_grammar(gen)
77+
@draw_length *= 0.5**gen
78+
@production = grammar.generate gen
79+
end
80+
81+
private
82+
83+
####################################################################
84+
# draws line using current pen position, color and length parameters
85+
# returns a pen corresponding to the new position
86+
###################################################################
87+
88+
def draw_line(pen, length)
89+
stroke(pen.color == :R ? RED : BLUE)
90+
new_xpos = pen.x - length * DegLut.cos(pen.angle)
91+
new_ypos = pen.y - length * DegLut.sin(pen.angle)
92+
line(pen.x, pen.y, new_xpos, new_ypos) # draw line
93+
Pen.new(new_xpos, new_ypos, pen.angle, pen.color) # return pen @ new pos
94+
end
95+
end
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
require 'picrate'
2+
3+
class ManyFrames < Propane::App
4+
#
5+
# Saves one PDF document of many frames drawn to the screen.
6+
# Starts the file when the mouse is pressed and end the file
7+
# when the mouse is released.
8+
load_library 'pdf'
9+
include_package 'processing.pdf'
10+
11+
def setup
12+
sketch_title 'Many Frames'
13+
frame_rate(24)
14+
background(255)
15+
end
16+
17+
def draw
18+
stroke(0, 20)
19+
stroke_weight(20.0)
20+
line(mouse_x, 0, width-mouse_y, height)
21+
end
22+
23+
def mouse_pressed
24+
begin_record(PDF, data_path('Lines.pdf'))
25+
background(255)
26+
end
27+
28+
def mouse_released
29+
end_record
30+
background(255)
31+
end
32+
33+
def settings
34+
size(600, 600)
35+
end
36+
end
37+
38+
ManyFrames.new
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
require 'propane'
2+
3+
class ManyPages < Propane::App
4+
#
5+
# Saves a new page into a PDF file each loop through draw().
6+
# Pressing the mouse finishes writing the file and exits the program.
7+
#
8+
load_library 'pdf'
9+
include_package 'processing.pdf'
10+
11+
attr_reader :pdf
12+
13+
def setup
14+
sketch_title 'Many Pages'
15+
frame_rate(4)
16+
@pdf = begin_record(PDF, data_path('Lines.pdf'))
17+
begin_record(pdf)
18+
end
19+
20+
def draw
21+
background(255)
22+
stroke(0, 20)
23+
stroke_weight(20.0)
24+
line(mouse_x, 0, width - mouse_y, height)
25+
pdf.nextPage
26+
end
27+
28+
def mouse_pressed
29+
end_record
30+
exit
31+
end
32+
33+
def settings
34+
size(600, 600)
35+
end
36+
end
37+
ManyPages.new
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
require 'propane'
2+
3+
class ManyPDFS < Propane::App
4+
#
5+
# Saves one PDF file each each frame while the mouse is pressed.
6+
# When the mouse is released, the PDF creation stops.
7+
#
8+
load_library 'pdf'
9+
include_package 'processing.pdf'
10+
11+
attr_reader :pdf, :save_pdf
12+
13+
def setup
14+
sketch_title 'Many Pdfs'
15+
frameRate(24)
16+
@save_pdf = false
17+
end
18+
19+
def draw
20+
begin_record(PDF, data_path("lines#{frame_count}.pdf")) unless !save_pdf
21+
background(255)
22+
stroke(0, 20)
23+
stroke_weight(20.0)
24+
line(mouse_x, 0, width-mouse_y, height)
25+
end_record unless !save_pdf
26+
end
27+
28+
def mouse_pressed
29+
@save_pdf = true
30+
end
31+
32+
def mouse_released
33+
@save_pdf = false
34+
end
35+
36+
def settings
37+
size(600, 600)
38+
end
39+
end
40+
41+
ManyPDFS.new
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
require 'propane'
2+
# One Frame.
3+
#
4+
# Saves one PDF with the contents of the display window.
5+
# Because this example uses beginRecord, the image is shown
6+
# on the display window and is saved to the file.
7+
class OneFrame < Propane::App
8+
load_library 'pdf'
9+
include_package 'processing.pdf'
10+
11+
def setup
12+
sketch_title 'One Frame'
13+
begin_record(PDF, data_path('line.pdf'))
14+
background(255)
15+
stroke(0, 20)
16+
strokeWeight(20.0)
17+
line(200, 0, 400, height)
18+
end_record
19+
end
20+
21+
def settings
22+
size(600, 600)
23+
end
24+
end
25+
OneFrame.new

0 commit comments

Comments
 (0)