如何解决控制台光线追踪器索引
我一直在创建光线追踪器。它在带有 ANSI 转义码的控制台中工作。但问题是,我不知道如何索引颜色。它采用控制台的维度并创建一个数组,在其中打印 ANSI。使用背景颜色和 u+2580 字符(“下半块”)将单个字符解释为 2 个像素。此外,颜色按二维数组排序,而像素按一维数组排序。请帮帮我
from PIL import Image
import numpy as np
from functools import reduce
from numbers import Number
import os
size=list(os.get_terminal_size())
cam=np.array([0,5])
image=np.array([[u"\033[48;{r};{g};{b}m",u"\033[38;{r};{g};{b}m\u2584"]]*size[0]*size[1])
def extract(cond,x):
if isinstance(x,Number):
return x
else:
return np.extract(cond,x)
class vec3():
def __init__(self,x,y,z):
(self.x,self.y,self.z) = (x,z)
def __mul__(self,other):
return vec3(self.x * other,self.y * other,self.z * other)
def __add__(self,other):
return vec3(self.x + other.x,self.y + other.y,self.z + other.z)
def __sub__(self,other):
return vec3(self.x - other.x,self.y - other.y,self.z - other.z)
def dot(self,other):
return (self.x * other.x) + (self.y * other.y) + (self.z * other.z)
def __abs__(self):
return self.dot(self)
def norm(self):
mag = np.sqrt(abs(self))
return self * (1.0 / np.where(mag == 0,1,mag))
def components(self):
return (self.x,self.z)
def extract(self,cond):
return vec3(extract(cond,self.x),extract(cond,self.y),self.z))
def place(self,cond):
r = vec3(np.zeros(cond.shape),np.zeros(cond.shape),np.zeros(cond.shape))
np.place(r.x,cond,self.x)
np.place(r.y,self.y)
np.place(r.z,self.z)
return r
rgb = vec3
(w,h) = (size[0],size[1]*2) # Screen size
L = vec3(5,5,-10) # Point light position
E = vec3(0,0.35,-1) # Eye position
FaraWAY = 1.0e39 # an implausibly huge distance
def raytrace(O,D,scene,bounce = 0):
# O is the ray origin,D is the normalized ray direction
# scene is a list of Sphere objects (see below)
# bounce is the number of the bounce,starting at zero for camera rays
distances = [s.intersect(O,D) for s in scene]
nearest = reduce(np.minimum,distances)
color = rgb(0,0)
for (s,d) in zip(scene,distances):
hit = (nearest != FaraWAY) & (d == nearest)
if np.any(hit):
dc = extract(hit,d)
Oc = O.extract(hit)
Dc = D.extract(hit)
cc = s.light(Oc,Dc,dc,bounce)
color += cc.place(hit)
return color
class Sphere:
def __init__(self,center,r,diffuse,mirror = 0.5):
self.c = center
self.r = r
self.diffuse = diffuse
self.mirror = mirror
def intersect(self,O,D):
b = 2 * D.dot(O - self.c)
c = abs(self.c) + abs(O) - 2 * self.c.dot(O) - (self.r * self.r)
disc = (b ** 2) - (4 * c)
sq = np.sqrt(np.maximum(0,disc))
h0 = (-b - sq) / 2
h1 = (-b + sq) / 2
h = np.where((h0 > 0) & (h0 < h1),h0,h1)
pred = (disc > 0) & (h > 0)
return np.where(pred,h,FaraWAY)
def diffusecolor(self,M):
return self.diffuse
def light(self,d,bounce):
M = (O + D * d) # intersection point
N = (M - self.c) * (1. / self.r) # normal
toL = (L - M).norm() # direction to light
toO = (E - M).norm() # direction to ray origin
nudged = M + N * .0001 # M nudged to avoid itself
# Shadow: find if the point is shadowed or not.
# This amounts to finding out if M can see the light
light_distances = [s.intersect(nudged,toL) for s in scene]
light_nearest = reduce(np.minimum,light_distances)
seelight = light_distances[scene.index(self)] == light_nearest
# Ambient
color = rgb(0.05,0.05,0.05)
# LAmbert shading (diffuse)
lv = np.maximum(N.dot(toL),0)
color += self.diffusecolor(M) * lv * seelight
# Reflection
if bounce < 2:
rayD = (D - N * 2 * D.dot(N)).norm()
color += raytrace(nudged,rayD,bounce + 1) * self.mirror
# Blinn-phong shading (specular)
phong = N.dot((toL + toO).norm())
color += rgb(1,1) * np.power(np.clip(phong,1),50) * seelight
return color
scene = [
Sphere(vec3(.75,.1,.6,rgb(0,1)),Sphere(vec3(-.75,2.25),rgb(.5,.223,.5)),Sphere(vec3(-2.75,3.5),rgb(1,.572,.184)),Sphere(vec3(0,-99999.5,0),99999,rgb(.75,.75,.75)),]
r = w/h
# Screen coordinates: x0,y0,x1,y1.
S = (-1,1 / r + .25,-1 / r + .25)
x = np.tile(np.linspace(S[0],S[2],w),h)
y = np.repeat(np.linspace(S[1],S[3],h),w)
Q = vec3(x,0)
color = raytrace(E,(Q - E).norm(),scene)
color=[(255 * np.clip(c,1).reshape((h,w))).astype(np.uint8) for c in color.components()]
r=color[0]
g=color[1]
b=color[2]
for i in range(len(image)):
#Problem Starts here
image[i][0]=image[i][0].format(r=r[i%2][i%w+i],g=g[i%2][i%w+i],b=b[i%2][i%w+i])
image[i][1]=image[i][1].format(r=r[i%2][i%w+i+1],g=g[i%2][i%w+i+1],b=b[i%2][i%w+i])
#Problem Ends Here
for i in image:
for c in i:
print(c,end="")
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。