-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Need for HueType #45
Comments
The hue types are mainly there for semantic purposes and the library itself would do just fine without them. I created them to
Angles will probably never be 100% intuitive when everything is based on linear types, and removing the hue types will make some thing easier and other things harder. Regarding your points:
|
It's going to be one of those subtle bugs, usually won't cause an error during arithmatic, but comparing or assuming the value is > 180 will be painful to debug. When you input Hsl::new(240,0,0), you tend to assume the value is still the same, even though it is mentioned in the docs.
|
The thing is that every value (except +-inf and NaN) is a valid hue, since it's a point on a circle, so you can never really trust them to be within a certain range. Possibly within -360 - +360, but who knows what they can add up to? Removing the hue types will never help with that. It will, at best, move the normalization responsibility from the library to the user. Do you think it would be helpful if there was some sort of |
RgbHueAdvantages:
Inconsistencies:
Downsides:
FloatAdvantages:
Disadvantages:
function like normalize, to_radians, from radians can be standalone functions that work on floats. |
Here is a example comparing float vs RgbHue benchmark for 1920x1080 pixels https://gist.github.com/sidred/a13b034b39373c6c10ad
It feels a bit clumky to use the RgbHue type. A few things:
|
Looks like the normalization function isn't inlined. I ran it through callgrind after an attempt to make things more even, and Here is a version where both hues are normalized using non-inlined functions: https://gist.github.com/Ogeon/78f00346489acf95c3d5 It went from
to
on my machine. Maybe we should stick
As for the clunkiness:
|
Just to clarify my view here: It's not that I'm not willing to "kill my darling", but I would rather try to improve it if possible. I think it fills a function, but it's not as good as it can be. |
I understand that. I am thinking out loud here too. I am wondering whether it makes it any easier from a usage point of view and whether its worth the added complexity. |
I can definitely see a use for partial ord when you only want to change something only on a particular set of hues like reds or blues. I was mistaken on the add and subtract. When i convert to float it will be normalized, so any comparison should be ok. |
Seems like we are on the same plane, then. We could make an attempt to improve it and see how it plays out. There are already a few here:
We could also rename I can also see the use for partial ord, but I'm not sure how it should be defined to make sense. An alternative would be some kind of range check to see if it falls within |
I just moved the normalize and clamp from benchmark to the palette crate and I still see the same results
I my case inling also doesn't seem to help. |
I added |
For some reason I am unable to duplicate your results even with all inlines. In any case there will be a slight performance impact on every access of the hue value. I only see 2 use of atan(), one in lab.rs and one in rgb.rs. Is that the only case where rust's internal [-180, 180] comes into play? If thats the case won't it be easier to normalize that value and store everything internally as [0,360]. Then we can have a single normalize function. |
That's very strange. I wonder why... Have you tried with
Not necessarily. Only if it's normalized every time, given that the inlining issue gets resolved.
It's also used when checking for the smallest difference between two hues. |
It's also used when checking for the smallest difference between two hues. Can you point me to the code? I can't find where this calculation is happening. One advantage of making it [0-360] is that we can use normalize for add and substract and then we can get rid of the normalize for read, we only normalize when the value changes or when it is loaded. I see no code that provides mutable access to the angle. |
It's in Moving the normalization to the add/sub operators will make it both mandatory and completely destructive. The "raw" value will be lost. The current method can at least be made opt-in/out (the idea with |
Wouldn't you still have the same problem even with (-180,180)? difference between 150 and 210 is 60, but becomes 300 ( 150 - (-150)) |
It takes the difference first, and then normalizes, so it's 150 - 210 and then normalize that to (-180,180). |
The proposed changes for improving the usability of the hue types are simple enough to be doable before 0.3.0, although I realize that no concrete decision has been made yet. I would still like to keep the hue types for a bit longer and see if those improvements makes them usable enough. I'm scheduling this issue as a reminder to make a decision before the next patch phase. |
I'm postponing this a bit to get the release out. It's not a show stopper. |
The hue types stays for now. |
I was trying the Hsl type and it seems inconsistent with the rest of the library.
All the other colors take floats for new, but hsl needs
Hsl::new((240.0).into(), 0.0, 0.0)
You input the hue as 240, but you cannot use hsl.hue, you need to use
hsl.hue.to_positive_degrees()
. I have been looking at this code for past few weeks and I made this mistake. This is going to be a very common issue. There is no compile error, but the code will not work as expected.I don't see the need for
hsl + 0.1
. I would rather this be a compile time error, because this is most likely a typo. The values are not on the same scale and does not make sense.What do you think of removing the huetype and storing the hues as 0-360 floats? I understand that HueType avoids some issues in the code, but maybe we can mitigate it by using more test cases?
The text was updated successfully, but these errors were encountered: