dimension_drawer 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/dimension_drawer.rb +174 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -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: []
|