-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathppm.py
More file actions
81 lines (67 loc) · 2.04 KB
/
Copy pathppm.py
File metadata and controls
81 lines (67 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python3
"""
ppm_thick_flipped_tile2x.py
"""
import numpy as np
def main():
txtfile = "grid.txt"
print(f"Reading {txtfile}...")
data = np.loadtxt(txtfile, skiprows=1, usecols=(0,1,2,3))
x = data[:,0].astype(int)
y = data[:,1].astype(int)
lcells = data[:,2]
lcomp = data[:,3]
nx = int(x.max()) + 1
ny = int(y.max()) + 1
grid = np.full((ny, nx), np.nan, dtype=float)
grid[y-1, x-1] = np.where(lcells > 0.01, lcomp, np.nan)
# R=1 solid thickening
solid = np.isnan(grid)
thickened = solid.copy()
for dy in [-1,0,1]:
for dx in [-1,0,1]:
if dy == 0 and dx == 0: continue
thickened |= np.roll(np.roll(solid, dy, axis=0), dx, axis=1)
grid[thickened] = np.nan
grid = np.flipud(grid) # grow upward
grid_tiled = np.hstack((grid, grid)) # 2× periodic
# === COLOR SCALE MATCHING ===
def to_ppm_color(val):
if np.isnan(val):
return (0, 0, 0) # solid black
# Normalize roughly 0–20 wt% (adjust as needed)
t = max(0.0, min(1.0, val / 20.0))
if t < 0.2:
r = 255
g = int(255 * (t / 0.2))
b = 0
elif t < 0.4:
r = int(255 * (1.0 - (t-0.2)/0.2))
g = 255
b = 0
elif t < 0.6:
r = 0
g = 255
b = int(255 * ((t-0.4)/0.2))
elif t < 0.8:
r = 0
g = int(255 * (1.0 - (t-0.6)/0.2))
b = 255
else:
r = int(100 * ((t-0.8)/0.2))
g = 0
b = 255
return (r, g, b)
# Write PPM
with open("out.ppm", "wb") as f:
f.write(b"P6\n")
f.write(f"{2*nx} {ny}\n".encode())
f.write(b"255\n")
for j in range(ny):
for i in range(2*nx):
r,g,b = to_ppm_color(grid_tiled[j,i])
f.write(bytes([r, g, b]))
print("✅ out.ppm created!")
print(f" Size: {2*nx} × {ny}")
if __name__ == "__main__":
main()