dudegl 0.2.1 → 0.2.2
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/lib/compose/arms.rb +41 -0
- data/lib/compose/body.rb +51 -0
- data/lib/compose/dudes_location.rb +48 -0
- data/lib/compose/legs.rb +25 -0
- data/lib/compose/limbs.rb +30 -0
- data/lib/config.rb +16 -4
- data/lib/dudegl.rb +31 -11
- data/lib/limbs/arm.rb +72 -0
- data/lib/limbs/leg.rb +41 -0
- data/lib/limbs/limb.rb +33 -0
- data/lib/render.rb +59 -0
- data/lib/utils.rb +4 -12
- metadata +11 -4
- data/lib/arm.rb +0 -80
- data/lib/dude.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 629bfb1702e517a1bf3f5f52fbf5b3c8eb7e82919cd122aadee7ffa494f35979
|
4
|
+
data.tar.gz: fa4395ff7d805a91016f9a384cb2928d7c777e84600e3ff473ff562c02eda072
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4531659105ee4b4e53cb098ddae20c75eb51bfc5175ace477dc2c705c8f435d2102c91347d789b45534f8dea6d12433130f929f51849094eb387a8b2196d76a
|
7
|
+
data.tar.gz: f2a4f167a1b012c647056ab937029eb9887c34184be036ce7d382f5235999b799ff97fc34f71602808420a4bc0620ca0fa9b174ff14e596610d8941a9938fcd3
|
data/lib/compose/arms.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../config'
|
2
|
+
require_relative 'limbs'
|
3
|
+
|
4
|
+
class Arms < Limbs
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def draw
|
9
|
+
super
|
10
|
+
divide_arms
|
11
|
+
|
12
|
+
@left_arms_num.times do |i|
|
13
|
+
@limbs << Arm.new(@left_arms[i], @body.body_left_x, hy(i), :left)
|
14
|
+
end
|
15
|
+
|
16
|
+
@right_arms_num.times do |i|
|
17
|
+
@limbs << Arm.new(@right_arms[i], @body.body_right_x, hy(i), :right)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def draw_parameters
|
22
|
+
return if super
|
23
|
+
|
24
|
+
remainder = @limbs_num % 2
|
25
|
+
|
26
|
+
@left_arms_num = (@limbs_num - remainder) / 2 + remainder
|
27
|
+
@right_arms_num = @limbs_num - @left_arms_num
|
28
|
+
|
29
|
+
# BODY_LENGTH * 0.9 - to avoid drawing hands on a body edges
|
30
|
+
@arms_step = ((Config::BODY_LENGTH * 0.9) / @left_arms_num).round
|
31
|
+
end
|
32
|
+
|
33
|
+
def divide_arms
|
34
|
+
@left_arms = @params_methods[0, @left_arms_num]
|
35
|
+
@right_arms = @params_methods[@left_arms_num, @limbs_num]
|
36
|
+
end
|
37
|
+
|
38
|
+
def hy(i)
|
39
|
+
(1.05 * @body.body_left_top_y + i * @arms_step).round
|
40
|
+
end
|
41
|
+
end
|
data/lib/compose/body.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative '../utils'
|
2
|
+
require_relative '../config'
|
3
|
+
|
4
|
+
class Body
|
5
|
+
include Utils
|
6
|
+
|
7
|
+
attr_reader :body_right_x, :body_right_top_y,
|
8
|
+
:body_left_x, :body_left_top_y, :draw_data
|
9
|
+
|
10
|
+
def initialize(name, offsets)
|
11
|
+
@name = name
|
12
|
+
@draw_data = []
|
13
|
+
@offset_x = offsets[:offset_x]
|
14
|
+
@offset_y = offsets[:offset_y]
|
15
|
+
draw_body
|
16
|
+
end
|
17
|
+
|
18
|
+
def draw_body
|
19
|
+
# head center
|
20
|
+
head_center_x = 0.5 * Config::DUDE_FRAME_SIZE + @offset_x
|
21
|
+
head_center_y = 0.3 * Config::DUDE_FRAME_SIZE + @offset_y
|
22
|
+
|
23
|
+
@body_right_x, @body_right_top_y = circle_rotate(head_center_x, head_center_y,
|
24
|
+
Config::HEAD_RADIUS,
|
25
|
+
Config::BODY_CENTER + Config::SLIM_FACTOR)
|
26
|
+
@body_left_x, @body_left_top_y = circle_rotate(head_center_x, head_center_y,
|
27
|
+
Config::HEAD_RADIUS,
|
28
|
+
Config::BODY_CENTER - Config::SLIM_FACTOR)
|
29
|
+
|
30
|
+
@draw_data << {
|
31
|
+
circle: {
|
32
|
+
cx: head_center_x,
|
33
|
+
cy: head_center_y,
|
34
|
+
r: Config::HEAD_RADIUS
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
@draw_data << draw_line(@body_right_x, @body_right_top_y,
|
39
|
+
@body_right_x, @body_right_top_y + Config::BODY_LENGTH)
|
40
|
+
# left part of a body
|
41
|
+
@draw_data << draw_line(@body_left_x, @body_left_top_y,
|
42
|
+
@body_left_x, @body_left_top_y + Config::BODY_LENGTH)
|
43
|
+
# bottom
|
44
|
+
@draw_data << draw_line(@body_right_x, @body_right_top_y + Config::BODY_LENGTH,
|
45
|
+
@body_left_x, @body_left_top_y + Config::BODY_LENGTH)
|
46
|
+
|
47
|
+
@draw_data << draw_caption(@name, head_center_x - Config::HEAD_RADIUS,
|
48
|
+
head_center_y - 1.1 * Config::HEAD_RADIUS,
|
49
|
+
font_size: 10)
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative '../config'
|
2
|
+
|
3
|
+
# arrange several dudes on canvas
|
4
|
+
class DudesLocation
|
5
|
+
attr_reader :offsets, :canvas_size_x, :canvas_size_y
|
6
|
+
|
7
|
+
def initialize(params_list, dudes_per_row_max = nil)
|
8
|
+
@dudes_num = params_list.size
|
9
|
+
@offsets = []
|
10
|
+
|
11
|
+
if dudes_per_row_max.nil?
|
12
|
+
@dudes_per_row_max = Config::DUDES_PER_ROW_MAX
|
13
|
+
else
|
14
|
+
@dudes_per_row_max = dudes_per_row_max
|
15
|
+
end
|
16
|
+
|
17
|
+
compute_dudes_coordiantes
|
18
|
+
compute_canvas_size
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# returns array with number of dudes in each row
|
24
|
+
# e.g. if we have 12 dudes and only 5 are allowed per row, then the output will be [5, 5, 2])
|
25
|
+
def compute_dudes_per_each_row
|
26
|
+
remaining_dudes = @dudes_num % @dudes_per_row_max
|
27
|
+
rows_num = (@dudes_num - remaining_dudes) / @dudes_per_row_max
|
28
|
+
full_rows = [@dudes_per_row_max] * rows_num
|
29
|
+
remaining_dudes > 0 ? full_rows + [remaining_dudes]: full_rows
|
30
|
+
end
|
31
|
+
|
32
|
+
def compute_dudes_coordiantes
|
33
|
+
@dudes_per_each_row = compute_dudes_per_each_row
|
34
|
+
offset_y = 0
|
35
|
+
@dudes_per_each_row.each_with_index do |dudes_in_row, y_index|
|
36
|
+
dudes_in_row.times do |x_index|
|
37
|
+
@offsets << { offset_x: x_index * Config::OFFSET_X, offset_y: y_index * Config::OFFSET_Y }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def compute_canvas_size
|
43
|
+
# max x size of canvas is x offset for the last dude in 1st row - @dudes_per_each_row.first - 1
|
44
|
+
# @offsets.last[:offset_y] - last dude has max y offset
|
45
|
+
@canvas_size_x = @offsets[@dudes_per_each_row.first - 1][:offset_x] + Config::DUDE_FRAME_SIZE
|
46
|
+
@canvas_size_y = @offsets.last[:offset_y] + Config::DUDE_FRAME_SIZE
|
47
|
+
end
|
48
|
+
end
|
data/lib/compose/legs.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../config'
|
2
|
+
require_relative 'limbs'
|
3
|
+
|
4
|
+
class Legs < Limbs
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def draw
|
9
|
+
super
|
10
|
+
|
11
|
+
@limbs_num.times do |i|
|
12
|
+
@limbs << Leg.new(@params_methods[i], hx(i), @body.body_right_top_y + Config::BODY_LENGTH)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def draw_parameters
|
17
|
+
return if super
|
18
|
+
@legs_step = (((@body.body_right_x - @body.body_left_x) * 0.9) / @limbs_num).round
|
19
|
+
end
|
20
|
+
|
21
|
+
def hx(i)
|
22
|
+
body_margin = (@body.body_right_x - @body.body_left_x) * 0.1
|
23
|
+
(@body.body_left_x + i * @legs_step + body_margin).round
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative '../config'
|
2
|
+
|
3
|
+
class Limbs
|
4
|
+
attr_reader :limbs
|
5
|
+
|
6
|
+
def initialize(params, body)
|
7
|
+
@params = params
|
8
|
+
@body = body
|
9
|
+
@limbs = []
|
10
|
+
|
11
|
+
draw_parameters
|
12
|
+
draw if @limbs_num.positive?
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def draw; end
|
18
|
+
|
19
|
+
def draw_parameters
|
20
|
+
@params_methods = @params[:methods].select { |param| param[:args].public_send(select_operator, 0) }
|
21
|
+
@limbs_num = @params_methods.size
|
22
|
+
return true if @limbs_num == 0
|
23
|
+
end
|
24
|
+
|
25
|
+
# dynamically select operator depending on a child class name
|
26
|
+
def select_operator
|
27
|
+
return '>' if self.class.name.downcase.include?('arm')
|
28
|
+
return '==' if self.class.name.downcase.include?('leg')
|
29
|
+
end
|
30
|
+
end
|
data/lib/config.rb
CHANGED
@@ -1,18 +1,30 @@
|
|
1
1
|
module Config
|
2
|
-
STYLE = { stroke: 'black', stroke_width: 1 }
|
3
2
|
IMAGE_DIR = 'images'
|
4
3
|
|
4
|
+
METHOD_LENGTH_OK_MAX = 5
|
5
|
+
|
6
|
+
# dude's parameters
|
5
7
|
BODY_LENGTH = 140
|
6
8
|
BODY_CENTER = Math::PI * (3 / 2.0)
|
7
9
|
# defines how slim is a body
|
8
10
|
SLIM_FACTOR = Math::PI * (2 / 8.0)
|
9
11
|
HEAD_RADIUS = 40
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
ARM_LENGTH_LONG = 70
|
13
|
+
LIMB_LENGTH = 40
|
14
|
+
LIMB_LENGTH_LONG = 70
|
14
15
|
ELLIPSE_LENGTH = 10
|
15
16
|
|
16
17
|
FINGER_LENGTH = 10
|
17
18
|
FINGER_ANGLE_START = Math::PI * (3 / 4.0)
|
19
|
+
FINGERS_RANGE = Math::PI / 2.0
|
20
|
+
|
21
|
+
# size of an square area in pixels where one dude is depicted
|
22
|
+
DUDE_FRAME_SIZE = 400
|
23
|
+
|
24
|
+
# for LocateDudes class
|
25
|
+
DUDES_PER_ROW_MAX = 6
|
26
|
+
|
27
|
+
# coordinates offset for drawing multiple dudes on a canvas
|
28
|
+
OFFSET_X = 0.7 * DUDE_FRAME_SIZE
|
29
|
+
OFFSET_Y = 0.8 * DUDE_FRAME_SIZE
|
18
30
|
end
|
data/lib/dudegl.rb
CHANGED
@@ -1,21 +1,41 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
1
|
+
require 'byebug'
|
2
|
+
# require all filder from current dir and subdirectories
|
3
|
+
Dir[File.dirname(__FILE__) + '/**/*.rb'].each {|file| require_relative file }
|
4
4
|
|
5
5
|
class DudeGl
|
6
|
-
def
|
7
|
-
@
|
6
|
+
def initialize(params_list, dudes_per_row_max = nil)
|
7
|
+
@params_list = params_list
|
8
|
+
@dudes = []
|
9
|
+
@locations = DudesLocation.new(@params_list, dudes_per_row_max)
|
10
|
+
|
11
|
+
build_dudes
|
12
|
+
end
|
13
|
+
|
14
|
+
def render
|
15
|
+
@svg = Render.new(@dudes.flatten,
|
16
|
+
width = @locations.canvas_size_x,
|
17
|
+
height = @locations.canvas_size_y)
|
8
18
|
end
|
9
19
|
|
10
|
-
def
|
11
|
-
|
20
|
+
def save(file_name)
|
21
|
+
File.open("images/#{file_name}.svg", 'w') { |file| file.write(@svg.contents) }
|
12
22
|
end
|
13
23
|
|
14
|
-
|
15
|
-
|
24
|
+
private
|
25
|
+
|
26
|
+
def build_dudes
|
27
|
+
@params_list.each_with_index { |params, index| @dudes << build_dude(params, index) }
|
16
28
|
end
|
17
29
|
|
18
|
-
def
|
19
|
-
@
|
30
|
+
def build_dude(params, index)
|
31
|
+
body = Body.new(params[:name], offsets = @locations.offsets[index])
|
32
|
+
|
33
|
+
arms = Arms.new(params, body).limbs
|
34
|
+
arms_draw_params = arms.map { |arm| arm.draw_data }
|
35
|
+
|
36
|
+
legs = Legs.new(params, body).limbs
|
37
|
+
legs_draw_params = legs.map { |leg| leg.draw_data }
|
38
|
+
|
39
|
+
(body.draw_data + arms_draw_params + legs_draw_params).flatten
|
20
40
|
end
|
21
41
|
end
|
data/lib/limbs/arm.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require_relative 'limb'
|
2
|
+
|
3
|
+
class Arm < Limb
|
4
|
+
attr_reader :body_side
|
5
|
+
|
6
|
+
def initialize(params, x0, y0, body_side)
|
7
|
+
@body_side = body_side
|
8
|
+
super(params, x0, y0)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def draw
|
14
|
+
super
|
15
|
+
@end_x = @x0 + @limb_length
|
16
|
+
|
17
|
+
if @params[:conditions].positive?
|
18
|
+
draw_conditions
|
19
|
+
else
|
20
|
+
@draw_data << draw_line(@x0, @y0, @x0 + @limb_length, @y0)
|
21
|
+
end
|
22
|
+
|
23
|
+
@draw_data << draw_caption(@params[:name], (@end_x - 20).round, (@y0 - 10).round)
|
24
|
+
draw_fingers(@params[:args])
|
25
|
+
end
|
26
|
+
|
27
|
+
def draw_conditions
|
28
|
+
@lines_num = @params[:conditions] + 1
|
29
|
+
@line_length = ((@limb_length.abs - @params[:conditions] * Config::ELLIPSE_LENGTH) / @lines_num).round
|
30
|
+
|
31
|
+
@x1 = @x0 + @line_length * orientation
|
32
|
+
|
33
|
+
@lines_num.times { |i| draw_condition(i) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def draw_condition(i)
|
37
|
+
@draw_data << draw_line(@x0, @y0, @x1, @y0)
|
38
|
+
|
39
|
+
@draw_data << { ellipse: {
|
40
|
+
cx: (@x1 + Config::ELLIPSE_LENGTH * orientation / 2).round,
|
41
|
+
cy: @y0, rx: (Config::ELLIPSE_LENGTH / 2).round,
|
42
|
+
ry: (Config::ELLIPSE_LENGTH / 4).round }} if i < @lines_num - 1
|
43
|
+
|
44
|
+
@x0 += (@line_length + Config::ELLIPSE_LENGTH) * orientation
|
45
|
+
@x1 = @x0 + @line_length * orientation
|
46
|
+
end
|
47
|
+
|
48
|
+
def draw_fingers(args_num)
|
49
|
+
if body_side == :left
|
50
|
+
finger_angle_start = Config::FINGER_ANGLE_START
|
51
|
+
finger_angle_end = finger_angle_start + Config::FINGERS_RANGE
|
52
|
+
finger_angle_step = calc_fingers_range(Config::FINGERS_RANGE, args_num)
|
53
|
+
else
|
54
|
+
finger_angle_start = - Config::FINGER_ANGLE_START + Math::PI
|
55
|
+
finger_angle_end = finger_angle_start - Config::FINGERS_RANGE
|
56
|
+
finger_angle_step = - calc_fingers_range(Config::FINGERS_RANGE, args_num)
|
57
|
+
end
|
58
|
+
|
59
|
+
args_num.times do |i|
|
60
|
+
finger_end_x, finger_end_y = circle_rotate(end_x, end_y, Config::FINGER_LENGTH,
|
61
|
+
finger_angle_start + finger_angle_step * i)
|
62
|
+
|
63
|
+
@draw_data << draw_line(end_x, end_y, finger_end_x, finger_end_y)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def calc_fingers_range(fingers_range, args_num)
|
68
|
+
return fingers_range / (args_num - 1).to_f if args_num > 1
|
69
|
+
return fingers_range / args_num.to_f if args_num == 1
|
70
|
+
return 0
|
71
|
+
end
|
72
|
+
end
|
data/lib/limbs/leg.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative 'limb'
|
2
|
+
|
3
|
+
class Leg < Limb
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def draw
|
8
|
+
super
|
9
|
+
caption_start_x = @x0
|
10
|
+
caption_y_start = @y0
|
11
|
+
|
12
|
+
if @params[:conditions].positive?
|
13
|
+
draw_conditions
|
14
|
+
else
|
15
|
+
@draw_data << draw_line(@x0, @y0, @x0, @y0 + @limb_length)
|
16
|
+
end
|
17
|
+
|
18
|
+
@draw_data << draw_caption(@params[:name], (caption_start_x + 10).round, (caption_y_start + 10).round, 9, :tb)
|
19
|
+
end
|
20
|
+
|
21
|
+
def draw_conditions
|
22
|
+
@lines_num = @params[:conditions] + 1
|
23
|
+
@line_length = ((@limb_length.abs - @params[:conditions] * Config::ELLIPSE_LENGTH) / @lines_num).round
|
24
|
+
|
25
|
+
@y1 = @y0 + @line_length
|
26
|
+
|
27
|
+
@lines_num.times { |i| draw_condition(i) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def draw_condition(i)
|
31
|
+
@draw_data << draw_line(@x0, @y0, @x0, @y1)
|
32
|
+
|
33
|
+
@draw_data << { ellipse: {
|
34
|
+
cx: @x0, cy: (@y1 + Config::ELLIPSE_LENGTH / 2).round ,
|
35
|
+
rx: (Config::ELLIPSE_LENGTH / 4).round, ry: (Config::ELLIPSE_LENGTH / 2).round
|
36
|
+
}} if i < @lines_num - 1
|
37
|
+
|
38
|
+
@y0 += @line_length + Config::ELLIPSE_LENGTH
|
39
|
+
@y1 = @y0 + @line_length
|
40
|
+
end
|
41
|
+
end
|
data/lib/limbs/limb.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../config'
|
2
|
+
|
3
|
+
class Limb
|
4
|
+
include Utils
|
5
|
+
|
6
|
+
attr_reader :end_x, :end_y, :draw_data
|
7
|
+
|
8
|
+
def initialize(params, x0, y0)
|
9
|
+
@params = params
|
10
|
+
@x0 = x0
|
11
|
+
@end_y = @y0 = y0
|
12
|
+
@draw_data = []
|
13
|
+
|
14
|
+
draw
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def draw
|
20
|
+
@limb_length = compute_limb_length
|
21
|
+
end
|
22
|
+
|
23
|
+
def compute_limb_length
|
24
|
+
@params[:length] <= Config::METHOD_LENGTH_OK_MAX ? Config::LIMB_LENGTH * orientation : Config::LIMB_LENGTH_LONG * orientation
|
25
|
+
end
|
26
|
+
|
27
|
+
def orientation
|
28
|
+
return 1 if @body_side.nil?
|
29
|
+
@body_side == :left ? -1 : 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def draw_conditions; end
|
33
|
+
end
|
data/lib/render.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative 'config'
|
2
|
+
|
3
|
+
class Render
|
4
|
+
attr_reader :contents
|
5
|
+
|
6
|
+
def initialize(elements, width = Config::DUDE_FRAME_SIZE, height = Config::DUDE_FRAME_SIZE)
|
7
|
+
code = []
|
8
|
+
code << %Q[<svg width="#{width}" height="#{height}" style="background:white" xmlns="http://www.w3.org/2000/svg">]
|
9
|
+
elements.each { |element| code << hash_to_svg(element) }
|
10
|
+
code << %Q[</svg>]
|
11
|
+
|
12
|
+
@contents = code.join("\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def hash_to_svg(hash)
|
18
|
+
operator, params = hash.first
|
19
|
+
send("svg_#{operator.to_s}".to_sym, params) if defined? operator
|
20
|
+
end
|
21
|
+
|
22
|
+
def svg_line(params)
|
23
|
+
<<~LINE.gsub(/\s+/, " ").strip
|
24
|
+
<line x1="#{params[:x1]}" y1="#{params[:y1]}"
|
25
|
+
x2="#{params[:x2]}"
|
26
|
+
y2="#{params[:y2]}"
|
27
|
+
style="stroke:black; stroke-width:1"/>
|
28
|
+
LINE
|
29
|
+
end
|
30
|
+
|
31
|
+
def svg_circle(params)
|
32
|
+
<<~CIRCLE.gsub(/\s+/, " ").strip
|
33
|
+
<circle cx="#{params[:cx]}"
|
34
|
+
cy="#{params[:cy]}"
|
35
|
+
r="#{params[:r]}"
|
36
|
+
fill="white" style="stroke:black; stroke-width:1"/>
|
37
|
+
CIRCLE
|
38
|
+
end
|
39
|
+
|
40
|
+
def svg_ellipse(params)
|
41
|
+
<<~ELLIPSE.gsub(/\s+/, " ").strip
|
42
|
+
<ellipse cx="#{params[:cx]}"
|
43
|
+
cy="#{params[:cy]}"
|
44
|
+
rx="#{params[:rx]}"
|
45
|
+
ry="#{params[:ry]}"
|
46
|
+
style="stroke:black; stroke-width:1" fill="white"/>
|
47
|
+
ELLIPSE
|
48
|
+
end
|
49
|
+
|
50
|
+
def svg_text(params)
|
51
|
+
<<~TEXT.gsub(/\s+/, " ").strip
|
52
|
+
<text x="#{params[:x]}"
|
53
|
+
y="#{params[:y]}"
|
54
|
+
font-family="arial" font-size="#{params[:font_size]}"
|
55
|
+
fill="black" style="writing-mode:
|
56
|
+
#{params[:orientation].to_s}">#{params[:caption]}</text>
|
57
|
+
TEXT
|
58
|
+
end
|
59
|
+
end
|
data/lib/utils.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'config'
|
2
|
-
|
3
1
|
module Utils
|
4
2
|
def circle_rotate(center_x, center_y, r, rotation)
|
5
3
|
x_rotated = center_x + r * Math.cos(rotation)
|
@@ -7,17 +5,11 @@ module Utils
|
|
7
5
|
return [x_rotated, y_rotated]
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
11
|
-
|
12
|
-
return fingers_range / args_num.to_f if args_num == 1
|
13
|
-
return 0
|
14
|
-
end
|
15
|
-
|
16
|
-
def draw_line(canvas, x1, y1, x2, y2)
|
17
|
-
canvas.line x1: x1, y1: y1, x2: x2, y2: y2, style: Config::STYLE
|
8
|
+
def draw_line(x1, y1, x2, y2)
|
9
|
+
{ line: { x1: x1, y1: y1, x2: x2, y2: y2 } }
|
18
10
|
end
|
19
11
|
|
20
|
-
def draw_caption(
|
21
|
-
|
12
|
+
def draw_caption(caption, x, y, font_size = 9, orientation = :lr)
|
13
|
+
{ text: { x: x, y: y, caption: caption, font_size: font_size, orientation: orientation } }
|
22
14
|
end
|
23
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dudegl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitry Khramtsov
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-12-
|
12
|
+
date: 2019-12-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: 'Anthropomorphic UML: visualization of code and OOP concepts in a form
|
15
15
|
of human body.'
|
@@ -19,10 +19,17 @@ executables: []
|
|
19
19
|
extensions: []
|
20
20
|
extra_rdoc_files: []
|
21
21
|
files:
|
22
|
-
- lib/
|
22
|
+
- lib/compose/arms.rb
|
23
|
+
- lib/compose/body.rb
|
24
|
+
- lib/compose/dudes_location.rb
|
25
|
+
- lib/compose/legs.rb
|
26
|
+
- lib/compose/limbs.rb
|
23
27
|
- lib/config.rb
|
24
|
-
- lib/dude.rb
|
25
28
|
- lib/dudegl.rb
|
29
|
+
- lib/limbs/arm.rb
|
30
|
+
- lib/limbs/leg.rb
|
31
|
+
- lib/limbs/limb.rb
|
32
|
+
- lib/render.rb
|
26
33
|
- lib/utils.rb
|
27
34
|
homepage: https://github.com/dmikhr/DudeGL/wiki
|
28
35
|
licenses:
|
data/lib/arm.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require_relative 'config'
|
2
|
-
require_relative 'utils'
|
3
|
-
|
4
|
-
class Arm
|
5
|
-
include Utils
|
6
|
-
|
7
|
-
attr_reader :end_x, :end_y, :body_side
|
8
|
-
|
9
|
-
def initialize(canvas, params, x0, y0, body_side)
|
10
|
-
@canvas = canvas
|
11
|
-
@params = params
|
12
|
-
@x0 = x0
|
13
|
-
@y0 = y0
|
14
|
-
@end_y = y0
|
15
|
-
@body_side = body_side
|
16
|
-
|
17
|
-
draw_arm
|
18
|
-
end
|
19
|
-
|
20
|
-
def draw_arm
|
21
|
-
caption = @params[:name]
|
22
|
-
length = @params[:length]
|
23
|
-
args_num = @params[:args]
|
24
|
-
conditions = @params[:conditions]
|
25
|
-
|
26
|
-
length <= Config::METHOD_LENGTH_OK_MAX ? arm_length = Config::ARM_LENGTH : arm_length = Config::ARM_LENGTH_LONG
|
27
|
-
arm_length = - arm_length if @body_side == :left
|
28
|
-
@end_x = @x0 + arm_length
|
29
|
-
|
30
|
-
if conditions.positive?
|
31
|
-
draw_conditions(conditions, arm_length, @x0, @y0, @body_side)
|
32
|
-
else
|
33
|
-
draw_line(@canvas, @x0, @y0, @x0 + arm_length, @y0)
|
34
|
-
end
|
35
|
-
|
36
|
-
draw_caption(@canvas, caption, 0.8 * (@x0 + arm_length).round, (0.95 * @y0).round)
|
37
|
-
draw_fingers(args_num)
|
38
|
-
end
|
39
|
-
|
40
|
-
def draw_conditions(conditions, arm_length, x0, y0, body_side)
|
41
|
-
lines_num = conditions + 1
|
42
|
-
line_length = ((arm_length.abs - conditions * Config::ELLIPSE_LENGTH) / lines_num).round
|
43
|
-
body_side == :left ? orientation = -1 : orientation = 1
|
44
|
-
|
45
|
-
x0 = x0
|
46
|
-
x1 = x0 + line_length * orientation
|
47
|
-
|
48
|
-
lines_num.times do |i|
|
49
|
-
draw_line(@canvas, x0, y0, x1, y0)
|
50
|
-
|
51
|
-
@canvas.ellipse cx: (x1 + Config::ELLIPSE_LENGTH * orientation / 2).round,
|
52
|
-
cy: y0, rx: (Config::ELLIPSE_LENGTH / 2).round, ry: (Config::ELLIPSE_LENGTH / 4).round,
|
53
|
-
style: Config::STYLE, fill: 'white' if i < lines_num - 1
|
54
|
-
|
55
|
-
x0 = x0 + (line_length + Config::ELLIPSE_LENGTH) * orientation
|
56
|
-
x1 = x0 + line_length * orientation
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def draw_fingers(args_num)
|
61
|
-
fingers_range = Math::PI / 2.0
|
62
|
-
|
63
|
-
if body_side == :left
|
64
|
-
finger_angle_start = Config::FINGER_ANGLE_START
|
65
|
-
finger_angle_end = finger_angle_start + fingers_range
|
66
|
-
finger_angle_step = calc_range(fingers_range, args_num)
|
67
|
-
else
|
68
|
-
finger_angle_start = - Config::FINGER_ANGLE_START + Math::PI
|
69
|
-
finger_angle_end = finger_angle_start - fingers_range
|
70
|
-
finger_angle_step = - calc_range(fingers_range, args_num)
|
71
|
-
end
|
72
|
-
|
73
|
-
args_num.times do |i|
|
74
|
-
finger_end_x, finger_end_y = circle_rotate(end_x, end_y, Config::FINGER_LENGTH,
|
75
|
-
finger_angle_start + finger_angle_step * i)
|
76
|
-
|
77
|
-
draw_line(@canvas, end_x, end_y, finger_end_x, finger_end_y)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
data/lib/dude.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require_relative 'utils'
|
2
|
-
require_relative 'config'
|
3
|
-
|
4
|
-
class Dude
|
5
|
-
include Utils
|
6
|
-
|
7
|
-
attr_reader :body_right_x, :body_right_top_y, :body_left_x, :body_left_top_y
|
8
|
-
|
9
|
-
def initialize(canvas, width = 400, height = 400)
|
10
|
-
@width = width
|
11
|
-
@height = height
|
12
|
-
@canvas = canvas
|
13
|
-
draw_dude
|
14
|
-
end
|
15
|
-
|
16
|
-
def draw_dude
|
17
|
-
# head center
|
18
|
-
head_center_x = (0.5 * @width).round
|
19
|
-
head_center_y = (0.3 * @height).round
|
20
|
-
|
21
|
-
@body_right_x, @body_right_top_y = circle_rotate(head_center_x, head_center_y,
|
22
|
-
Config::HEAD_RADIUS,
|
23
|
-
Config::BODY_CENTER + Config::SLIM_FACTOR)
|
24
|
-
@body_left_x, @body_left_top_y = circle_rotate(head_center_x, head_center_y,
|
25
|
-
Config::HEAD_RADIUS,
|
26
|
-
Config::BODY_CENTER - Config::SLIM_FACTOR)
|
27
|
-
# head
|
28
|
-
@canvas.circle cx: head_center_x, cy: head_center_y, r: Config::HEAD_RADIUS,
|
29
|
-
fill: 'white', style: Config::STYLE
|
30
|
-
# right part of a body
|
31
|
-
draw_line(@canvas, @body_right_x, @body_right_top_y,
|
32
|
-
@body_right_x, @body_right_top_y + Config::BODY_LENGTH)
|
33
|
-
# left part of a body
|
34
|
-
draw_line(@canvas, @body_left_x, @body_left_top_y,
|
35
|
-
@body_left_x, @body_left_top_y + Config::BODY_LENGTH)
|
36
|
-
# bottom
|
37
|
-
draw_line(@canvas, @body_right_x, @body_right_top_y + Config::BODY_LENGTH,
|
38
|
-
@body_left_x, @body_left_top_y + Config::BODY_LENGTH)
|
39
|
-
end
|
40
|
-
end
|