微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

控制台光线追踪器索引

如何解决控制台光线追踪器索引

我一直在创建光线追踪器。它在带有 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 举报,一经查实,本站将立刻删除。