1+ namespace Wacton . Unicolour . Tests ;
2+
3+ using System ;
4+ using NUnit . Framework ;
5+ using Wacton . Unicolour . Tests . Utils ;
6+
7+ /*
8+ * Conversions that are just translations to/from cylindrical coordinate spaces
9+ * should have input values clamped to the range of the source coordinate space
10+ * otherwise they will be mapped to incorrect values
11+ * e.g. RGB with negative -> HSB should produce the same value as RGB with zero -> HSB
12+ */
13+ public class CoordinateSpaceTests
14+ {
15+ [ Test ]
16+ public void CartesianRgbToCylindricalHsb ( )
17+ {
18+ ColourTriplet upperOutRange = new ( 1.00001 , 100 , double . PositiveInfinity ) ;
19+ ColourTriplet upperInRange = new ( 1 , 1 , 1 ) ;
20+ ColourTriplet lowerOutRange = new ( - 0.00001 , - 100 , double . NegativeInfinity ) ;
21+ ColourTriplet lowerInRange = new ( 0 , 0 , 0 ) ;
22+ AssertRgbToHsb ( upperInRange , upperOutRange ) ;
23+ AssertRgbToHsb ( lowerInRange , lowerOutRange ) ;
24+ }
25+
26+ [ Test ]
27+ public void CylindricalHsbToCartesianRgb ( )
28+ {
29+ ColourTriplet upperOutRange = new ( 360.00001 , 100 , double . PositiveInfinity ) ;
30+ ColourTriplet upperInRange = new ( 0.00001 , 1 , 1 ) ;
31+ ColourTriplet lowerOutRange = new ( - 0.00001 , - 100 , double . NegativeInfinity ) ;
32+ ColourTriplet lowerInRange = new ( 359.99999 , 0 , 0 ) ;
33+ AssertHsbToRgb ( upperInRange , upperOutRange ) ;
34+ AssertHsbToRgb ( lowerInRange , lowerOutRange ) ;
35+ }
36+
37+ [ Test ]
38+ public void CylindricalHsbToCylindricalHsl ( )
39+ {
40+ ColourTriplet upperOutRange = new ( 360.00001 , 100 , double . PositiveInfinity ) ;
41+ ColourTriplet upperInRange = new ( 0.00001 , 1 , 1 ) ;
42+ ColourTriplet lowerOutRange = new ( - 0.00001 , - 100 , double . NegativeInfinity ) ;
43+ ColourTriplet lowerInRange = new ( 359.99999 , 0 , 0 ) ;
44+ AssertHsbToHsl ( upperInRange , upperOutRange ) ;
45+ AssertHsbToHsl ( lowerInRange , lowerOutRange ) ;
46+ }
47+
48+ [ Test ]
49+ public void CylindricalHslToCylindricalHsb ( )
50+ {
51+ ColourTriplet upperOutRange = new ( 360.00001 , 100 , double . PositiveInfinity ) ;
52+ ColourTriplet upperInRange = new ( 0.00001 , 1 , 1 ) ;
53+ ColourTriplet lowerOutRange = new ( - 0.00001 , - 100 , double . NegativeInfinity ) ;
54+ ColourTriplet lowerInRange = new ( 359.99999 , 0 , 0 ) ;
55+ AssertHslToHsb ( upperInRange , upperOutRange ) ;
56+ AssertHslToHsb ( lowerInRange , lowerOutRange ) ;
57+ }
58+
59+ private static void AssertRgbToHsb ( ColourTriplet inRange , ColourTriplet outRange )
60+ {
61+ Rgb GetInput ( ColourTriplet triplet ) => new ( triplet . First , triplet . Second , triplet . Third , Configuration . Default ) ;
62+ var inRangeInput = GetInput ( inRange ) ;
63+ var outRangeInput = GetInput ( outRange ) ;
64+
65+ Hsb GetOutput ( Rgb rgb ) => Conversion . RgbToHsb ( rgb ) ;
66+ var inRangeOutput = GetOutput ( inRangeInput ) ;
67+ var outRangeOutput = GetOutput ( outRangeInput ) ;
68+
69+ AssertTriplets (
70+ AsTriplets ( inRangeInput ) , AsTriplets ( outRangeInput ) ,
71+ AsTriplets ( inRangeOutput ) , AsTriplets ( outRangeOutput ) ) ;
72+ }
73+
74+ private static void AssertHsbToRgb ( ColourTriplet inRange , ColourTriplet outRange )
75+ {
76+ Hsb GetInput ( ColourTriplet triplet ) => new ( triplet . First , triplet . Second , triplet . Third ) ;
77+ var inRangeInput = GetInput ( inRange ) ;
78+ var outRangeInput = GetInput ( outRange ) ;
79+
80+ Rgb GetOutput ( Hsb hsb ) => Conversion . HsbToRgb ( hsb , Configuration . Default ) ;
81+ var inRangeOutput = GetOutput ( inRangeInput ) ;
82+ var outRangeOutput = GetOutput ( outRangeInput ) ;
83+
84+ AssertTriplets (
85+ AsTriplets ( inRangeInput ) , AsTriplets ( outRangeInput ) ,
86+ AsTriplets ( inRangeOutput ) , AsTriplets ( outRangeOutput ) ) ;
87+ }
88+
89+ private static void AssertHsbToHsl ( ColourTriplet inRange , ColourTriplet outRange )
90+ {
91+ Hsb GetInput ( ColourTriplet triplet ) => new ( triplet . First , triplet . Second , triplet . Third ) ;
92+ var inRangeInput = GetInput ( inRange ) ;
93+ var outRangeInput = GetInput ( outRange ) ;
94+
95+ Hsl GetOutput ( Hsb hsb ) => Conversion . HsbToHsl ( hsb ) ;
96+ var inRangeOutput = GetOutput ( inRangeInput ) ;
97+ var outRangeOutput = GetOutput ( outRangeInput ) ;
98+
99+ AssertTriplets (
100+ AsTriplets ( inRangeInput ) , AsTriplets ( outRangeInput ) ,
101+ AsTriplets ( inRangeOutput ) , AsTriplets ( outRangeOutput ) ) ;
102+ }
103+
104+ private static void AssertHslToHsb ( ColourTriplet inRange , ColourTriplet outRange )
105+ {
106+ Hsl GetInput ( ColourTriplet triplet ) => new ( triplet . First , triplet . Second , triplet . Third ) ;
107+ var inRangeInput = GetInput ( inRange ) ;
108+ var outRangeInput = GetInput ( outRange ) ;
109+
110+ Hsb GetOutput ( Hsl hsl ) => Conversion . HslToHsb ( hsl ) ;
111+ var inRangeOutput = GetOutput ( inRangeInput ) ;
112+ var outRangeOutput = GetOutput ( outRangeInput ) ;
113+
114+ AssertTriplets (
115+ AsTriplets ( inRangeInput ) , AsTriplets ( outRangeInput ) ,
116+ AsTriplets ( inRangeOutput ) , AsTriplets ( outRangeOutput ) ) ;
117+ }
118+
119+ private static void AssertTriplets ( Triplets inRangeInput , Triplets outRangeInput , Triplets inRangeOutput , Triplets outRangeOutput )
120+ {
121+ AssertUtils . AssertColourTriplet ( outRangeInput . Constrained , inRangeInput . Unconstrained , 0.00001 ) ;
122+ AssertUtils . AssertColourTriplet ( outRangeOutput . Unconstrained , inRangeOutput . Unconstrained , 0.00001 ) ;
123+ AssertUtils . AssertColourTriplet ( outRangeOutput . Constrained , inRangeOutput . Unconstrained , 0.00001 ) ;
124+ }
125+
126+ private static Triplets AsTriplets ( Rgb rgb ) => new ( rgb . Triplet , rgb . ConstrainedTriplet ) ;
127+ private static Triplets AsTriplets ( Hsb hsb ) => new ( hsb . Triplet , hsb . ConstrainedTriplet ) ;
128+ private static Triplets AsTriplets ( Hsl hsl ) => new ( hsl . Triplet , hsl . ConstrainedTriplet ) ;
129+
130+ private record Triplets ( ColourTriplet Unconstrained , ColourTriplet Constrained ) ;
131+ }
0 commit comments