-
Notifications
You must be signed in to change notification settings - Fork 0
/
2018-scale.rb
78 lines (57 loc) · 2.06 KB
/
2018-scale.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# Scale
# Linear scaling function from a domain (x1, x2) to a range (y1, y2)
# see https://github.com/d3/d3-scale
def scale(x1, x2, y1, y2, v, explain=false)
domain_magnitude = x2 - x1
range_magnitude = y2 - y1
scale_factor = range_magnitude / domain_magnitude
diff = v - x1
result = diff * scale_factor + y1
explanation = <<-EXPLANATION
First, calculate the scale factor.
The scale factor is the difference between the magnitude of ranges.
The magnitude of a range is the difference between the max value and min value.
So, let's calculate the magnitude of the domain:
domain_magnitude = x2 - x1 = #{x2} - #{x1} = #{domain_magnitude}
Now the magnitude of the range:
range_magnitude = y2 - y1 = #{y2} - #{y1} = #{range_magnitude}
Then the scale factor:
scale_factor = range_magnitude / domain_magnitude = #{range_magnitude} / #{domain_magnitude} = #{scale_factor}
Then calculate the difference of the input and the min value of domain.
Or answer: How far away is the input from the domain min value?
diff = v - x1 = #{v} - #{x1} = #{diff}
Then multiply diff by the scale factor then add that to the range min val:
diff * scale_factor + y1 = #{diff} * #{scale_factor} + #{y1} = #{diff * scale_factor + y1}
And the result is:
#{result}
EXPLANATION
puts explanation if explain
result
end
# Test
def test(output, target)
pass = output == target
if pass
puts '✅'
else
puts "❌"
puts "target: #{target}"
puts "output: #{output}"
end
end
test scale(0, 10, 0, 100, 1), 10
test scale(0, 10, 0, 100, 9.5), 95
test scale(0, 10, -5, 5, 0), -5
test scale(0, 10, -5, 5, 5), 0
test scale(0, 10, -5, 5, 10), 5
test scale(-10, 10, 20, 60, -10), 20
test scale(-10, 10, 20, 60, 0), 40
test scale(-10, 10, 20, 60, 10), 60
test scale(-10, 10, 20, 60, -10), 20
test scale(-10, 10, 20, 60, 0), 40
test scale(-10, 10, 20, 60, 10), 60
test scale(-10, 10, 10, -10, -10), 10
test scale(-10, 10, 10, -10, 0), 0
test scale(-10, 10, 10, -10, 10), -10
test scale(-10, 10, 10, -10, 10), -10
test scale(-10, 10, 10, 10, 10, true), 10