| import 'HSVTree.ecore#/'; |
| import 'HSLTree.ecore#/'; |
| import 'HSV2HSL.ecore#/'; |
| |
| transformation hsv2hsl |
| { |
| hsv imports HSVTree; |
| hsl imports HSLTree; |
| imports HSV2HSL; |
| } |
| |
| map HSV2HSLRoot in hsv2hsl |
| { |
| check hsv(hsvRoot : HSVTree::HSVNode[1] |
| | |
| hsvRoot.parent = null;) {} |
| check enforce hsl() { |
| realize hslRoot : HSLTree::HSLNode[1] |
| | |
| hslRoot.parent := null; |
| } |
| |
| where() { |
| realize middleRoot : HSV2HSL::HSVNode2HSLNode[1] |
| | |
| middleRoot.parent := null; |
| middleRoot.hsv := hsvRoot; |
| middleRoot.hsl := hslRoot; |
| } |
| |
| map |
| { |
| |
| where() { |
| middleRoot.name := hsvRoot.name; |
| middleRoot.name := hslRoot.name; |
| hsvRoot.name := middleRoot.name; |
| hslRoot.name := middleRoot.name; |
| hsvRoot.hsv := rgb2hsv(middleRoot.rgb); |
| hslRoot.hsl := rgb2hsl(middleRoot.rgb); |
| middleRoot.rgb := hsv2rgb(hsvRoot.hsv); |
| middleRoot.rgb := hsl2rgb(hslRoot.hsl); |
| } |
| } |
| } |
| |
| map HSV2HSLRecursion in hsv2hsl |
| { |
| check enforce hsv(hsvParent : HSVTree::HSVNode[1] |
| |) { |
| realize hsvNode : HSVTree::HSVNode[1] |
| | |
| hsvNode.parent := hsvParent; |
| } |
| |
| check enforce hsl(hslParent : HSLTree::HSLNode[1] |
| |) { |
| realize hslNode : HSLTree::HSLNode[1] |
| | |
| hslNode.parent := hslParent; |
| } |
| |
| where(middleParent : HSV2HSL::HSVNode2HSLNode[1] |
| | |
| middleParent.hsv = hsvParent; |
| middleParent.hsl = hslParent;) { |
| realize middleNode : HSV2HSL::HSVNode2HSLNode[1] |
| | |
| middleNode.parent := middleParent; |
| middleNode.hsv := hsvNode; |
| middleNode.hsl := hslNode; |
| } |
| |
| map |
| { |
| |
| where() { |
| middleNode.name := hsvNode.name; |
| middleNode.name := hslNode.name; |
| hslNode.name := middleNode.name; |
| hsvNode.name := middleNode.name; |
| hsvNode.hsv := rgb2hsv(middleNode.rgb); |
| hslNode.hsl := rgb2hsl(middleNode.rgb); |
| middleNode.rgb := hsv2rgb(hsvNode.hsv); |
| middleNode.rgb := hsl2rgb(hslNode.hsl); |
| } |
| } |
| } |
| |
| query hsv2hsl::hsl2rgb(color : HSLTree::HSL) : HSV2HSL::RGB[1] |
| { |
| HSV2HSL::RGB{value=color} |
| } |
| |
| query hsv2hsl::hsv2rgb(color : HSVTree::HSV[1]) : HSV2HSL::RGB[1] |
| { |
| let hsv : Sequence(String) = color.tokenize(',') in |
| let h : Integer = hsv->at(1).toReal().round() in |
| let s : Real = hsv->at(2).toReal()/100.0 in |
| let v : Real = hsv->at(3).toReal()/100.0 in |
| let c : Real = v * s in |
| let hh1 : Real = h/120 in |
| let hh2 : Real = 2 * (hh1 - hh1.floor()) in |
| let x : Real = c * (1 - (hh2 - 1).abs()) in |
| let m : Real = v -c in |
| let t : Tuple(r:Real,g:Real,b:Real) = |
| if h < 60 then Tuple{r=c,g=x,b=0.0} |
| elseif h < 120 then Tuple{r=x,g=c,b=0.0} |
| elseif h < 180 then Tuple{r=0.0,g=c,b=x} |
| elseif h < 240 then Tuple{r=0.0,g=x,b=c} |
| elseif h < 300 then Tuple{r=x,g=0.0,b=c} |
| else Tuple{r=c,g=0.0,b=x} endif in |
| let r = (255 * (t.r + m)).round() in |
| let g = (255 * (t.g + m)).round() in |
| let b = (255 * (t.b + m)).round() in |
| HSV2HSL::RGB{value=r.toString() + ',' + g.toString() + ',' + b.toString()} |
| } |
| |
| query hsv2hsl::rgb2hsl(color : HSV2HSL::RGB[1]) : HSLTree::HSL[1] |
| { |
| let rgb : Sequence(String) = color.tokenize(',') in |
| let r : Real = rgb->at(1).toReal()/255.0 in |
| let g : Real = rgb->at(2).toReal()/255.0 in |
| let b : Real = rgb->at(3).toReal()/255.0 in |
| let cMax : Real = r.max(g).max(b) in |
| let cMin : Real = r.min(g).min(b) in |
| let l : Real = (cMax + cMin) / 2 in |
| let delta : Real = cMax - cMin in |
| let h : Real = if delta = 0 then 0 |
| elseif cMax = r and g >= b then 60 * ((g - b) / delta + 0) |
| elseif cMax = r and g < b then 60 * ((g - b) / delta + 6) |
| elseif cMax = g then 60 * ((b - r) / delta + 2) |
| else 60 * ((r - g) / delta + 4) endif in |
| let s : Real = if delta = 0 then 0 else delta / (1 - (2 * l - 1).abs()) endif in |
| HSLTree::HSL{value=h.round().toString() + ',' + (100*s).round().toString() + ',' + (100*l).round().toString()} |
| } |
| |
| query hsv2hsl::rgb2hsv(color : HSV2HSL::RGB) : HSVTree::HSV[1] |
| { |
| HSVTree::HSV{value=color} |
| } |
| |
| /* |
| query hsv2hsl::rgb2hsl(rgb:Sequence(Integer)) : Sequence(Real) { |
| let r: Real = rgb->at(1), |
| g: Real = rgb->at(2), |
| b: Real = rgb->at(3), |
| rgbReal = Sequence{r,g,b}, |
| max: Real = rgbReal->iterate(x : Real, y:Real=0 | y.max(x)), |
| min: Real = rgbReal->iterate(x : Real, y:Real=1 | y.min(x)), |
| l: Real = (max+min)/2 |
| in |
| if max = min then |
| Sequence{0, 0, l*100} |
| else |
| let c:Real = max-min, |
| s:Real = if l < 0.5 then |
| c / (max+min) |
| else |
| c / (2-max-min) |
| endif, |
| r1:Real = ((max-r)/6 + c/2)/c, |
| g1:Real = ((max-g)/6 + c/2)/c, |
| b1:Real = ((max-b)/6 + c/2)/c |
| in |
| if max = r then |
| let h:Real = b1 - g1 |
| in |
| Sequence{h*360, s*100, l*100} |
| else |
| if max = g then |
| let h: Real = 1/3 + r1 - b1 |
| in |
| Sequence{h*360, s*100, l*100} |
| else -- max = b |
| let h: Real = 2/3 + g1 - r1 |
| in |
| Sequence{h*360, s*100, l*100} |
| endif |
| endif |
| endif |
| } |
| |
| query hsv2hsl::hsl2rgb(hsl:Sequence(Real)) : Sequence(Integer) { |
| |
| let h: Real = hsl->at(1), |
| s: Real = hsl->at(2)/100, |
| l: Real = hsl->at(3)/100, |
| c: Real = 1 - (2*l-1).abs()*s, |
| h2: Real = (h/60), |
| hmod: Real = h2.floor().mod(2) + (h/60 - h2.floor()), |
| x:Real = c*(1-(hmod-1).abs()), |
| m:Real = l - 0.5*c |
| in |
| if h2 < 1 then |
| Sequence{c+m, x+m, m} |
| else |
| if h2 < 2 then |
| Sequence{x+m, c+m, m} |
| else |
| if h2 < 3 then |
| Sequence{m, c+m, x+m} |
| else |
| if h2 < 4 then |
| Sequence{m, x, c} |
| else |
| if h2 < 5 then |
| Sequence{x+m, m, c+m} |
| else |
| Sequence{c+m, m, x+m} |
| endif |
| endif |
| endif |
| endif |
| endif |
| } |
| |
| query hsv2hsl::rgb2hsv(rgb:Sequence(Integer)) : Sequence(Real) { |
| let r: Real = rgb->at(1), |
| g: Real = rgb->at(2), |
| b: Real = rgb->at(3), |
| rgbReal = Sequence{r,g,b}, |
| max: Real = rgbReal->iterate(x : Real, y:Real=0 | y.max(x)), |
| min: Real = rgbReal->iterate(x : Real, y:Real=1 | y.min(x)), |
| v: Real = max |
| in |
| if max = min then |
| Sequence{0, 0, v*100} |
| else |
| let c:Real = max-min, |
| s:Real = c/max, |
| r1:Real = ((max-r)/6 + c/2)/c, |
| g1:Real = ((max-g)/6 + c/2)/c, |
| b1:Real = ((max-b)/6 + c/2)/c |
| in |
| if max = r then |
| let h:Real = b1 - g1 |
| in |
| Sequence{h*360, s*100, v*100} |
| else |
| if max = g then |
| let h: Real = 1/3 + r1 - b1 |
| in |
| Sequence{h*360, s*100, v*100} |
| else -- max = b |
| let h: Real = 2/3 + g1 - r1 |
| in |
| Sequence{h*360, s*100, v*100} |
| endif |
| endif |
| endif |
| } |
| |
| query hsv2hsl::hsv2rgb(hsv:Sequence(Real)) : Sequence(Integer) { |
| let h: Real = hsv->at(1), |
| s: Real = hsv->at(2)/100, |
| v: Real = hsv->at(3)/100, |
| i:Integer = (h/60).floor(), |
| f:Real = h/60 - i, |
| p:Real = v * (1 - s), |
| q:Real = v * (1 - f * s), |
| t:Real = v * (1 - (1 - f) * s) |
| in |
| if i = 0 then |
| Sequence{v, t, p} |
| else |
| if i = 1 then |
| Sequence{q, v, p} |
| else |
| if i = 2 then |
| Sequence{p, v, t} |
| else |
| if i = 3 then |
| Sequence{p, q, v} |
| else |
| if i = 4 then |
| Sequence{t, p, v} |
| else |
| Sequence{v, p, q} |
| endif |
| endif |
| endif |
| endif |
| endif |
| } |
| |
| */ |