[Intro]
HSP color model is a made-up color model created in 2006. It uses the same values as HSV for Hue and Saturation but, for calculating the P (perceived brightness), it uses Weighted Euclidean norm of the [R, G, B] vector. More info: https://alienryderflex.com/hsp.html
As you can see, at the bottom of the website, there are formulas for calculating between RGB and HSP that I've taken and re-formatted for Python.
[Issues]
In some places, I found that for calculating the Perceived brightness, you need to first linearize the RGB channels (assuming it's sRGB) but if you do so, then the formulas no longer work. For that reason, I'm not doing that and applying the formulas directly on the input RGB color. Also, I found in a js library someone made it so the perceived brightness is in range 0-255. I don't know where they got that idea, but it should be in range 0-100 (percentage).
[Where it all goes wrong]
I don't have any issues with calculating from RGB to HSP. The problem is when calculating RGB from HSP. I won't bother you with the full code since you can take it from the link above but I'm giving you a snippet of the part that doesn't work correctly (or I have a mistake that I can't find).
P.S: After further investigation, it turns out that more than just this snippet gives false results!
elif H < 4 / 6: # B > G > R
H = 6 * (-H + 4 / 6)
B = (P ** 2 / (Pb + Pg * H ** 2)) ** 0.5
G = B * H
R = 0
This is the part where Saturation is 100%. The problem is that when you pass it these values HSP(253, 100, 50), or any similar ones, the resulting blue is beyond the acceptable range (in this case 356). I tried clamping the values to 255 but then when doing the RGB to HSV conversion, the values don't match so the problem isn't there.
Any ideas?
So, I found a mistake in my code which brought down the out-of-range values from 300+ to a maximum of 261 which is acceptable to be clamped at 255 (for 8-bit colors) without needing to do anything to the other values. No values need to be clamped on the black side.
Here's my simplified version of the calculation with comments:
This works pretty well and the conversions are really accurate. Note that in order to get perfect conversions, you'll need to use an exact floating-point number for the calculations. Otherwise, you'll get a number of overlapping values due to limitations of the system. Ex. RGB = 256 * 256 * 256 = 16 777 216 colors, whereas HSP = 360 * 100 * 100 = 3 600 000 unique colors.