dudegl 0.1.0
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 +7 -0
- data/lib/config.rb +4 -0
- data/lib/dudegl.rb +154 -0
- data/lib/utils.rb +23 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c04d0cd5702b11e8381dbc79bbdc7ff3de2342cf90949588938c3a2d0596f183
|
4
|
+
data.tar.gz: 78bf8825a9325dba3058cae821deed12182b1412413beb966eaa2c510f32b4f8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b0d2a81573a6e29ed3b0b1d39b1f92b1c2a1a8cbb87662822f9416e51833f8fa39950586d92b53e36371241ecfd6206b02c3a9bf293870b659eb19cf4a9a7134
|
7
|
+
data.tar.gz: 48edbacecbc05fbc3d5aeea47a0c0458b4a4e18bc26ec5c427d8a145db1ce019ca2956988a35f28a4d8bd0696f7909de04d4057dcd44cbea4d50f410da17680a
|
data/lib/config.rb
ADDED
data/lib/dudegl.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'victor'
|
2
|
+
require 'byebug'
|
3
|
+
require_relative 'config'
|
4
|
+
require_relative 'utils'
|
5
|
+
|
6
|
+
class DudeGl
|
7
|
+
include Utils
|
8
|
+
|
9
|
+
BODY_LENGTH = 140
|
10
|
+
BODY_CENTER = Math::PI * (3 / 2.0)
|
11
|
+
# defines how slim is a body
|
12
|
+
SLIM_FACTOR = Math::PI * (2 / 8.0)
|
13
|
+
HEAD_RADIUS = 40
|
14
|
+
|
15
|
+
METHOD_LENGTH_OK_MAX = 5
|
16
|
+
ARM_LENGTH = 40
|
17
|
+
ARM_LENGTH_LONG = 70
|
18
|
+
ELLIPSE_LENGTH = 10
|
19
|
+
|
20
|
+
FINGER_LENGTH = 10
|
21
|
+
FINGER_ANGLE_START = Math::PI * (3 / 4.0)
|
22
|
+
|
23
|
+
def initialize(object, width = 400, height = 400)
|
24
|
+
@object = object
|
25
|
+
@width = width
|
26
|
+
@height = height
|
27
|
+
create_canvas
|
28
|
+
draw_dude
|
29
|
+
draw_arms
|
30
|
+
end
|
31
|
+
|
32
|
+
def save_to_svg(file_name)
|
33
|
+
@canvas.save "#{Config::IMAGE_DIR}/#{file_name}"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def create_canvas
|
39
|
+
@canvas = Victor::SVG.new width: @width, height: @height, style: { background: 'white' }
|
40
|
+
end
|
41
|
+
|
42
|
+
def draw_dude
|
43
|
+
# head center
|
44
|
+
head_center_x = (0.5 * @width).round
|
45
|
+
head_center_y = (0.3 * @height).round
|
46
|
+
|
47
|
+
@body_right_x, @body_right_top_y = circle_rotate(head_center_x, head_center_y,
|
48
|
+
HEAD_RADIUS, BODY_CENTER + SLIM_FACTOR)
|
49
|
+
@body_left_x, @body_left_top_y = circle_rotate(head_center_x, head_center_y,
|
50
|
+
HEAD_RADIUS, BODY_CENTER - SLIM_FACTOR)
|
51
|
+
# head
|
52
|
+
@canvas.circle cx: head_center_x, cy: head_center_y, r: HEAD_RADIUS,
|
53
|
+
fill: 'white', style: Config::STYLE
|
54
|
+
# right part of a body
|
55
|
+
draw_line(@canvas, @body_right_x, @body_right_top_y,
|
56
|
+
@body_right_x, @body_right_top_y + BODY_LENGTH)
|
57
|
+
# left part of a body
|
58
|
+
draw_line(@canvas, @body_left_x, @body_left_top_y,
|
59
|
+
@body_left_x, @body_left_top_y + BODY_LENGTH)
|
60
|
+
# bottom
|
61
|
+
draw_line(@canvas, @body_right_x, @body_right_top_y + BODY_LENGTH,
|
62
|
+
@body_left_x, @body_left_top_y + BODY_LENGTH)
|
63
|
+
end
|
64
|
+
|
65
|
+
def draw_arm(side_arms, x0, y0, body_side)
|
66
|
+
method_name = side_arms[:name]
|
67
|
+
length = side_arms[:length]
|
68
|
+
args_num = side_arms[:args]
|
69
|
+
conditions = side_arms[:conditions]
|
70
|
+
|
71
|
+
length <= METHOD_LENGTH_OK_MAX ? arm_length = ARM_LENGTH : arm_length = ARM_LENGTH_LONG
|
72
|
+
arm_length = - arm_length if body_side == :left
|
73
|
+
|
74
|
+
if conditions.positive?
|
75
|
+
draw_conditions(conditions, arm_length, x0, y0, body_side)
|
76
|
+
else
|
77
|
+
draw_line(@canvas, x0, y0, x0 + arm_length, y0)
|
78
|
+
end
|
79
|
+
|
80
|
+
draw_caption(@canvas, method_name, 0.8 * (x0 + arm_length).round, (0.95 * y0).round)
|
81
|
+
draw_fingers(args_num, x0 + arm_length, y0, body_side)
|
82
|
+
end
|
83
|
+
|
84
|
+
def draw_arms
|
85
|
+
arms_draw_parameters
|
86
|
+
divide_arms
|
87
|
+
|
88
|
+
@left_arms_num.times do |i|
|
89
|
+
hy = (1.05 * @body_left_top_y + i * @arms_step).round
|
90
|
+
draw_arm(@left_arms[i], @body_left_x, hy, :left)
|
91
|
+
end
|
92
|
+
|
93
|
+
@right_arms_num.times do |i|
|
94
|
+
hy = (1.05 * @body_right_top_y + i * @arms_step).round
|
95
|
+
draw_arm(@right_arms[i], @body_right_x, hy, :right)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def draw_conditions(conditions, arm_length, x0, y0, body_side)
|
100
|
+
lines_num = conditions + 1
|
101
|
+
line_length = ((arm_length.abs - conditions * ELLIPSE_LENGTH) / lines_num).round
|
102
|
+
body_side == :left ? orientation = -1 : orientation = 1
|
103
|
+
|
104
|
+
x0 = x0
|
105
|
+
x1 = x0 + line_length * orientation
|
106
|
+
|
107
|
+
lines_num.times do |i|
|
108
|
+
draw_line(@canvas, x0, y0, x1, y0)
|
109
|
+
|
110
|
+
@canvas.ellipse cx: (x1 + ELLIPSE_LENGTH * orientation / 2).round,
|
111
|
+
cy: y0, rx: (ELLIPSE_LENGTH / 2).round, ry: (ELLIPSE_LENGTH / 4).round,
|
112
|
+
style: Config::STYLE, fill: 'white' if i < lines_num - 1
|
113
|
+
|
114
|
+
x0 = x0 + (line_length + ELLIPSE_LENGTH) * orientation
|
115
|
+
x1 = x0 + line_length * orientation
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def arms_draw_parameters
|
120
|
+
@methods_num = @object[:methods].size
|
121
|
+
remainder = @methods_num % 2
|
122
|
+
|
123
|
+
@left_arms_num = (@methods_num - remainder) / 2 + remainder
|
124
|
+
@right_arms_num = @methods_num - @left_arms_num
|
125
|
+
|
126
|
+
# BODY_LENGTH * 0.9 - to avoid drawing hands on a body edges
|
127
|
+
@arms_step = ((BODY_LENGTH * 0.9) / @left_arms_num).round
|
128
|
+
end
|
129
|
+
|
130
|
+
def divide_arms
|
131
|
+
@left_arms = @object[:methods][0, @left_arms_num]
|
132
|
+
@right_arms = @object[:methods][@left_arms_num, @methods_num]
|
133
|
+
end
|
134
|
+
|
135
|
+
def draw_fingers(args_num, arm_end_x, arm_end_y, body_side)
|
136
|
+
fingers_range = Math::PI / 2.0
|
137
|
+
|
138
|
+
if body_side == :left
|
139
|
+
finger_angle_start = FINGER_ANGLE_START
|
140
|
+
finger_angle_end = finger_angle_start + fingers_range
|
141
|
+
finger_angle_step = calc_range(fingers_range, args_num)
|
142
|
+
else
|
143
|
+
finger_angle_start = - FINGER_ANGLE_START + Math::PI
|
144
|
+
finger_angle_end = finger_angle_start - fingers_range
|
145
|
+
finger_angle_step = - calc_range(fingers_range, args_num)
|
146
|
+
end
|
147
|
+
|
148
|
+
args_num.times do |i|
|
149
|
+
finger_end_x, finger_end_y = circle_rotate(arm_end_x, arm_end_y, FINGER_LENGTH,
|
150
|
+
finger_angle_start + finger_angle_step * i)
|
151
|
+
draw_line(@canvas, arm_end_x, arm_end_y, finger_end_x, finger_end_y)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/lib/utils.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'config'
|
2
|
+
|
3
|
+
module Utils
|
4
|
+
def circle_rotate(center_x, center_y, r, rotation)
|
5
|
+
x_rotated = center_x + r * Math.cos(rotation)
|
6
|
+
y_rotated = center_y - r * Math.sin(rotation)
|
7
|
+
return [x_rotated, y_rotated]
|
8
|
+
end
|
9
|
+
|
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
|
18
|
+
end
|
19
|
+
|
20
|
+
def draw_caption(canvas, caption, x, y)
|
21
|
+
canvas.text caption, x: x, y: y, font_family: 'arial', font_size: 9, fill: 'black'
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dudegl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dmitry Khramtsov
|
8
|
+
- Ivan Nemytchenko
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2019-12-11 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: 'Anthropomorphic UML: visualization of code and OOP concepts in a form
|
15
|
+
of human body.'
|
16
|
+
email:
|
17
|
+
- dp@khramtsov.net
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/config.rb
|
23
|
+
- lib/dudegl.rb
|
24
|
+
- lib/utils.rb
|
25
|
+
homepage: https://github.com/dmikhr/DudeGL/wiki
|
26
|
+
licenses:
|
27
|
+
- MIT
|
28
|
+
metadata: {}
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubygems_version: 3.0.3
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Visualization of code and OOP concepts in a form of human body
|
48
|
+
test_files: []
|