dimension_drawer 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/dimension_drawer.rb +174 -0
  3. metadata +47 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f2228128484e0dc4311cfae46b8bdae70ec4fce9
4
+ data.tar.gz: 7ffd40dbeb6511f8bc1c27cd420adfa3519f3d2a
5
+ SHA512:
6
+ metadata.gz: 3caae2727c8d886a3ae36f3e77e3b63af8bd36c7ab368bbf98bcf7b2f0b98bbdb1660bbbb572d330c48fc5b1de5af9838e5e4de60ea20d7d3df235f0c8f4e7e6
7
+ data.tar.gz: a11e7cd2fd131ad604f3eefdd1f3e4ceb2ff386a3c5786c27cfb35e71ccd93385508e9e00b507c0c97a92d6e7cc0d8d6b45726924fce6ca71b089332f88d9ec3
@@ -0,0 +1,174 @@
1
+
2
+ class DimensionDrawer
3
+
4
+ def initialize(height, width, depth, view_width, view_height, options = {})
5
+ @height = height
6
+ @width = width
7
+ @depth = depth
8
+ @view_height = view_height
9
+ @view_width = view_width
10
+ @scale = options[:scale]
11
+ @exclude_units = options[:exclude_units]
12
+ end
13
+
14
+ def cabinet_projection(angle = 45)
15
+
16
+ margin = 20
17
+
18
+ # This is an artificial number which approximates perspective.
19
+ depth_scale = 0.5
20
+
21
+ scaled_depth = @depth * depth_scale
22
+
23
+ lines = []
24
+
25
+ total_height = @height + height_given_angle_and_hyp(angle, scaled_depth)
26
+ total_width = @width + width_given_angle_and_hyp(angle, scaled_depth) + 6.7
27
+
28
+ height_scale = (@view_height - (margin * 2)) / total_height
29
+ width_scale = (@view_width - (margin * 2)) / total_width
30
+
31
+ calculated_scale = [height_scale, width_scale].min
32
+
33
+ if @scale.is_a? Float
34
+ scale = @scale
35
+ elsif @scale.is_a? Array
36
+ scale = @scale.sort.reverse.detect {|x| calculated_scale > x } || calculated_scale
37
+ else
38
+ scale = calculated_scale
39
+ end
40
+
41
+ # the front box
42
+ lines << rect(
43
+ margin,
44
+ @view_height - (margin + (scale * @height)),
45
+ scale * @width,
46
+ scale * @height
47
+ )
48
+
49
+ # first diagonal line
50
+ lines << line(
51
+ margin,
52
+ (@view_height - (margin + (scale * @height))),
53
+ margin + width_given_angle_and_hyp(angle, scale * @depth * depth_scale),
54
+ (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth)))
55
+ )
56
+
57
+ # second diagonal line
58
+ lines << line(
59
+ margin + (scale * @width),
60
+ (@view_height - (margin + (scale * @height))),
61
+ margin + (scale * @width) + width_given_angle_and_hyp(angle, scale * scaled_depth),
62
+ (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth)))
63
+ )
64
+
65
+ # third diagonal line
66
+ lines << line(
67
+ margin + (scale * @width),
68
+ (@view_height - margin),
69
+ margin + (scale * @width) + width_given_angle_and_hyp(angle, scale * scaled_depth),
70
+ (@view_height - (margin + height_given_angle_and_hyp(angle, scale * scaled_depth)))
71
+ )
72
+
73
+ # top line
74
+ lines << line(
75
+ margin + width_given_angle_and_hyp(angle, scale * scaled_depth),
76
+ (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth))),
77
+ margin + width_given_angle_and_hyp(angle, scale * scaled_depth) + (scale * @width),
78
+ (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth))),
79
+ )
80
+
81
+ # right line
82
+ lines << line(
83
+ margin + width_given_angle_and_hyp(angle, scale * scaled_depth) + (scale * @width),
84
+ (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth))),
85
+ margin + width_given_angle_and_hyp(angle, scale * scaled_depth) + (scale * @width),
86
+ (@view_height - margin - height_given_angle_and_hyp(angle, scale * scaled_depth))
87
+ )
88
+
89
+ unless @exclude_units
90
+
91
+ # Width text
92
+ lines << text(margin + (scale * @width) / 2, @view_height - margin - 4, measurement_label(@width), :middle)
93
+
94
+ # Hight text
95
+ lines << text(margin + (scale * @width) - 2, @view_height - margin - ((scale * @height) / 2), measurement_label(@height), :end)
96
+
97
+ # Depth text
98
+ lines << text(
99
+ margin + (width_given_angle_and_hyp(angle, scale * scaled_depth) / 2) + 20,
100
+ @view_height - margin -(scale * @height) - (height_given_angle_and_hyp(angle, scale * scaled_depth) / 2),
101
+ measurement_label(@depth), :start)
102
+
103
+ end
104
+
105
+ "<svg viewbox=\"0 0 400 320\" class=\"dimension-view\">" +
106
+ lines.join('') +
107
+ tennis_ball(scale, margin + (scale * @width) + margin, @view_height - margin) +
108
+ "</svg>"
109
+
110
+ end
111
+
112
+ private
113
+
114
+ def measurement_label(cm)
115
+
116
+ if cm < 1
117
+ unit = 'mm'
118
+ value = cm * 10
119
+ elsif cm < 100
120
+ unit = 'cm'
121
+ value = cm
122
+ else
123
+ unit = 'm'
124
+ value = cm / 100
125
+ end
126
+
127
+ value = "%g" % value.round(1)
128
+
129
+ "#{value} #{unit}"
130
+ end
131
+
132
+ def width_given_angle_and_hyp(angle, hyp)
133
+ radians = angle.to_f / 180 * Math::PI
134
+ hyp.to_f * Math.cos(radians)
135
+ end
136
+
137
+ def height_given_angle_and_hyp(angle, hyp)
138
+ radians = angle.to_f / 180 * Math::PI
139
+ hyp.to_f * Math.sin(radians)
140
+ end
141
+
142
+ def longest_length
143
+ [@height, @width, @depth].max
144
+ end
145
+
146
+ def tennis_ball(scale, x, y)
147
+
148
+ tennis_ball_height = (6.7 * scale)
149
+
150
+ transformed_scale = tennis_ball_height / 280
151
+
152
+ "<g fill-rule=\"evenodd\" transform=\"translate(#{x},#{y - tennis_ball_height})\">
153
+ <g class=\"tennis-ball\" transform=\"scale(#{transformed_scale},#{transformed_scale})\">
154
+ <circle class=\"ball\" cx=\"140.5\" cy=\"140.5\" r=\"139.5\"></circle>
155
+ <path class=\"line\" d=\"M35.4973996,48.6564543 C42.5067217,75.8893541 47.1024057,103.045405 48.5071593,129.267474 C49.2050919,142.295548 49.1487206,156.313997 48.4007524,171.179475 C47.3170518,192.717458 44.831768,215.405368 41.2689042,238.548172 C44.0920595,241.405174 47.0377013,244.140872 50.0973089,246.746747 C54.274085,220.981656 57.1814249,195.664391 58.388118,171.681997 C59.152645,156.487423 59.2103921,142.12682 58.4928407,128.732526 C56.9456805,99.8522041 51.6525537,69.9875212 43.5965239,40.1505937 C40.7799535,42.8710386 38.077622,45.7089492 35.4973996,48.6564543 L35.4973996,48.6564543 Z\"></path>
156
+ <path class=\"line\" d=\"M209.929126,19.4775696 C207.210255,20.7350524 204.523231,22.0798819 201.877774,23.5155872 C185.816543,32.2321125 172.62404,43.5997536 163.365582,57.9858795 C152.309799,75.1647521 147.361062,95.9365435 149.519284,120.438716 C153.246233,162.750546 177.6149,202.948254 215.783496,239.999593 C219.369774,243.480895 223.018502,246.874207 226.714223,250.176799 C229.361836,248.092694 231.93214,245.91478 234.420126,243.648068 C230.467945,240.143617 226.570656,236.534305 222.748767,232.824289 C186.140739,197.287837 162.958794,159.047704 159.480716,119.561284 C157.514766,97.2419721 161.935618,78.6859198 171.774644,63.3976879 C180.045966,50.5454103 191.971382,40.2695847 206.647666,32.3046788 C211.02518,29.9289759 215.539302,27.8153877 220.133919,25.9481492 C216.833521,23.6494818 213.429097,21.4897954 209.929126,19.4775696 L209.929126,19.4775696 Z\"></path>
157
+ </g></g>"
158
+ end
159
+
160
+
161
+ def line(x1, y1, x2, y2)
162
+ "<line x1=\"#{x1}\" y1=\"#{y1}\" x2=\"#{x2}\" y2=\"#{y2}\" class=\"edge\"></line>"
163
+ end
164
+
165
+
166
+ def rect(x, y, width, height)
167
+ "<rect x=\"#{x}\" y=\"#{y}\" width=\"#{width}\" height=\"#{height}\" class=\"edge\"></rect>"
168
+ end
169
+
170
+ def text(x, y, text_content, text_anchor)
171
+ "<text x=\"#{x}\" y=\"#{y}\" text-anchor=\"#{text_anchor}\">#{text_content}</text>"
172
+ end
173
+
174
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dimension_drawer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Frankie Roberto
8
+ - George Oates
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-10-30 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Given a set of three dimensions (height, width, depth), this class produces
15
+ an SVG drawing representing the object’s volume as a wireframe-style box, with an
16
+ optional tennis ball for scale.
17
+ email: frankie@frankieroberto.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/dimension_drawer.rb
23
+ homepage: https://github.com/goodformandspectacle/dimension-drawer
24
+ licenses:
25
+ - tbc
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.4.5
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Renders an 3D-ish drawing of an object in SVG.
47
+ test_files: []