Python 暴力绘制RGB三色图 Pygame框架下
昨天水群,有个群友想要绘制一个三色图,如下
对于Pygame或者其他的GUI框架,画面显示都是依靠图像的一层层覆盖来实现刷新的。所以当绿色的圆覆盖蓝色的圆时,颜色不会想象中的叠加。 最开始的想法是(未实现,具体实现方法请下翻),根据三色叠加的原理,依次绘制三个圆,判断叠加区域,叠加区域的色彩值=(R1+R2, G1+G2, B1+B2),例如蓝色(0,0,255)与红色(255,0,0)叠加,最终色彩值为(255,0,255)。同理,中间白色区域就是三个颜色的叠加,最终为(255,255,255)也就是白色。 具体方法如上图,每次绘制后建立一个surface的副本,然后再绘制下一个圆,接着依次对比原surface,找出颜色改变的地方,并且此点原先不能为白色。从而判断这个点就所处在叠加区域,接着在将原点的RGB与现点的RGB相加,即可做到颜色的叠加。
但是这种方法想想都头疼,也没创建过surface副本的经验。正在准备硬着头皮上时,有个群友说“这个时候肯定要用数学知识呀,数学总是在该用时想不到”,是啊,确实,用数学方法应该是个不错的办法。
那么就来考虑新办法,但是接下来那个群友的数学方法就比较复杂了,他打算以中间白色区域构成一个等边三角形,然后画弧,具体的我也没太了解,但是看起来也比较复杂。
(最后实现方法)
我的想法是,遍历所有像素点,判断该点与三个圆心的距离,如果距离小于圆的半径,则该点在此圆内,给予该点相应色彩值,如果同时在两个圆内,那么该点相应色彩值就是两个圆颜色的叠加后应有的颜色,同理三个圆(所以说暴力硬算,不过那是电脑该干的了。
说干就干。
- 引入pygame模块,并初始化
import pygame
from pygame import *
pygame.init()
- 确定三个圆的圆心坐标,及半径值,简要在图中画出其所在位置
circle = [(200, 100), (150, 200), (250, 200)]
r = 100
for i in circle:
pygame.draw.circle(window, (255, 255, 255), i, r, 10)
- 创建数组,用来判断三个圆对该点的包含情况,初始值都为False
in_circle = [False, False, False]
- 开始遍历,核心部分
for y in range(0, 400):
for x in range(0, 400):
in_circle = [False, False, False]
for i in range(3):
if ((circle[i][0] - x)**2 + (circle[i][1] - y)**2) <= r*r:
in_circle[i] = True
if in_circle[0] == False and in_circle[1] == False and in_circle[2] == False:
window.set_at((x, y), (255, 255, 255))
elif in_circle[0] == True and in_circle[1] == False and in_circle[2] == False:
window.set_at((x, y), (0, 0, 255))
elif in_circle[0] == False and in_circle[1] == True and in_circle[2] == False:
window.set_at((x, y), (0, 255, 0))
elif in_circle[0] == False and in_circle[1] == False and in_circle[2] == True:
window.set_at((x, y), (255, 0, 0))
elif in_circle[0] == True and in_circle[1] == True and in_circle[2] == False:
window.set_at((x, y), (0, 255, 255))
elif in_circle[0] == False and in_circle[1] == True and in_circle[2] == True:
window.set_at((x, y), (255, 255, 0))
elif in_circle[0] == True and in_circle[1] == False and in_circle[2] == True:
window.set_at((x, y), (255, 0, 255))
elif in_circle[0] == True and in_circle[1] == True and in_circle[2] == True:
window.set_at((x, y), (255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
pygame.display.update()
- 最后,在绘制完后,不让界面关闭,加入一个while循环
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
break
-
最终效果:(要慢一些,我这个快进了哈哈 -
所有代码
import pygame
from pygame import *
pygame.init()
window = pygame.display.set_mode((400, 400))
pygame.display.set_caption("RGB")
circle = [(200, 100), (150, 200), (250, 200)]
r = 100
in_circle = [False, False, False]
for i in circle:
pygame.draw.circle(window, (255, 255, 255), i, r, 10)
for y in range(0, 400):
for x in range(0, 400):
in_circle = [False, False, False]
for i in range(3):
if ((circle[i][0] - x)**2 + (circle[i][1] - y)**2) <= r*r:
in_circle[i] = True
if in_circle[0] == False and in_circle[1] == False and in_circle[2] == False:
window.set_at((x, y), (255, 255, 255))
elif in_circle[0] == True and in_circle[1] == False and in_circle[2] == False:
window.set_at((x, y), (0, 0, 255))
elif in_circle[0] == False and in_circle[1] == True and in_circle[2] == False:
window.set_at((x, y), (0, 255, 0))
elif in_circle[0] == False and in_circle[1] == False and in_circle[2] == True:
window.set_at((x, y), (255, 0, 0))
elif in_circle[0] == True and in_circle[1] == True and in_circle[2] == False:
window.set_at((x, y), (0, 255, 255))
elif in_circle[0] == False and in_circle[1] == True and in_circle[2] == True:
window.set_at((x, y), (255, 255, 0))
elif in_circle[0] == True and in_circle[1] == False and in_circle[2] == True:
window.set_at((x, y), (255, 0, 255))
elif in_circle[0] == True and in_circle[1] == True and in_circle[2] == True:
window.set_at((x, y), (255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
break
以上,over! 有更好的方法欢迎评论告知,我向你敬礼呀~ 或许我该去学学算法了( 具体的应该还能再优化? https://blog.csdn.net/zx3517288/article/details/53326420
|