[orx-color] Add ColorRGBa.convertTo<>() and simplify shiftHue, saturate, mix

This commit is contained in:
Edwin Jakobs
2023-12-08 11:24:53 +01:00
parent 0b27dc735c
commit ee9a5f5463

View File

@@ -3,7 +3,9 @@ package org.openrndr.extra.color.tools
import org.openrndr.color.* import org.openrndr.color.*
import org.openrndr.extra.color.spaces.* import org.openrndr.extra.color.spaces.*
inline fun <reified T : AlgebraicColor<T>> ColorRGBa.blendWith(other: ColorRGBa, steps: Int): Sequence<ColorRGBa> { inline fun <reified T> ColorRGBa.blendWith(other: ColorRGBa, steps: Int): Sequence<ColorRGBa>
where T : AlgebraicColor<T>,
T: ColorModel<T> {
return sequence { return sequence {
for (step in 0 until steps) { for (step in 0 until steps) {
yield(mixedWith<T>(other, step / (steps - 1.0))) yield(mixedWith<T>(other, step / (steps - 1.0)))
@@ -11,30 +13,36 @@ inline fun <reified T : AlgebraicColor<T>> ColorRGBa.blendWith(other: ColorRGBa,
} }
} }
inline fun <reified T : AlgebraicColor<T>> ColorRGBa.mixedWith(other: ColorRGBa, factor: Double): ColorRGBa { inline fun <reified T : ColorModel<T>> ColorRGBa.convertTo(): T {
val converted = when (T::class) {
val mixed = when (T::class) { ColorHSLa::class -> this.toHSLa()
ColorHSLa::class -> this.toHSLa().mix(other.toHSLa(), factor) ColorHSVa::class -> this.toHSVa()
ColorHSVa::class -> this.toHSVa().mix(other.toHSVa(), factor) ColorRGBa::class -> this
ColorRGBa::class -> this.mix(other, factor) ColorHSLUVa::class -> this.toHSLUVa()
ColorOKLABa::class -> this.toOKLABa()
ColorHSLUVa::class -> this.toHSLUVa().mix(other.toHSLUVa(), factor) ColorOKLCHa::class -> this.toOKLCHa()
ColorOKLABa::class -> this.toOKLABa().mix(other.toOKLABa(), factor) ColorOKHSLa::class -> this.toOKHSLa()
ColorOKLCHa::class -> this.toOKLCHa().mix(other.toOKLCHa(), factor) ColorOKHSVa::class -> this.toOKHSVa()
ColorOKHSLa::class -> this.toOKHSLa().mix(other.toOKHSLa(), factor) ColorLABa::class -> this.toLABa()
ColorOKHSVa::class -> this.toOKHSVa().mix(other.toOKHSVa(), factor) ColorLUVa::class -> this.toLUVa()
ColorLCHABa::class -> this.toLCHABa()
ColorLABa::class -> this.toLABa().mix(other.toLABa(), factor) ColorLCHUVa::class -> this.toLCHUVa()
ColorLUVa::class -> this.toLUVa().mix(other.toLUVa(), factor) ColorOKHSLa::class -> this.toOKHSLa()
ColorLCHABa::class -> this.toLCHABa().mix(other.toLCHABa(), factor) ColorXYZa::class -> this.toXYZa()
ColorLCHUVa::class -> this.toLCHUVa().mix(other.toLCHUVa(), factor) ColorXSLUVa::class -> this.toXSLUVa()
ColorOKHSLa::class -> this.toOKHSLa().mix(other.toOKHSLa(), factor) ColorXSVa::class -> this.toXSVa()
ColorXYZa::class -> this.toXYZa().mix(other.toXYZa(), factor) ColorXSLa::class -> this.toXSLa()
ColorXSLUVa::class -> this.toXSLUVa().mix(other.toXSLUVa(), factor)
ColorXSVa::class -> this.toXSVa().mix(other.toXSVa(), factor)
ColorXSLa::class -> this.toXSLa().mix(other.toXSLa(), factor)
else -> error("color model ${T::class} not supported") else -> error("color model ${T::class} not supported")
}.toRGBa() }
return converted as T
}
inline fun <reified T> ColorRGBa.mixedWith(other: ColorRGBa, factor: Double): ColorRGBa
where T : AlgebraicColor<T>, T : ColorModel<T> {
val source = convertTo<T>()
val target = other.convertTo<T>()
val mixed = source.mix(target, factor).toRGBa()
return if (mixed.linearity.isEquivalent(linearity)) { return if (mixed.linearity.isEquivalent(linearity)) {
mixed mixed
@@ -47,30 +55,14 @@ inline fun <reified T : AlgebraicColor<T>> ColorRGBa.mixedWith(other: ColorRGBa,
mixed mixed
} }
} }
return this
} }
inline fun <reified T> ColorRGBa.saturate(factor: Double): ColorRGBa inline fun <reified T> ColorRGBa.saturate(factor: Double): ColorRGBa
where T : SaturatableColor<T>, where T : SaturatableColor<T>,
T : ColorModel<T>,
T : ConvertibleToColorRGBa { T : ConvertibleToColorRGBa {
val converted = when (T::class) { val saturated = convertTo<T>().saturate(factor).toRGBa()
ColorHPLUVa::class -> toHPLUVa()
ColorHSLUVa::class -> toHSLUVa()
ColorHSLa::class -> toHSLa()
ColorHSVa::class -> toHSVa()
ColorXSLa::class -> toXSLa()
ColorXSVa::class -> toXSVa()
ColorOKLCHa::class -> toOKLCHa()
ColorOKHSLa::class -> toOKHSLa()
ColorOKHSVa::class -> toOKHSVa()
ColorXSLUVa::class -> toXSLUVa()
ColorOKLCHa::class -> toOKLCHa()
else -> error("Color space ${T::class} not supported")
}
val saturated = (converted.saturate(factor) as ConvertibleToColorRGBa).toRGBa()
return if (saturated.linearity.isEquivalent(linearity)) { return if (saturated.linearity.isEquivalent(linearity)) {
saturated saturated
} else { } else {
@@ -85,22 +77,10 @@ inline fun <reified T> ColorRGBa.saturate(factor: Double): ColorRGBa
} }
inline fun <reified T> ColorRGBa.shiftHue(degrees: Double): ColorRGBa where inline fun <reified T> ColorRGBa.shiftHue(degrees: Double): ColorRGBa where
T : HueShiftableColor<T>, T : ConvertibleToColorRGBa { T : HueShiftableColor<T>,
val converted = when (T::class) { T : ColorModel<T>,
ColorHSLa::class -> toHSLa() T : ConvertibleToColorRGBa {
ColorHSVa::class -> toHSVa() val converted = convertTo<T>()
ColorXSLa::class -> toXSLa()
ColorXSVa::class -> toXSVa()
ColorOKLCHa::class -> toOKLCHa()
ColorLCHABa::class -> toLCHABa()
ColorLCHUVa::class -> toLCHABa()
ColorOKHSLa::class -> toOKHSLa()
ColorOKHSVa::class -> toOKHSVa()
ColorHPLUVa::class -> toHPLUVa()
ColorHSLUVa::class -> toHSLUVa()
ColorXSLUVa::class -> toXSLUVa()
else -> error("Color space ${T::class} not supported")
}
val shifted = (converted.shiftHue(degrees) as ConvertibleToColorRGBa).toRGBa() val shifted = (converted.shiftHue(degrees) as ConvertibleToColorRGBa).toRGBa()
return if (shifted.linearity.isEquivalent(linearity)) { return if (shifted.linearity.isEquivalent(linearity)) {
shifted shifted