渲染对象之间的随机线 python

random lines between rendered objects python

我正在制作一个非常基本的 3d 引擎。当我渲染 2 个或更多对象时,它会在它们之间画线。我不知道为什么会这样,因为我将笔编码为在绘制每个三角形后上升。奇怪的是,当我绘制背景线时,每个对象也将线绘制到背景线。我很迷惑。我只能想到一个原因;它使用另一个对象的最后一个点作为主对象第一个三角形的第一个点。然而,情况似乎并非如此,因为它甚至在背景中也发生了一条简单的线。

from turtle import*
from time import*
from math import*
wn=Screen()
speed(0)
ht()
pu()
wn.tracer(0,0)
fov=200
camx=0
camy=0
camz=-5
xoff=0
yoff=0
zoff=0
xrot=pi*2
yrot=pi
zrot=pi
def goto3d(x,y,z):
  rotxx=x
  rotxy=y*cos(yrot)-z*sin(yrot)
  rotxz=y*sin(yrot)+z*cos(yrot)
  rotyx=rotxx*cos(xrot)+rotxz*sin(xrot)
  rotyy=rotxy
  rotyz=rotxz*cos(xrot)-rotxx*sin(xrot)
  rotzx=rotyx*cos(zrot)-rotyy*sin(zrot)
  rotzy=rotyx*sin(zrot)+rotyy*cos(zrot)
  rotzz=rotyz
  transx=rotzx-xoff
  transy=rotzy-yoff
  transz=rotzz-zoff
  newx=fov*transx/transz
  newy=fov*transy/transz
  if transz<0.1 or newx<=-200 or newy<=-200 or newx>=200 or newy>=200:
    return
  goto(newx,newy)
def triangle(p1x,p1y,p1z,p2x,p2y,p2z,p3x,p3y,p3z):
  goto3d(p1x,p1y,p1z)
  pd()
  goto3d(p2x,p2y,p2z)
  goto3d(p3x,p3y,p3z)
  goto3d(p1x,p1y,p1z)
  pu()
def face(p1x,p1y,p1z,p2x,p2y,p2z,p3x,p3y,p3z,p4x,p4y,p4z,r,g,b,a):
  fillcolor(r,g,b,a)
  begin_fill()
  triangle(p1x,p1y,p1z,p2x,p2y,p2z,p3x,p3y,p3z)
  end_fill()
  begin_fill()
  triangle(p2x,p2y,p2z,p3x,p3y,p3z,p4x,p4y,p4z)
  end_fill()
def bbox(x,y,z,w,h,l,r,g,b,a):
  x+=camx
  y+=camy
  z+=camz
  face(x+-w,y+h,z+l,x+w,y+h,z+l,x+-w,y+-h,z+l,x+w,y+-h,z+l,r,g,b,a)
  face(x+-w,y+h,z+-l,x+w,y+h,z+-l,x+-w,y+-h,z+-l,x+w,y+-h,z+-l,r,g,b,a)
  face(x+-w,y+h,z+l,x+-w,y+h,z+-l,x+-w,y+-h,z+l,x+-w,y+-h,z+-l,r,g,b,a)
  face(x+w,y+h,z+l,x+w,y+h,z+-l,x+w,y+-h,z+l,x+w,y+-h,z+-l,r,g,b,a)
  face(x+-w,y+-h,z+l,x+-w,y+-h,z+-l,x+w,y+-h,z+l,x+w,y+-h,z+-l,r,g,b,a)
  face(x+-w,y+h,z+l,x+-w,y+h,z+-l,x+w,y+h,z+l,x+w,y+h,z+-l,r,g,b,a)
def box(x,y,z,w,h,l,r,g,b):
  if w>=2 or h>=2 or l>=2:
    bbox(x-(w/4),y-(h/4),z-(l/4),w/4,h/4,l/4,r,g,b,.2)
    bbox(x+(w/4),y-(h/4),z-(l/4),w/4,h/4,l/4,r,g,b,.2)
    bbox(x+(w/4),y+(h/4),z-(l/4),w/4,h/4,l/4,r,g,b,.2)
    bbox(x-(w/4),y+(h/4),z-(l/4),w/4,h/4,l/4,r,g,b,.2)
    bbox(x-(w/4),y-(h/4),z+(l/4),w/4,h/4,l/4,r,g,b,.2)
    bbox(x+(w/4),y-(h/4),z+(l/4),w/4,h/4,l/4,r,g,b,.2)
    bbox(x+(w/4),y+(h/4),z+(l/4),w/4,h/4,l/4,r,g,b,.2)
    bbox(x-(w/4),y+(h/4),z+(l/4),w/4,h/4,l/4,r,g,b,.2)
  else:
    bbox(x,y,z,w,h,l,r,g,b,.5)
def render():
  goto(-200,-5)
  pd()
  goto(200,-5)
  pu()
  ### ||| objects go here ||| ###
  ### ||| format is box(x,y,z,width,height,length,r,g,b) ||| ###
  box(2,0,-5,2,2,2,0,255,255)
  box(0,0,0,1,1,1,255,0,0)
def tl():
  global xrot
  xrot-=pi/40
def tr():
  global xrot
  xrot+=pi/40
def f():
  global camx
  global camz
  camz+=.3*cos(-xrot)
  camx+=-(.3*sin(-xrot))
def b():
  global camx
  global camz
  camz+=-(.3*cos(-xrot))
  camx+=.3*sin(-xrot)
wn.onkey(tl,'Left')
wn.onkey(tr,'Right')
wn.onkey(f,'Up')
wn.onkey(b,'Down')
wn.listen()
while True:
  clear()
  render()
  update()

When I render 2 or more objects, it draws lines between them. I do not know why this happens

即使您只有一个对象也会出现问题 - 注释掉您的第一个(小蓝色)框并移动第二个(大红色)框:

问题出在 goto3d()triangle() 中,因为 goto3d() 有一个故障情况(它正在测试),它不会向 triangle() 发回信号,所以它继续并继续绘图。

下面是我修改你的代码来修补这个问题(并将代码翻译成 Python ;-)

from turtle import Screen, Turtle
from math import pi, sin, cos

fov = 200

camx = 0
camy = 0
camz = -5

xoff = 0
yoff = 0
zoff = 0

xrot = pi * 2
yrot = pi
zrot = pi

def goto3d(x, y, z):
    rotxx = x
    rotxy = y * cos(yrot) - z * sin(yrot)
    rotxz = y * sin(yrot) + z * cos(yrot)
    rotyx = rotxx * cos(xrot) + rotxz * sin(xrot)
    rotyy = rotxy
    rotyz = rotxz * cos(xrot) - rotxx * sin(xrot)
    rotzx = rotyx * cos(zrot) - rotyy * sin(zrot)
    rotzy = rotyx * sin(zrot) + rotyy * cos(zrot)
    rotzz = rotyz

    transx = rotzx - xoff
    transy = rotzy - yoff
    transz = rotzz - zoff

    if transz < 0.1:
        return False

    newx = fov * transx/transz
    newy = fov * transy/transz

    if not -200 < newx < 200 or not -200 < newy < 200:
        return False

    turtle.goto(newx, newy)

    return True

def triangle(p1x, p1y, p1z, p2x, p2y, p2z, p3x, p3y, p3z):
    if goto3d(p1x, p1y, p1z):

        turtle.pendown()
        turtle.begin_fill()
        goto3d(p2x, p2y, p2z)
        goto3d(p3x, p3y, p3z)
        goto3d(p1x, p1y, p1z)
        turtle.end_fill()
        turtle.penup()

def face(p1x, p1y, p1z, p2x, p2y, p2z, p3x, p3y, p3z, p4x, p4y, p4z, color):
    turtle.fillcolor(color)

    triangle(p1x, p1y, p1z, p2x, p2y, p2z, p3x, p3y, p3z)
    triangle(p2x, p2y, p2z, p3x, p3y, p3z, p4x, p4y, p4z)

def bbox(x, y, z, w, h, l, color):
    x += camx
    y += camy
    z += camz

    face(x - w, y + h, z + l, x + w, y + h, z + l, x - w, y - h, z + l, x + w, y - h, z + l, color)
    face(x - w, y + h, z - l, x + w, y + h, z - l, x - w, y - h, z - l, x + w, y - h, z - l, color)
    face(x - w, y + h, z + l, x - w, y + h, z - l, x - w, y - h, z + l, x - w, y - h, z - l, color)
    face(x + w, y + h, z + l, x + w, y + h, z - l, x + w, y - h, z + l, x + w, y - h, z - l, color)
    face(x - w, y - h, z + l, x - w, y - h, z - l, x + w, y - h, z + l, x + w, y - h, z - l, color)
    face(x - w, y + h, z + l, x - w, y + h, z - l, x + w, y + h, z + l, x + w, y + h, z - l, color)

def box(x, y, z, w, h, l, color):
    if w >= 2 or h >= 2 or l >= 2:
        # transparent_color = (*color, 0.2)
        transparent_color = color

        bbox(x - w/4, y - h/4, z - l/4, w/4, h/4, l/4, transparent_color)
        bbox(x + w/4, y - h/4, z - l/4, w/4, h/4, l/4, transparent_color)
        bbox(x + w/4, y + h/4, z - l/4, w/4, h/4, l/4, transparent_color)
        bbox(x - w/4, y + h/4, z - l/4, w/4, h/4, l/4, transparent_color)
        bbox(x - w/4, y - h/4, z + l/4, w/4, h/4, l/4, transparent_color)
        bbox(x + w/4, y - h/4, z + l/4, w/4, h/4, l/4, transparent_color)
        bbox(x + w/4, y + h/4, z + l/4, w/4, h/4, l/4, transparent_color)
        bbox(x - w/4, y + h/4, z + l/4, w/4, h/4, l/4, transparent_color)
    else:
        # transparent_color = (*color, 0.5)
        transparent_color = color

        bbox(x, y, z, w, h, l, transparent_color)

def render():
    turtle.clear()
    turtle.goto(-200, -5)
    turtle.pendown()
    turtle.goto(200, -5)
    turtle.penup()

    ### ||| objects go here ||| ###
    ### ||| format is box(x, y, z, width, height, length, (r, g, b)) ||| ###
    box(2, 0, -5, 2, 2, 2, (0, 255, 255))
    box(0, 0, 0, 1, 1, 1, (255, 0, 0))

    screen.update()
    screen.ontimer(render)

def tl():
    global xrot
    xrot -= pi/40

def tr():
    global xrot
    xrot += pi/40

def f():
    global camx, camz

    camz += 0.3 * cos(-xrot)
    camx += -(0.3 * sin(-xrot))

def b():
    global camx, camz

    camz += -(0.3 * cos(-xrot))
    camx += 0.3 * sin(-xrot)

screen = Screen()
screen.tracer(0)
screen.colormode(255)

turtle = Turtle()
turtle.hideturtle()
turtle.penup()

screen.onkey(tl, 'Left')
screen.onkey(tr, 'Right')
screen.onkey(f, 'Up')
screen.onkey(b, 'Down')
screen.listen()

render()

screen.mainloop()

我禁用了透明度,因为我的系统不支持它,但您可以取消注释相应的行以将其恢复。