GPU art: redraw front and back with real detail
Six-blade fans with rim, air duct and hub, graphite shroud with fin stack, copper heat-pipe ends and an 8-pin connector, PCB with parts and per-contact gold fingers; back has brushed backplate, vents, screws, recessed silkscreen plate, QR/barcode sticker and a seal. Overlays realigned. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
de7d5caafe
commit
e643332a41
10 files changed
+148
-57
No files matched your search
+148
-57
@@ -30,6 +30,12 @@ C = {
|
||||
'Y': (0xC8, 0xA4, 0x4A), # 金手指
|
||||
'c': (0x2E, 0x2A, 0x2A), # 焦黑
|
||||
'e': (0x6B, 0x4A, 0x3A), # 焦痕
|
||||
'p': (0xC0, 0x7A, 0x4A), # 铜
|
||||
'q': (0x8A, 0x4F, 0x34), # 暗铜
|
||||
'w': (0xE6, 0xE2, 0xD0), # 白
|
||||
'n': (0x1E, 0x1B, 0x25), # 近黑
|
||||
'x': (0x4A, 0x4E, 0x58), # 石墨亮边
|
||||
'z': (0x2D, 0x2F, 0x38), # 石墨暗
|
||||
}
|
||||
|
||||
|
||||
@@ -117,92 +123,176 @@ def outline(c):
|
||||
|
||||
|
||||
def bracket(c):
|
||||
"""左端金属挡板,三个接口孔。"""
|
||||
"""左端金属挡板:带折边、网孔、三个接口(带高光边与内壁)、底部固定螺丝。"""
|
||||
c.rect(1, 2, 5, 27, 'b')
|
||||
c.rect(1, 2, 1, 27, 'h'); c.rect(5, 2, 5, 27, 'd')
|
||||
for y in (5, 11, 17):
|
||||
c.rect(1, 2, 1, 27, 'h'); c.rect(2, 2, 2, 27, 'l'); c.rect(5, 2, 5, 27, 'd'); c.rect(4, 2, 4, 27, 'm')
|
||||
for y in (5, 11, 17): # 三个接口:外框亮边、内腔深色、中间一条触片
|
||||
c.rect(2, y, 4, y + 3, 'k')
|
||||
c.rect(2, y, 4, y, 'g')
|
||||
c.put(3, 22, 'k'); c.put(3, 24, 'k')
|
||||
c.rect(2, y, 4, y, 'h'); c.put(2, y + 1, 'g'); c.put(4, y + 1, 'g')
|
||||
c.put(3, y + 2, 'd'); c.put(3, y + 3, 'g')
|
||||
for y in range(20, 27, 2): # 散热网孔
|
||||
c.put(2, y, 'k'); c.put(4, y, 'k')
|
||||
c.put(3, y + 1, 'k')
|
||||
c.put(3, 3, 'k'); c.put(3, 27, 'g') # 顶部卡扣与底部螺丝
|
||||
c.put(2, 27, 'h'); c.put(4, 27, 'd')
|
||||
|
||||
|
||||
def fan(c, cx, cy, accent, burnt=False):
|
||||
"""风扇:深色风道里六片弯曲扇叶(前缘高光、叶面按受光渐变),外圈细边,轴心带品牌色点;光从左上来。"""
|
||||
import math
|
||||
for y in range(cy - 7, cy + 8):
|
||||
for x in range(cx - 7, cx + 8):
|
||||
dx, dy = x - cx, y - cy
|
||||
r = math.hypot(dx, dy)
|
||||
if r > 7.4:
|
||||
continue
|
||||
ang = (math.atan2(dy, dx) / (2 * math.pi)) % 1.0
|
||||
lit = (dx + dy) < 0
|
||||
if r >= 6.5: # 外圈细边
|
||||
c.put(x, y, 'l' if dx + dy < -3 else ('b' if dx + dy < 3 else 'g'))
|
||||
elif r >= 5.6: # 风道
|
||||
c.put(x, y, 'n')
|
||||
elif r <= 2.3: # 轴心
|
||||
c.put(x, y, 'h' if (dx + dy) < -1 else 'b' if dx + dy < 2 else 'm')
|
||||
else:
|
||||
t = (ang * 6 + (r - 3) * 0.16) % 1.0
|
||||
if t < 0.55:
|
||||
c.put(x, y, 'h' if t < 0.09 else ('l' if lit else 'b') if t < 0.30 else ('b' if lit else 'm'))
|
||||
else:
|
||||
c.put(x, y, 'n' if t < 0.85 else 'k')
|
||||
c.put(cx, cy, accent)
|
||||
c.put(cx - 1, cy - 1, 'w')
|
||||
|
||||
|
||||
def gpu_front(accent, accent_dark, burnt=False):
|
||||
"""显卡正面(48×32,3×2 格),略微俯视:顶面是带两个风扇的散热罩,左端金属挡板(三个接口),
|
||||
前沿露出 PCB 和金手指,右端一道暗侧面。每格中心都不透明。"""
|
||||
"""显卡正面(48×32,3×2 格),略微俯视:石墨色散热罩带斜切角与品牌色斜条,两个七叶风扇,
|
||||
右端露出鳍片,顶沿露出铜热管和 8 针供电口,前沿是带元件的 PCB 和逐根画出的金手指。每格中心都不透明。"""
|
||||
c = Canvas(W, H)
|
||||
bracket(c)
|
||||
# 散热罩底色:左上亮、右下暗的渐变,右上角切角
|
||||
for y in range(TOP0, TOP1 + 1):
|
||||
for x in range(L, R + 1):
|
||||
c.put(x, y, 'm')
|
||||
c.put(R, y, 'd'); c.put(R - 1, y, 'd')
|
||||
c.put(x, y, 'x' if y < TOP0 + 3 else 'd' if (x - L) < 4 else 'z')
|
||||
for x in range(L, R + 1):
|
||||
c.put(x, TOP0, 'l'); c.put(x, TOP0 + 1, 'b')
|
||||
for x in range(L + 1, R - 1):
|
||||
c.put(x, TOP1 - 1, accent)
|
||||
c.put(L + 1, TOP1, accent_dark); c.put(R - 2, TOP1, accent_dark)
|
||||
c.put(x, TOP0, 'h' if x < R - 5 else 'l'); c.put(x, TOP0 + 1, 'l' if x < R - 8 else 'b')
|
||||
for y in range(TOP0, TOP1 + 1): # 左缘受光
|
||||
c.put(L, y, 'l'); c.put(L + 1, y, 'b')
|
||||
# 右端鳍片(竖向细条)
|
||||
for x in range(R - 4, R + 1):
|
||||
for y in range(TOP0 + 2, TOP1):
|
||||
c.put(x, y, 'g' if (x - (R - 4)) % 2 == 0 else 'k')
|
||||
c.rect(R - 5, TOP0 + 2, R - 5, TOP1 - 1, 'x')
|
||||
# 中间的筋条(两个风扇之间)与上下沿的槽
|
||||
for y in range(TOP0 + 3, TOP1 - 2):
|
||||
c.put(25, y, 'k'); c.put(26, y, 'x')
|
||||
# 品牌色斜条(从前沿向左上延伸)与前沿色条
|
||||
for k in range(0, 8):
|
||||
c.put(L + 3 + k, TOP1 - 1 - k // 2, accent)
|
||||
for x in range(L + 1, R - 5):
|
||||
c.put(x, TOP1 - 1, accent if x % 9 else accent_dark)
|
||||
c.put(x, TOP1, accent_dark)
|
||||
for cx, cy in FANS:
|
||||
for y in range(cy - 7, cy + 8):
|
||||
for x in range(cx - 7, cx + 8):
|
||||
d2 = (x - cx) ** 2 + (y - cy) ** 2
|
||||
if d2 <= 49:
|
||||
c.put(x, y, 'k')
|
||||
if 26 <= d2 <= 38:
|
||||
c.put(x, y, 'g')
|
||||
for k in range(-5, 6):
|
||||
if abs(k) >= 1:
|
||||
c.put(cx + k, cy, 'g'); c.put(cx, cy + k, 'g')
|
||||
for dx, dy in ((-3, -3), (3, 3), (3, -3), (-3, 3)):
|
||||
c.put(cx + dx, cy + dy, 'g')
|
||||
c.rect(cx - 1, cy - 1, cx + 1, cy + 1, 'b')
|
||||
c.put(cx, cy, 'h')
|
||||
fan(c, cx, cy, accent)
|
||||
for dx, dy in ((-7, -7), (7, -7), (-7, 7), (7, 7)): # 风扇四角的固定孔
|
||||
c.put(cx + dx, cy + dy, 'n' if dx + dy else 'k')
|
||||
# 顶沿:铜热管端头 + 8 针供电口(带针脚)
|
||||
for x0 in (L + 6, L + 8, L + 10, L + 12):
|
||||
c.put(x0, TOP0 - 1, 'p'); c.put(x0 + 1, TOP0 - 1, 'q')
|
||||
for x in range(L + 18, L + 28):
|
||||
c.put(x, TOP0 - 1, 'n')
|
||||
for x in range(L + 18, L + 28, 2):
|
||||
c.put(x, TOP0 - 2, 'k')
|
||||
for x in range(L + 19, L + 28, 2):
|
||||
c.put(x, TOP0 - 2, 'Y')
|
||||
# 前沿:PCB(绿)带元件,之后金手指
|
||||
for x in range(L, R + 1):
|
||||
c.put(x, TOP1 + 1, 'g2'); c.put(x, TOP1 + 2, 'g2')
|
||||
for x in range(L, R + 1):
|
||||
c.put(x, TOP1 + 3, 'Y'); c.put(x, TOP1 + 4, 'Y' if x % 2 == 0 else 'e')
|
||||
for y in (TOP1 + 3, TOP1 + 4):
|
||||
c.put(L + 17, y, 'k'); c.put(L + 18, y, 'k')
|
||||
for x0 in (L + 4, L + 12): # 顶上供电口
|
||||
c.rect(x0, TOP0 - 1, x0 + 4, TOP0 - 1, 'k')
|
||||
c.put(x, TOP1 + 1, 'G' if x % 7 else 'g2'); c.put(x, TOP1 + 2, 'g2')
|
||||
for x0 in (L + 4, L + 11, L + 22, L + 29):
|
||||
c.put(x0, TOP1 + 1, 'b'); c.put(x0 + 1, TOP1 + 1, 'g')
|
||||
for x in range(L, R + 1): # 金手指:每一根带深色分隔
|
||||
if x in (L + 17, L + 18):
|
||||
continue
|
||||
c.put(x, TOP1 + 3, 'Y' if x % 2 == 0 else 'e'); c.put(x, TOP1 + 4, 'Y' if x % 2 == 0 else 'q')
|
||||
c.put(x, TOP1 + 5, 'e' if x % 2 == 0 else 'k')
|
||||
for x in range(L, R + 1):
|
||||
for y in range(TOP1 + 1, 28):
|
||||
if c.px[y][x] is None:
|
||||
c.put(x, y, 'k')
|
||||
if burnt:
|
||||
for x, y in [(12, 8), (13, 9), (18, 17), (35, 8), (36, 9), (40, 18), (24, 12), (25, 11)]:
|
||||
for x, y in [(12, 8), (13, 9), (18, 17), (35, 8), (36, 9), (40, 18), (24, 12), (25, 11), (19, 9), (33, 16)]:
|
||||
c.put(x, y, 'c')
|
||||
for x in range(L + 1, R - 1):
|
||||
for x in range(L + 1, R - 5):
|
||||
c.put(x, TOP1 - 1, 'e')
|
||||
for cx, cy in FANS:
|
||||
for dx, dy in ((0, 0), (1, 1), (-1, 1), (2, -2), (-2, -2)):
|
||||
c.put(cx + dx, cy + dy, 'c')
|
||||
outline(c)
|
||||
return c
|
||||
|
||||
|
||||
def screw(c, x, y):
|
||||
c.put(x, y, 'b'); c.put(x + 1, y, 'g'); c.put(x, y + 1, 'g'); c.put(x + 1, y + 1, 'k')
|
||||
|
||||
|
||||
def gpu_back(accent, accent_dark, burnt=False):
|
||||
"""显卡背面(翻面后):左端仍是挡板;黑色背板,上面一行丝印(型号用叠加图画),
|
||||
右下一张序列号贴纸,贴纸边上一道封条。"""
|
||||
"""显卡背面(翻面后):左端仍是挡板;拉丝金属背板,带通风槽、四角螺丝、品牌色斜条;
|
||||
中上是一块凹进去的丝印区(型号用叠加图写在这里),右下是带二维码和条码的序列号贴纸,贴纸边上一道封条。"""
|
||||
c = Canvas(W, H)
|
||||
bracket(c)
|
||||
for y in range(TOP0, 28):
|
||||
for x in range(L, R + 1):
|
||||
c.put(x, y, 'd')
|
||||
c.put(R, y, 'k'); c.put(R - 1, y, 'k')
|
||||
c.put(x, y, 'd' if (y % 3) else 'm' if x % 2 else 'd')
|
||||
c.put(R, y, 'k'); c.put(R - 1, y, 'z')
|
||||
for x in range(L, R + 1):
|
||||
c.put(x, TOP0, 'm'); c.put(x, TOP0 + 1, 'm')
|
||||
c.put(x, TOP0, 'l'); c.put(x, TOP0 + 1, 'b')
|
||||
for y in range(TOP0, 28):
|
||||
c.put(L, y, 'b'); c.put(L + 1, y, 'x')
|
||||
# 丝印凹槽
|
||||
c.rect(9, 7, 43, 13, 'z')
|
||||
c.rect(9, 7, 43, 7, 'k'); c.rect(9, 7, 9, 13, 'k')
|
||||
c.rect(9, 13, 43, 13, 'x')
|
||||
# 品牌色斜条与前沿色条
|
||||
for x in range(L + 1, R - 1):
|
||||
c.put(x, 16, accent)
|
||||
c.put(L + 1, 17, accent_dark); c.put(R - 2, 17, accent_dark)
|
||||
for x in range(L + 2, R - 2, 5): # 背板螺丝
|
||||
for y in (22, 25):
|
||||
c.put(x, y, 'b'); c.put(x + 1, y, 'k')
|
||||
c.rect(26, 18, 41, 21, 'h') # 序列号贴纸(印刷条码)
|
||||
for x in range(27, 41, 2):
|
||||
c.rect(x, 19, x, 20, 'k')
|
||||
c.rect(44, 17, 44, 22, 'R') # 封条(红色)
|
||||
c.rect(43, 17, 43, 22, 'r2')
|
||||
for k in range(0, 7):
|
||||
c.put(R - 3 - k, 15 - k // 2 if k < 4 else 14, accent_dark)
|
||||
# 通风槽(左下一组)
|
||||
for y in (19, 21, 23, 25):
|
||||
for x in range(L + 4, L + 14):
|
||||
c.put(x, y, 'k')
|
||||
for x in range(L + 4, L + 14):
|
||||
c.put(x, y + 1, 'x') if y + 1 < 27 else None
|
||||
# 四角螺丝
|
||||
for x, y in ((L + 2, TOP0 + 3), (R - 5, TOP0 + 3), (L + 2, 24), (R - 5, 24)):
|
||||
screw(c, x, y)
|
||||
# 序列号贴纸:左边二维码,右边条码与小字
|
||||
c.rect(22, 17, 41, 23, 'w')
|
||||
c.rect(22, 17, 41, 17, 'h'); c.rect(22, 23, 41, 23, 'l')
|
||||
qr = ['1110101', '1010011', '1011101', '0001010', '1101111', '0100101', '1110011']
|
||||
for j, row in enumerate(qr):
|
||||
for i, ch in enumerate(row):
|
||||
if ch == '1':
|
||||
c.put(23 + i, 17 + j - (1 if j == 6 else 0) * 0, 'n') if j < 6 else None
|
||||
for x in range(31, 41, 2):
|
||||
c.rect(x, 18, x, 20, 'n')
|
||||
for x in range(32, 41, 3):
|
||||
c.put(x, 18, 'w'); c.put(x, 19, 'w')
|
||||
for x in range(31, 41):
|
||||
if x % 3 != 0:
|
||||
c.put(x, 22, 'm')
|
||||
# 封条(红底白字)
|
||||
c.rect(43, 16, 44, 24, 'R')
|
||||
c.rect(43, 16, 43, 24, 'r2')
|
||||
for y in (18, 20, 22):
|
||||
c.put(44, y, 'w')
|
||||
# 背面金手指一行
|
||||
for x in range(L, R + 1):
|
||||
for y in range(28, 28):
|
||||
pass
|
||||
if x in (L + 17, L + 18):
|
||||
continue
|
||||
c.put(x, 27, 'Y' if x % 2 == 0 else 'e')
|
||||
if burnt:
|
||||
for x, y in [(14, 9), (15, 10), (30, 11), (36, 13), (20, 14)]:
|
||||
for x, y in [(14, 9), (15, 10), (30, 11), (36, 13), (20, 14), (26, 21), (12, 22)]:
|
||||
c.put(x, y, 'c')
|
||||
outline(c)
|
||||
return c
|
||||
@@ -265,14 +355,15 @@ def ov_sticker(kind):
|
||||
"""贴纸叠加:1 手写序列号(条码被盖住、写了歪歪扭扭的字);2 封条缺失(只剩撕过的残胶)。"""
|
||||
c = overlay()
|
||||
if kind == 1:
|
||||
c.rect(26, 18, 41, 21, 'h')
|
||||
for x, y in ((27, 20), (28, 19), (29, 20), (30, 19), (32, 20), (33, 19), (33, 21), (35, 19), (36, 20), (37, 19), (38, 21), (39, 20), (40, 19)):
|
||||
c.rect(22, 17, 41, 23, 'w')
|
||||
c.rect(22, 17, 41, 17, 'h'); c.rect(22, 23, 41, 23, 'l')
|
||||
for x, y in ((24, 20), (25, 19), (26, 20), (27, 19), (29, 20), (30, 19), (30, 21), (32, 19), (33, 20), (34, 19), (35, 21), (36, 20), (37, 19), (38, 20), (39, 21), (24, 22), (26, 21), (28, 22), (31, 22), (35, 22)):
|
||||
c.put(x, y, 'O')
|
||||
else:
|
||||
c.rect(43, 17, 44, 22, 'd')
|
||||
for y in (17, 19, 21, 22):
|
||||
c.rect(43, 16, 44, 24, 'd')
|
||||
for y in (16, 18, 20, 22, 24):
|
||||
c.put(44, y, 'm')
|
||||
c.put(43, 18, 'm'); c.put(43, 20, 'm')
|
||||
c.put(43, 17, 'm'); c.put(43, 21, 'm'); c.put(43, 23, 'x')
|
||||
return c
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user