82 lines
2.4 KiB
Python
82 lines
2.4 KiB
Python
from dataclasses import dataclass
|
|
from typing import Any, Callable
|
|
import rich
|
|
# from ._ansii import ANSII
|
|
# TODO depricate with rich
|
|
|
|
@dataclass(slots=True, kw_only=False, frozen=False)
|
|
class RGB:
|
|
r: int
|
|
g: int
|
|
b: int
|
|
data: Any = ''
|
|
|
|
def __getitem__(_, item):
|
|
return (_.r, _.g, _.b)[item]
|
|
|
|
@staticmethod
|
|
def hexadec(hexCode: hex):
|
|
# print(RGB.hexadec(0xFF0003))
|
|
r = hexCode >> 16
|
|
g = (hexCode ^ (r << 16)) >> 8
|
|
b = (hexCode ^ (r << 16)) ^ (g << 8)
|
|
return RGB(r, g, b)
|
|
|
|
@staticmethod
|
|
def hx(hexCode: hex):
|
|
return RGB.hexadec(hexCode)
|
|
|
|
def withData(_, data):
|
|
return RGB(_.r, _.g, _.b, data=data)
|
|
|
|
def interpolateRGB(*args, count=100):
|
|
assert all(isinstance(x, RGB) for x in args)
|
|
interpolation = []
|
|
count = int(count / len(args)) + 1
|
|
for ag in range(len(args) - 1):
|
|
interval = [abs((args[ag][i] - args[ag + 1][i]) / count) for i in [0, 1, 2]]
|
|
# print(args[ag], args[ag + 1], interval)
|
|
for c in range(count):
|
|
working = [
|
|
int(args[ag][i] -
|
|
interval[i] * c) if args[ag][i] > args[ag +
|
|
1][i] else int(args[ag][i] + interval[i] * c)
|
|
for i in [0, 1, 2]
|
|
]
|
|
# print(working)
|
|
interpolation.append(RGB(*working))
|
|
# print()
|
|
# print(interpolation)
|
|
return interpolation
|
|
|
|
def interpolatePoint(
|
|
interpolateRGBList,
|
|
array,
|
|
scale: Callable | None = None,
|
|
):
|
|
|
|
arrayNorm = array
|
|
if scale:
|
|
arrayNorm = scale([x for x in array])
|
|
arrayNorm = [x.real if isinstance(x, complex) else x for x in arrayNorm] # TODO why?
|
|
|
|
if not all(isinstance(x, int | float) for x in arrayNorm):
|
|
raise ValueError(f'not type(int|float) | {str(arrayNorm)[:200]}')
|
|
NoNum = object()
|
|
|
|
def norm(ll):
|
|
arrMax, arrMin = (max(ll), min(ll))
|
|
return [(x-arrMin) / max((arrMax - arrMin), 1) if isinstance(x, int | float) else NoNum for x in ll]
|
|
|
|
arrayNorm = norm(arrayNorm)
|
|
assert max(arrayNorm) <= 1
|
|
assert min(arrayNorm) >= 0
|
|
|
|
def index(xx):
|
|
return min(int(xx * (len(interpolateRGBList) - 1)), len(interpolateRGBList) - 1)
|
|
|
|
return [
|
|
interpolateRGBList[index(normal)].withData(data) if data is not NoNum else data
|
|
for data, normal in zip(array, arrayNorm)
|
|
]
|