You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中实现色彩数学的环形数值范围判断方案

色轮色相环形范围判断解决方案

问题说明

我正在用Python开发色轮功能:先生成随机RGB颜色,转成HSL格式后固定饱和度(S)和亮度(L),只保留色相(H)变化。现在需要比较两个颜色的色相,判断颜色2的色相是否处于颜色1色相的±90度环形范围内——比如颜色1色相为300时,有效范围是210到30(而非390)。现有if语句无法处理这种环形范围逻辑,求解决方法。

原代码片段:

# 生成随机RGB颜色
import random
no_of_colors= 23 
rgb_colors =["#"+''.join([random.choice('0123456789ABCDEF') for i in range(6)])
       for j in range(no_of_colors)]

# 转换为HSL
from hsluv import hex_to_hsluv, hsluv_to_hex

hsl_colors = list()
for i in rgb_colors:
    col = hex_to_hsluv(i)
    hsl_colors.append(col)

# 转为可变列表
hsl_colors = [list(elem) for elem in hsl_colors]

# 固定饱和度和亮度
for i in hsl_colors:
    i[1] = 75

for i in hsl_colors:
    i[2] = 75

# 同理生成第二个色相列表hsl_colors2
# 这里是判断逻辑的问题点
if hsl_colors2[0] > (hsl_colors[0]-90) or hsl_colors2[0] < (hsl_colors[0]+90):
    print(hsl_colors[j][0])
else:
    print("not within range")

# 尝试过的错误逻辑
if hsl_colors2[0] > (hsl_colors[0]-90) or hsl_colors2[0] < (hsl_colors[0]+90):
    if hsl_colors[0]+90 > 360:
         hsl_colors[0]+90 / 360
         print(hsl_colors[0]+90 / 360)
else:
    print("not within range")

解决思路

色相是0-360度的环形值,直接用大小比较会忽略环形特性。核心是计算两个色相的最小环形差值,或者处理范围跨0/360的情况:

  1. 最小差值法:计算两个色相的差值,取模360后,判断最小的环形距离是否≤90。比如300和30的差值,(300-30) % 360 = 270,最小距离是360-270=90,刚好符合条件。
  2. 范围拆分法:把基准色相的±90范围拆成两种情况:
    • 如果基准色相+90 ≤360,直接判断颜色2色相在[基准-90, 基准+90]之间
    • 如果基准色相+90 >360,判断颜色2色相在[基准-90, 360] 或者 [0, 基准+90-360]之间

实现代码

推荐用最小差值法,逻辑更简洁:

def is_hue_in_range(hue1, hue2, delta=90):
    # 确保色相在0-360范围内
    hue1 = hue1 % 360
    hue2 = hue2 % 360
    # 计算环形差值
    diff = abs(hue1 - hue2)
    # 取最小的环形距离
    min_diff = min(diff, 360 - diff)
    return min_diff <= delta

# 使用示例
hue1 = hsl_colors[0][0]
hue2 = hsl_colors2[0][0]

if is_hue_in_range(hue1, hue2):
    print(f"色相{hue2}在{hue1}的±90度范围内")
else:
    print("色相不在范围内")

如果用范围拆分法,代码如下:

def is_hue_in_range(hue1, hue2, delta=90):
    hue1 = hue1 % 360
    hue2 = hue2 % 360
    lower = hue1 - delta
    upper = hue1 + delta
    
    if upper <= 360:
        return lower <= hue2 <= upper
    else:
        # 范围跨0度,判断是否在[lower,360]或[0, upper-360]
        return hue2 >= lower or hue2 <= (upper - 360)

# 使用示例
hue1 = hsl_colors[0][0]
hue2 = hsl_colors2[0][0]

if is_hue_in_range(hue1, hue2):
    print(f"色相{hue2}在{hue1}的±90度范围内")
else:
    print("色相不在范围内")

完整修改后的代码

把判断逻辑整合到原流程中:

import random
from hsluv import hex_to_hsluv, hsluv_to_hex

def generate_hue_list(no_of_colors):
    # 生成随机RGB并转为固定S=75、L=75的HSL列表
    rgb_colors = ["#"+''.join([random.choice('0123456789ABCDEF') for _ in range(6)]) 
                  for _ in range(no_of_colors)]
    hsl_colors = []
    for rgb in rgb_colors:
        h, s, l = hex_to_hsluv(rgb)
        hsl_colors.append([h, 75, 75])
    return hsl_colors

def is_hue_in_range(hue1, hue2, delta=90):
    hue1 = hue1 % 360
    hue2 = hue2 % 360
    diff = abs(hue1 - hue2)
    min_diff = min(diff, 360 - diff)
    return min_diff <= delta

# 生成两个色相列表
no_of_colors = 23
hsl_colors = generate_hue_list(no_of_colors)
hsl_colors2 = generate_hue_list(no_of_colors)

# 比较第一个元素的色相
hue1 = hsl_colors[0][0]
hue2 = hsl_colors2[0][0]

if is_hue_in_range(hue1, hue2):
    print(f"色相{hue2:.2f}在{hue1:.2f}的±90度环形范围内")
else:
    print("色相不在范围内")

内容的提问来源于stack exchange,提问作者Doda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:40:33