3D python v2.1
肝
修bug 加功能 刪代碼

#2.1 9/19/2022
#介紹
print('3d v2.1')
print('1 修復(fù)了攝像頭z大于長方體后仍能看到的bug(因?yàn)樵瓉硎侵本€和平面的交點(diǎn))')
print('2 修復(fù)了攝像頭在長方體里面看到圖像錯(cuò)誤(原因和上面差不多)')
print('3 會(huì)顯示攝像機(jī)當(dāng)前坐標(biāo)了')
print('4 對于攝像機(jī)的操控更加方便了')
print('5 可以通過輸入自定義視野 縮放 長方體坐標(biāo)了 允許畫線和面 點(diǎn)的話因?yàn)榭床坏骄蜎]允許')
print('6 讓沒用的變量及時(shí)下班')
#函數(shù)區(qū)
import math
def str_int(list): ? #把列表里的元素都變?yōu)閕nt
? ? index = 0
? ? for n in list:
? ? ? ? list[index] = int(n)
? ? ? ? index+=1
? ? del index,n
? ? return(list)
def trans(camera,f,P): ? #精髓 坐標(biāo)變換 這版更高級(jí)(難 XD)
? ? if camera[2]-P[2] >= 0: ? #v2.1修的主要bug在這里 從=0變成≥0 至于為什么 自己品 懶得講
? ? ? ? Q = [-int(frame/2+f*(camera[0]-P[0])-1),
? ? -int(frame/2+f*(camera[1]-P[1])-1)] ? #Q的兩個(gè)坐標(biāo)加了負(fù)號(hào) 至于為什么 自己品 懶得講
? ? else: ? #把空間直線和平面的交點(diǎn)轉(zhuǎn)化為2個(gè)平面中2直線的交點(diǎn)問題
? ? ? ? Q = [int(frame/2+f*(camera[0]-P[0])/(camera[2]-P[2])-1),
? ? int(frame/2+f*(camera[1]-P[1])/(camera[2]-P[2])-1)]
? ? return(Q)
def lines(P,Q): ? #基本就是v1.0的函數(shù)
? ? c_temp = {}
? ? if P[0] < Q[0]: ? #還是和上次一樣 這個(gè)條件和下一個(gè)其實(shí)只是步長不一樣 函數(shù)解析式是一樣的
? ? ? ? for x in range(P[0],Q[0]+1):
? ? ? ? ? ? l_temp = set()
? ? ? ? ? ? l_temp.add(int(round((P[1]-Q[1])/(P[0]-Q[0])*(x-P[0])+P[1],0)))
? ? ? ? ? ? c_temp[x] = l_temp
? ? elif P[0] > Q[0]:
? ? ? ? for x in range(P[0],Q[0]+1,-1):
? ? ? ? ? ? l_temp = set()
? ? ? ? ? ? l_temp.add(int(round((P[1]-Q[1])/(P[0]-Q[0])*(x-P[0])+P[1],0)))
? ? ? ? ? ? c_temp[x] = l_temp
? ? elif P[0] == Q[0]:
? ? ? ? if P[1] < Q[1]:
? ? ? ? ? ? c_temp[P[0]] = set(range(P[1],Q[1]))
? ? ? ? if P[1] > Q[1]:
? ? ? ? ? ? c_temp[P[0]] = set(range(P[1],Q[1],-1))
? ? return(c_temp)
def draw(coordinate): ? #可以導(dǎo)入 但是沒必要 v2.1精簡了一下
? ? x_axis = []
? ? for x in coordinate:
? ? ? ? x_axis.append(x)
? ? x_axis.sort()
? ? x_axis = tuple(range(x_axis[0],x_axis[-1]+1))
? ? del x
? ? #得到y(tǒng)從小到大的序列
? ? y_axis = []
? ? for coordinate_y in coordinate:
? ? ? ? y_axis.extend(coordinate[coordinate_y])
? ? del coordinate_y
? ? y_axis = list(set(y_axis))
? ? y_axis.sort(reverse=True)
? ? y_axis = tuple(y_axis)
? ? #繪圖
? ? for y in range(y_axis[0],y_axis[len(y_axis)-1]-1,-1): ? # y
? ? ? ? print('')
? ? ? ? print(y,'\t',end='') ? #顯示y軸坐標(biāo)
? ? ? ? former_x = 0 ? # x
? ? ? ? for x in x_axis:
? ? ? ? ? ? if y in coordinate[x]:
? ? ? ? ? ? ? ? print(' ?'*(x-former_x),end='')
? ? ? ? ? ? ? ? print('██',end='')
? ? ? ? ? ? ? ? former_x = x+1
? ? del x,former_x,y_axis
#輸入
print('''
? ? ? ?y
? ? ? ↑ ? ?z
? ? ? │ ?↗
? ? ? │ ╱
? ? ? │╱ ? ? ? ? x
――――――┼――――――→
? ? ?╱│
? ? ╱ │
? ?╱ ?│ ? ?
輸入自定義的參數(shù)
自定義視野輸入w按回車后輸入(0,180)的實(shí)數(shù) ? 默認(rèn)60度
自定義縮放輸入s按回車后輸入大于0的實(shí)數(shù) ? 默認(rèn)1
自定義長方體坐標(biāo)輸入p后按回車輸入一個(gè)點(diǎn)坐標(biāo) 后按回車輸入另一個(gè)點(diǎn)坐標(biāo)
點(diǎn)坐標(biāo)按照'x y z'輸入 空格連接 如果不是整數(shù)則會(huì)去尾變?yōu)檎麛?shù)
默認(rèn)A(-10 -20 40) G(20 10 90)
按回車確認(rèn)''')
#默認(rèn)數(shù)據(jù)
camera = [0,0,0]
width,scale = 60,1
A,G = [-20,-20,40],[20,10,90]
#自定義輸入
option = input()
while True:
? ? if option == 'w':
? ? ? ? while True:
? ? ? ? ? ? width = input('輸入視野大小 范圍為(0,180)的實(shí)數(shù) 按回車則默認(rèn)60')
? ? ? ? ? ? try:
? ? ? ? ? ? ? ? if width == '':
? ? ? ? ? ? ? ? ? ? width = 60
? ? ? ? ? ? ? ? width = int(float(width))
? ? ? ? ? ? ? ? if width <=0 or width >= 180:
? ? ? ? ? ? ? ? ? ? width = int('')
? ? ? ? ? ? ? ? break
? ? ? ? ? ? except:
? ? ? ? ? ? ? ? print('請檢查輸入內(nèi)容')
? ? ? ? option = input()
? ? if option == 's':
? ? ? ? while True:
? ? ? ? ? ? scale = input('輸入縮放大小 范圍為大于0的實(shí)數(shù) 按回車則默認(rèn)1(畫面為61x61)')
? ? ? ? ? ? try:
? ? ? ? ? ? ? ? if scale == '':
? ? ? ? ? ? ? ? ? ? scale = 1
? ? ? ? ? ? ? ? scale = float(scale)
? ? ? ? ? ? ? ? if scale <= 0:
? ? ? ? ? ? ? ? ? ? scale = int('')
? ? ? ? ? ? ? ? break
? ? ? ? ? ? except:
? ? ? ? ? ? ? ? print('請檢查輸入內(nèi)容')
? ? ? ? option = input()
? ? if option == 'p':
? ? ? ? while True:
? ? ? ? ? ? A = input()
? ? ? ? ? ? try:
? ? ? ? ? ? ? ? if len(A.split()) != 3:
? ? ? ? ? ? ? ? ? ? A = int('')
? ? ? ? ? ? ? ? A = str_int(A.split())
? ? ? ? ? ? ? ? break
? ? ? ? ? ? except:
? ? ? ? ? ? ? ? print('請檢查輸入內(nèi)容')
? ? ? ? ? ?
? ? ? ? while True:
? ? ? ? ? ? G = input()
? ? ? ? ? ? try:
? ? ? ? ? ? ? ? if len(G.split()) != 3:
? ? ? ? ? ? ? ? ? ? G = int('')
? ? ? ? ? ? ? ? G = str_int(G.split())
? ? ? ? ? ? ? ? if G == A:
? ? ? ? ? ? ? ? ? ? print('G和A不應(yīng)重合')
? ? ? ? ? ? ? ? ? ? G = int('')
? ? ? ? ? ? ? ? break
? ? ? ? ? ? except:
? ? ? ? ? ? ? ? print('請檢查輸入內(nèi)容')
? ? ? ? option = input()
? ? if option == '':
? ? ? ? break
del option
#一些別的量
frame = int(63*scale)
step = int(scale*0.5)+1
f = ((frame-2)/2)/math.tan(width/360*math.pi) ? #攝像機(jī)到等效平面的距離
#計(jì)算其余6個(gè)點(diǎn)坐標(biāo)
B,C,D = [G[0],A[1],A[2]],[G[0],G[1],A[2]],[A[0],G[1],A[2]]
E,F,H = [A[0],A[1],G[2]],[G[0],A[1],G[2]],[A[0],G[1],G[2]]
while True:
? ? coordinate = {}
? ? for temp in range(0,frame):
? ? ? ? coordinate[temp] = {frame-1,0} ? #0-62
? ? del temp
? ? coordinate[0] = set(range(0,frame))
? ? coordinate[frame-1] = set(range(0,frame))
? ? #計(jì)算對應(yīng)的二維坐標(biāo)
? ? A2,B2,C2,D2 = trans(camera,f,A),trans(camera,f,B),trans(camera,f,C),trans(camera,f,D)
? ? E2,F2,G2,H2 = trans(camera,f,E),trans(camera,f,F),trans(camera,f,G),trans(camera,f,H)
? ? #計(jì)算連線線的所有的點(diǎn)
? ? ab,bc,cd,ad = lines(A2,B2),lines(B2,C2),lines(C2,D2),lines(A2,D2)
? ? ae,bf,cg,dh = lines(A2,E2),lines(B2,F2),lines(C2,G2),lines(D2,H2)
? ? ef,fg,gh,eh = lines(E2,F2),lines(F2,G2),lines(G2,H2),lines(E2,H2)
? ? all_lines = (ab,bc,cd,ad,ae,bf,cg,dh,ef,fg,gh,eh)
? ? del A2,B2,C2,D2,E2,F2,G2,H2
? ? #把坐標(biāo)丟進(jìn)coordinate里
? ? for x in range(1,frame):
? ? ? ? for line in all_lines:
? ? ? ? ? ? if x in line.keys():
? ? ? ? ? ? ? ? coordinate[x].update(line[x])
? ? del all_lines,ab,bc,cd,ad,ae,bf,cg,dh,ef,fg,gh,eh
? ? #把y超過范圍的刪掉
? ? coordinate_temp = coordinate
? ? for x in coordinate_temp:
? ? ? ? temp = set()
? ? ? ? for y in coordinate_temp[x]:
? ? ? ? ? ? if y > frame-1 or y < 0:
? ? ? ? ? ? ? ? temp.add(y)
? ? ? ? for y in temp:
? ? ? ? ? ? coordinate[x].remove(y)
? ? del coordinate_temp,x,y,temp
? ? #畫圖
? ? draw(coordinate)
? ? print('\n當(dāng)前攝像機(jī)坐標(biāo)為',camera)
? ?
? ? #移動(dòng)攝像機(jī)
? ? print('直接輸入WASD EF控制鏡頭按默認(rèn)距離移動(dòng)')
? ? print('輸入W/A/S/D/E/F+數(shù)字 控制鏡頭按自定義距離移動(dòng)')
? ? print('直接輸入如1 2 3控制鏡頭到自定義坐標(biāo) 空格連接')
? ? print('輸入c使攝像頭回到原點(diǎn) 輸入q退出')
? ? camera_move = input()
? ? #按默認(rèn)步長移動(dòng)
? ? if camera_move == 'w':
? ? ? ? camera = [camera[0],camera[1],camera[2]+step]
? ? elif camera_move == 'a':
? ? ? ? camera = [camera[0]-step,camera[1],camera[2]]
? ? elif camera_move == 's':
? ? ? ? camera = [camera[0],camera[1],camera[2]-step]
? ? elif camera_move == 'd':
? ? ? ? camera = [camera[0]+step,camera[1],camera[2]]
? ? elif camera_move == 'e':
? ? ? ? camera = [camera[0],camera[1]+step,camera[2]]
? ? elif camera_move == 'f':
? ? ? ? camera = [camera[0],camera[1]-step,camera[2]]
? ?
? ? elif camera_move == 'c': ? #回到原點(diǎn)
? ? ? ? camera = [0,0,0]
? ? elif camera_move == 'q': ? #退出
? ? ? ? exit()
? ? elif camera_move == '': ? #防止點(diǎn)快了沒輸入就按回車導(dǎo)致的bug
? ? ? ? print('\n'*frame*2)
? ? ? ? continue
? ? #按自定義步長移動(dòng)攝像機(jī)
? ? elif camera_move[0] == 'w':
? ? ? ? try:
? ? ? ? ? ? camera = [camera[0],camera[1],camera[2]+int(camera_move[1:])]
? ? ? ? except:
? ? ? ? ? ? print('輸入字母+整數(shù)表示移動(dòng)的方向和距離')
? ? elif camera_move[0] == 'a':
? ? ? ? try:
? ? ? ? ? ? camera = [camera[0]-int(camera_move[1:]),camera[1],camera[2]]
? ? ? ? except:
? ? ? ? ? ? print('輸入字母+整數(shù)表示移動(dòng)的方向和距離')
? ? elif camera_move[0] == 's':
? ? ? ? try:
? ? ? ? ? ? camera = [camera[0],camera[1],camera[2]-int(camera_move[1:])]
? ? ? ? except:
? ? ? ? ? ? print('輸入字母+整數(shù)表示移動(dòng)的方向和距離')
? ? elif camera_move[0] == 'd':
? ? ? ? try:
? ? ? ? ? ? camera = [camera[0]+int(camera_move[1:]),camera[1],camera[2]]
? ? ? ? except:
? ? ? ? ? ? print('輸入字母+整數(shù)表示移動(dòng)的方向和距離')
? ? elif camera_move[0] == 'e':
? ? ? ? try:
? ? ? ? ? ? camera = [camera[0],camera[1]+int(camera_move[1:]),camera[2]]
? ? ? ? except:
? ? ? ? ? ? print('輸入字母+整數(shù)表示移動(dòng)的方向和距離')
? ? elif camera_move[0] == 'f':
? ? ? ? try:
? ? ? ? ? ? camera = [camera[0],camera[1]-int(camera_move[1:]),camera[2]]
? ? ? ? except:
? ? ? ? ? ? print('輸入字母+整數(shù)表示移動(dòng)的方向和距離')
? ? #按照坐標(biāo)直接移動(dòng)攝像機(jī)
? ? elif len(camera_move.split()) == 3:
? ? ? ? try:
? ? ? ? ? ? count = 0
? ? ? ? ? ? for temp in camera_move.split():
? ? ? ? ? ? ? ? camera[count] = int(temp)
? ? ? ? ? ? ? ? count+=1
? ? ? ? ? ? del temp,count
? ? ? ? except:
? ? ? ? ? ? print('按諸如 \'1 2 -3\' 輸入整數(shù)')
? ? #換很多行 "隱藏"上一張畫面
? ? print('\n'*frame*2)
