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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13f1304b0ae95eb9b152695f413cff69449df95ca35193ecedfe20e34cec3370
4
- data.tar.gz: bd6973c943d8f154b7ead9a3ae8534236fc96e063ae991e749a016f9208f1369
3
+ metadata.gz: 629bfb1702e517a1bf3f5f52fbf5b3c8eb7e82919cd122aadee7ffa494f35979
4
+ data.tar.gz: fa4395ff7d805a91016f9a384cb2928d7c777e84600e3ff473ff562c02eda072
5
5
  SHA512:
6
- metadata.gz: 3a50aef2628c1cf09311a07b2d7f46281f7a249b9e444c3e8d36ef5bcb96f2f9e1bd63e0fe03db4958802d1b35625a4eaa94c9a2476f61db5e4ef471e0350e61
7
- data.tar.gz: f35a6d614803681b283afdfedeed808108ad8f7a263c5999eb0c0814b45716f5fa216d4b546ff323f63a55a1278465cc0cba5dd7eb609ab887bf28ebb77d2642
6
+ metadata.gz: a4531659105ee4b4e53cb098ddae20c75eb51bfc5175ace477dc2c705c8f435d2102c91347d789b45534f8dea6d12433130f929f51849094eb387a8b2196d76a
7
+ data.tar.gz: f2a4f167a1b012c647056ab937029eb9887c34184be036ce7d382f5235999b799ff97fc34f71602808420a4bc0620ca0fa9b174ff14e596610d8941a9938fcd3
@@ -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
@@ -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
@@ -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
- METHOD_LENGTH_OK_MAX = 5
12
- ARM_LENGTH = 40
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 'victor'
2
- require_relative 'dude'
3
- require_relative 'arm'
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 create_canvas(width = 400, height = 400)
7
- @canvas = Victor::SVG.new width: width, height: height, style: { background: 'white' }
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 create_dude
11
- Dude.new(@canvas)
20
+ def save(file_name)
21
+ File.open("images/#{file_name}.svg", 'w') { |file| file.write(@svg.contents) }
12
22
  end
13
23
 
14
- def add_arm(params, x0, y0, body_side)
15
- Arm.new(@canvas, params, x0, y0, body_side)
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 save_to_svg(file_name)
19
- @canvas.save "#{Config::IMAGE_DIR}/#{file_name}"
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 calc_range(fingers_range, args_num)
11
- return fingers_range / (args_num - 1).to_f if args_num > 1
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(canvas, caption, x, y)
21
- canvas.text caption, x: x, y: y, font_family: 'arial', font_size: 9, fill: 'black'
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.1
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-11 00:00:00.000000000 Z
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/arm.rb
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