Skip to content

Instantly share code, notes, and snippets.

@Deradon
Created November 7, 2012 20:24
Show Gist options
  • Save Deradon/4034172 to your computer and use it in GitHub Desktop.
Save Deradon/4034172 to your computer and use it in GitHub Desktop.
wtf.rb
def rgb_to_hsv(r, g, b)
if r == b && r == g
h = s = 0
v = (0.299 * r + 0.587 * g + 0.114 * b) / 255
else
max = [r, g, b].max.to_f
min = [r, g, b].min.to_f
v = max
s = min
if max == r
if min == b
h = g
fi = Proc.new { |a| -1 == a ? 0 : 120 - 2 * (120 * Math.atan(a/0.5)/Math::PI) }
else
h = b
fi = Proc.new { |a| -1 == a ? 0 : 315 + 2 * (45 * Math.atan(a/1.33)/Math::PI) }
end
elsif max == g
if min == r
h = b
fi = Proc.new { |a| -1 == a ? 180 : 210 - 2 * (30 * Math.atan(a/0.75)/Math::PI) }
else
h = r
fi = Proc.new { |a| -1 == a ? 180 : 120 + 2 * (60 * Math.atan(a/0.5)/Math::PI) }
end
else
if min == r
h = g
fi = Proc.new { |a| -1 == a ? 255 : 210 + 2 * (45 * Math.atan(a/1.33)/Math::PI) }
else
h = r
fi = Proc.new { |a| -1 == a ? 255 : 315 - 2 * (60 * Math.atan(a/1.33)/Math::PI) }
end
end
if h == min
temp = -1
else
temp = (max-h)/(h-min)
end
h = fi.call(temp)
s = (v-s)/v
v /= 255
end
return [h, s, v]
end
def hsv_to_rgb(h, s, v)
max = v * 255
min = max - s * max
fi = case h
when (0.0..120.0)
Proc.new { |a| 0 == a ? -1 : 0.5 * Math.tan((120 - a)/120 * Math::PI / 2) }
when (120.0..180.0)
Proc.new { |a| 180 == a ? -1 : 0.5 * Math.tan((a - 120)/60 * Math::PI / 2) }
when (180.0..210.0)
Proc.new { |a| 180 == a ? -1 : 0.75 * Math.tan((210 - a)/30 * Math::PI / 2) }
when (210.0..255.0)
Proc.new { |a| 255 == a ? -1 : 1.33 * Math.tan((a - 210)/45 * Math::PI / 2) }
when (255.0..315.0)
Proc.new { |a| 255 == a ? -1 : 1.33 * Math.tan((315 - a)/60 * Math::PI / 2) }
when (315.0..360.0)
Proc.new { |a| 0 == a ? -1 : 1.33 * Math.tan((a - 315)/45 * Math::PI / 2) }
else
raise ArgumentError
end
tmp = fi.call(h)
tmp = (tmp == -1) ? min : (max + tmp*min) / (tmp + 1)
case h
when (0.0..120.0)
return [max, tmp, min]
when (120.0..180.0)
return [tmp, max, min]
when (180.0..210.0)
return [min, max, tmp]
when (210.0..255.0)
return [min, tmp, max]
when (255.0..315.0)
return [tmp, min, max]
when (315.0..360.0)
return [max, min, tmp]
else
raise ArgumentError
end
end
p rgb_to_hsv(0x2B, 0x00, 0xFF)
p hsv_to_rgb(225, 1.0, 1.0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment