class DimensionDrawer
Public Class Methods
new(height, width, depth, view_width, view_height, options = {})
click to toggle source
# File lib/dimension_drawer.rb, line 4 def initialize(height, width, depth, view_width, view_height, options = {}) @height = height @width = width @depth = depth @view_height = view_height @view_width = view_width @scale = options[:scale] @exclude_units = options[:exclude_units] end
Public Instance Methods
cabinet_projection(angle = 45)
click to toggle source
# File lib/dimension_drawer.rb, line 14 def cabinet_projection(angle = 45) margin = 20 # This is an artificial number which approximates perspective. depth_scale = 0.5 scaled_depth = @depth * depth_scale lines = [] total_height = @height + height_given_angle_and_hyp(angle, scaled_depth) total_width = @width + width_given_angle_and_hyp(angle, scaled_depth) + 6.7 height_scale = (@view_height - (margin * 2)) / total_height width_scale = (@view_width - (margin * 2)) / total_width calculated_scale = [height_scale, width_scale].min if @scale.is_a? Float scale = @scale elsif @scale.is_a? Array scale = @scale.sort.reverse.detect {|x| calculated_scale > x } || calculated_scale else scale = calculated_scale end # the front box lines << rect( margin, @view_height - (margin + (scale * @height)), scale * @width, scale * @height ) # first diagonal line lines << line( margin, (@view_height - (margin + (scale * @height))), margin + width_given_angle_and_hyp(angle, scale * @depth * depth_scale), (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth))) ) # second diagonal line lines << line( margin + (scale * @width), (@view_height - (margin + (scale * @height))), margin + (scale * @width) + width_given_angle_and_hyp(angle, scale * scaled_depth), (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth))) ) # third diagonal line lines << line( margin + (scale * @width), (@view_height - margin), margin + (scale * @width) + width_given_angle_and_hyp(angle, scale * scaled_depth), (@view_height - (margin + height_given_angle_and_hyp(angle, scale * scaled_depth))) ) # top line lines << line( margin + width_given_angle_and_hyp(angle, scale * scaled_depth), (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth))), margin + width_given_angle_and_hyp(angle, scale * scaled_depth) + (scale * @width), (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth))), ) # right line lines << line( margin + width_given_angle_and_hyp(angle, scale * scaled_depth) + (scale * @width), (@view_height - (margin + (scale * @height) + height_given_angle_and_hyp(angle, scale * scaled_depth))), margin + width_given_angle_and_hyp(angle, scale * scaled_depth) + (scale * @width), (@view_height - margin - height_given_angle_and_hyp(angle, scale * scaled_depth)) ) unless @exclude_units # Width text lines << text(margin + (scale * @width) / 2, @view_height - margin - 4, measurement_label(@width), :middle) # Hight text lines << text(margin + (scale * @width) - 2, @view_height - margin - ((scale * @height) / 2), measurement_label(@height), :end) # Depth text lines << text( margin + (width_given_angle_and_hyp(angle, scale * scaled_depth) / 2) + 20, @view_height - margin -(scale * @height) - (height_given_angle_and_hyp(angle, scale * scaled_depth) / 2), measurement_label(@depth), :start) end "<svg viewbox=\"0 0 400 320\" class=\"dimension-view\">" + lines.join('') + tennis_ball(scale, margin + (scale * @width) + margin, @view_height - margin) + "</svg>" end
Private Instance Methods
height_given_angle_and_hyp(angle, hyp)
click to toggle source
# File lib/dimension_drawer.rb, line 137 def height_given_angle_and_hyp(angle, hyp) radians = angle.to_f / 180 * Math::PI hyp.to_f * Math.sin(radians) end
line(x1, y1, x2, y2)
click to toggle source
# File lib/dimension_drawer.rb, line 161 def line(x1, y1, x2, y2) "<line x1=\"#{x1}\" y1=\"#{y1}\" x2=\"#{x2}\" y2=\"#{y2}\" class=\"edge\"></line>" end
longest_length()
click to toggle source
# File lib/dimension_drawer.rb, line 142 def longest_length [@height, @width, @depth].max end
measurement_label(cm)
click to toggle source
# File lib/dimension_drawer.rb, line 114 def measurement_label(cm) if cm < 1 unit = 'mm' value = cm * 10 elsif cm < 100 unit = 'cm' value = cm else unit = 'm' value = cm / 100 end value = "%g" % value.round(1) "#{value} #{unit}" end
rect(x, y, width, height)
click to toggle source
# File lib/dimension_drawer.rb, line 166 def rect(x, y, width, height) "<rect x=\"#{x}\" y=\"#{y}\" width=\"#{width}\" height=\"#{height}\" class=\"edge\"></rect>" end
tennis_ball(scale, x, y)
click to toggle source
# File lib/dimension_drawer.rb, line 146 def tennis_ball(scale, x, y) tennis_ball_height = (6.7 * scale) transformed_scale = tennis_ball_height / 280 "<g fill-rule=\"evenodd\" transform=\"translate(#{x},#{y - tennis_ball_height})\"> <g class=\"tennis-ball\" transform=\"scale(#{transformed_scale},#{transformed_scale})\"> <circle class=\"ball\" cx=\"140.5\" cy=\"140.5\" r=\"139.5\"></circle> <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> <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> </g></g>" end
text(x, y, text_content, text_anchor)
click to toggle source
# File lib/dimension_drawer.rb, line 170 def text(x, y, text_content, text_anchor) "<text x=\"#{x}\" y=\"#{y}\" text-anchor=\"#{text_anchor}\">#{text_content}</text>" end
width_given_angle_and_hyp(angle, hyp)
click to toggle source
# File lib/dimension_drawer.rb, line 132 def width_given_angle_and_hyp(angle, hyp) radians = angle.to_f / 180 * Math::PI hyp.to_f * Math.cos(radians) end