跟随《Ray Tracing in One Weekend》生成PPM文件仅得单个像素,求修复
问题修复方案
核心错误点
- 循环范围失效:
for i in ny和for j in nx仅会执行一次(Julia中单个数值作为迭代对象时,只会遍历该值一次),无法生成200×100=20000个像素。 - 绿色通道计算错误:
j / (200 - nx)中nx=200,分母为0,导致g为无穷大,最终计算出的绿色值超出PPM颜色值0-255的限制(出现256)。 - 像素值溢出:
round(255.99*r)当r=1时会得到256,违反PPM颜色值范围要求。
修复后的代码
# Graphics Hello World nx = 200 ny = 100 open("image.PPM", "w") do image # 写入PPM文件头 write(image, "P3\n$nx $ny\n255\n") # 遍历每一行(从底部到顶部,匹配PPM图像坐标习惯) for y in ny:-1:1 # 遍历每一列(从左到右) for x in 1:nx # 计算RGB值:红色随行渐变,绿色随列渐变,蓝色固定 r = y / ny g = x / nx b = 0.2 # 将浮点值转换为0-255的整数,用floor避免溢出 ir = floor(Int, 255.99 * r) ig = floor(Int, 255.99 * g) ib = floor(Int, 255.99 * b) # 写入当前像素的RGB值,每行一个像素 write(image, "$ir $ig $ib\n") end end end
修复说明
- 修正循环范围:用
ny:-1:1遍历行(从底部到顶部,和书中的坐标系统一致),1:nx遍历列,确保生成全部20000个像素。 - 修复绿色通道计算:将
j / (200 - nx)改为x / nx,让绿色从左到右从0渐变到1。 - 避免颜色值溢出:用
floor(Int, ...)替代round,确保颜色值不会超过255(比如r=1时,255.99×1=255.99,floor后为255)。 - 简化写入操作:用字符串插值
"P3\n$nx $ny\n255\n"替代多次write调用,代码更简洁。
生成的PPM文件会包含20000行像素值,呈现红色从底部到顶部渐变、绿色从左到右渐变、蓝色固定为51的效果。
内容的提问来源于stack exchange,提问作者I.Inferno
相关产品推荐
相关产品推荐

