From 2a7d141ddb46bb1ef5dd5d1bb9f82152807ad650 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Thu, 14 Sep 2023 20:23:22 -0700 Subject: [PATCH] add HSV --- HSV.zig | 26 ++++++++++++++++++++++++++ mod.zig | 1 + sRGB.zig | 18 ++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 HSV.zig diff --git a/HSV.zig b/HSV.zig new file mode 100644 index 0000000000000000000000000000000000000000..7db51d0da3c2cf12a5f161c6b1f087071598508c --- /dev/null +++ b/HSV.zig @@ -0,0 +1,26 @@ +//! object representing a single color in the HSV colorspace with h channel value from 0-360 and s,v channel values from 0-1 + +const std = @import("std"); +const Self = @This(); + +h: f32, // hue +s: f32, // saturation +v: f32, // value +a: f32, // alpha + +pub fn initHSVA(h: f32, s: f32, v: f32, a: f32) Self { + std.debug.assert(h >= 0.0 and h <= 1.0); + std.debug.assert(s >= 0.0 and s <= 1.0); + std.debug.assert(v >= 0.0 and v <= 1.0); + std.debug.assert(a >= 0.0 and a <= 1.0); + return Self{ + .h = h, + .s = s, + .v = v, + .a = a, + }; +} + +pub fn eql(x: Self, y: Self) bool { + return x.h == y.h and x.s == y.s and x.v == y.v and x.a == y.a; +} diff --git a/mod.zig b/mod.zig index 621e3dcdf45a9f1b7de0842ba0dac64e832ed6cd..a5fbd2ac934f3a91da9e5ac8c6bfc7b872a62349 100644 --- a/mod.zig +++ b/mod.zig @@ -5,3 +5,4 @@ pub const sRGB = @import("./sRGB.zig"); pub const LinearRgb = @import("./LinearRgb.zig"); pub const CMYK = @import("./CMYK.zig"); pub const HSL = @import("./HSL.zig"); +pub const HSV = @import("./HSV.zig"); diff --git a/sRGB.zig b/sRGB.zig index a93e9cfeab7ce6db934e8aa91b4570756a964ce1..46b42d2de25f30cd08e185cacb0ba09bce765ee2 100644 --- a/sRGB.zig +++ b/sRGB.zig @@ -126,3 +126,21 @@ pub fn to_hsl(x: Self) color.HSL { const a = f.a; return color.HSL.initHSLA(h, s, l, a); } + +pub fn to_hsv(x: Self) color.HSV { + const f = x.to_float(); + const cmax = @max(f.r, f.g, f.b); + const cmin = @min(f.r, f.g, f.b); + const delta = cmax - cmin; + const h = blk: { + if (delta == 0) break :blk 0; + if (cmax == f.r) break :blk ((((f.g - f.b) / delta) % 6) * 60) % 360; + if (cmax == f.g) break :blk ((((f.b - f.r) / delta) + 2) * 60) % 360; + if (cmax == f.b) break :blk ((((f.r - f.g) / delta) + 4) * 60) % 360; + unreachable; + }; + const s = if (cmax == 0) 0 else delta / cmax; + const v = cmax; + const a = f.a; + return color.HSV.initHSVA(h, s, v, a); +} -- 2.54.0