3D python v1.0 v1.1 v2.0
通過print()函數(shù)繪制3d圖像
v1.0

#立方體
#8個(gè)頂點(diǎn)的坐標(biāo)
A,B,C,D,E,F,G,H = [-7,-3,0],[7,-3,0],[7,3,0],[-7,3,0],[-7,-3,20],[7,-3,20],[7,3,20],[-7,3,20]
#縮放
temp = (A,B,C,D,E,F,G,H)
temp_size = float(input())
for temp_s in temp:
? ? for temp_co in temp_s:
? ? ? ? temp_s[temp_s.index(temp_co)] = temp_co*temp_size
del temp_s,temp,temp_co,temp_size
#3維坐標(biāo)轉(zhuǎn)為2維 透視用的是占視野的比例 視野120°
#攝像機(jī)(0, 0, 10x3?) 約等于(0, 0, -17.321)
def trans(spot):
? ? spot[0] = int( spot[0] * 30 / ((3**0.5)* spot[2] +30) )
? ? spot[1] = int( spot[1] * 30 / ((3**0.5)* spot[2] +30) )
? ? spot.pop()
? ? return(spot)
A,B,C,D,E,F,G,H = trans(A),trans(B),trans(C),trans(D),trans(E),trans(F),trans(G),trans(H)
#計(jì)算12條棱分別經(jīng)過的點(diǎn)坐標(biāo) (點(diǎn)斜式表示的直線方程 外加斜率不存在討論)
def lines(P,Q):
? ? c_temp = {}
? ? if P[0] < Q[0]:
? ? ? ? for x in range(P[0],Q[0]+1):
? ? ? ? ? ? l_temp = []
? ? ? ? ? ? l_temp.append(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 = []
? ? ? ? ? ? l_temp.append(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]] = list(range(P[1],Q[1]))
? ? ? ? if P[1] > Q[1]:
? ? ? ? ? ? c_temp[P[0]] = list(range(P[1],Q[1],-1))
? ? return(c_temp)
ab,bc,cd,ad = lines(A,B),lines(B,C),lines(C,D),lines(A,D)
ae,bf,cg,dh = lines(A,E),lines(B,F),lines(C,G),lines(D,H)
ef,fg,gh,eh = lines(E,F),lines(F,G),lines(G,H),lines(E,H)
all_lines = (ab,bc,cd,ad,ae,bf,cg,dh,ef,fg,gh,eh)
#所有 x 的值
coordinate,x_all_lines = {},[]
for line in all_lines:
? ? for x in line:
? ? ? ? x_all_lines.append(x)
? ? ? ? coordinate[x] = []
x_all_lines = list(set(x_all_lines))
x_all_lines.sort
x_all_lines = tuple(x_all_lines)
del x,line
#合并12條棱的坐標(biāo) (感覺這可能才是難點(diǎn)? 雖然代碼挺短)
for x in x_all_lines:
? ? for line in all_lines:
? ? ? ? temp = coordinate[x]
? ? ? ? if x in line.keys():
? ? ? ? ? ? temp.extend(line[x])
? ? ? ? coordinate[x] = temp
print(coordinate)
#畫畫 代碼參考另一個(gè)程序 本來可以導(dǎo)入的 但是原來那個(gè)就不是為了當(dāng)模塊/函數(shù)用的
#所以...
#Ctrl+C Ctrl+V 稍微刪點(diǎn)沒用的東西
def draw(coordinate):
? ? x_axis = []
? ? for x in coordinate:
? ? ? ? x_axis.append(x)
? ? x_axis.sort()
? ? if len(x_axis) < len(range(x_axis[0],x_axis[-1]+1)):
? ? ? ? for x in range(x_axis[0],x_axis[-1]+1):
? ? ? ? ? ? try:
? ? ? ? ? ? ? ? coordinate[x] = coordinate[x]
? ? ? ? ? ? except:
? ? ? ? ? ? ? ? coordinate[x] = []
? ? x_axis = tuple(range(x_axis[0],x_axis[-1]+1))
? ? del x
? ? 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):
? ? ? ? print('')
? ? ? ? former_x = 0
? ? ? ? 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
? ? print('')
? ? for x in coordinate:
? ? ? ? for y in coordinate[x]:
? ? ? ? ? ? print('(%d,%d)' % (x+1,y),end=' ')
draw (coordinate)

---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
v2.0? ?一個(gè)讓我很興奮的東西


#介紹
print('3d v2.0')
print('1 確定了畫面分辨率 標(biāo)了界限')
print('2 可以平移攝像機(jī)(巨大飛躍)')
print('3 很多數(shù)值都可以方便的調(diào)了 比如視野角度')
print('4 代碼相對更整潔了 吧')
#函數(shù)區(qū)
import math
def str_int(list): ? #把列表里的元素都變?yōu)閕nt
? ? index = 0
? ? for n in list:
? ? ? ? list[index] = int(n)
? ? ? ? index+=1
? ? return(list)
def trans(camera,f,P): ? #精髓 坐標(biāo)變換 這版更高級(jí)(難 XD)
? ? if camera[2]-P[2] == 0:
? ? ? ? Q = [int(frame/2+f*(camera[0]-P[0])-1),
? ? int(frame/2+f*(camera[1]-P[1])-1)]
? ? 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): ? #基本就是上一個(gè)版的函數(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,val=''): ? #可以導(dǎo)入 但是沒必要
? ? #不需要的功能 說不需要也需要 可以縮 但沒要 反正能用 沒這段還跑不起來 因?yàn)槎x了變量
? ? #確保x連續(xù) 如果缺失了x值則自動(dòng)填補(bǔ)
? ? x_axis = []
? ? for x in coordinate:
? ? ? ? x_axis.append(x)
? ? x_axis.sort()
? ? if len(x_axis) < len(range(x_axis[0],x_axis[-1]+1)):
? ? ? ? for x in range(x_axis[0],x_axis[-1]+1):
? ? ? ? ? ? try:
? ? ? ? ? ? ? ? coordinate[x] = coordinate[x]
? ? ? ? ? ? except:
? ? ? ? ? ? ? ? coordinate[x] = []
? ? 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
? ? #顯示所有點(diǎn)的坐標(biāo)(其實(shí)沒啥用 在這里 但是 何必刪呢)
? ? if val == 1:
? ? ? ? print('')
? ? ? ? for x in coordinate:
? ? ? ? ? ? for y in coordinate[x]:
? ? ? ? ? ? ? ? print('(%d,%d)' % (x+1,y),end=' ')
#啊啊啊啊啊
print('''
? ? ? ?y
? ? ? ↑ ? ?z
? ? ? │ ?↗
? ? ? │ ╱
? ? ? │╱ ? ? ? ? x
――――――┼――――――→
? ? ?╱│
? ? ╱ │
? ?╱ ?│ ? ?''')
camera = [0,0,0]
width = 60
scale = float(input('輸入1 則 63x63\n')) ? #邊框縮放大小
frame = int(63*scale)
step = int(scale*5)
f = ((frame-2)/2)/math.tan(width/360*math.pi) ? #攝像機(jī)到等效平面的距離
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))
? ? #輸入兩點(diǎn)坐標(biāo)
? ? #A = input()
? ? A = '-20 -20 52'
? ? if len(A.split()) != 3:
? ? ? ? print('3個(gè)數(shù)')
? ? ? ? exit()
? ? #G = input()
? ? G = '20 20 84'
? ? if len(G.split()) != 3:
? ? ? ? print('3個(gè)數(shù)')
? ? ? ? exit()
? ? if A == G:
? ? ? ? print('= x')
? ? ? ? exit()
? ? A,G = str_int(A.split()),str_int(G.split())
? ? #計(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]]
? ? #計(jì)算對應(yīng)的二維坐標(biāo)
? ? A,B,C,D = trans(camera,f,A),trans(camera,f,B),trans(camera,f,C),trans(camera,f,D)
? ? E,F,G,H = trans(camera,f,E),trans(camera,f,F),trans(camera,f,G),trans(camera,f,H)
? ? #計(jì)算連線線的所有的點(diǎn)
? ? ab,bc,cd,ad = lines(A,B),lines(B,C),lines(C,D),lines(A,D)
? ? ae,bf,cg,dh = lines(A,E),lines(B,F),lines(C,G),lines(D,H)
? ? ef,fg,gh,eh = lines(E,F),lines(F,G),lines(G,H),lines(E,H)
? ? all_lines = (ab,bc,cd,ad,ae,bf,cg,dh,ef,fg,gh,eh)
? ? #刪掉畫面外的點(diǎn) 根據(jù) x 的值
? ? for line in all_lines:
? ? ? ? key = list(line.keys())
? ? ? ? for x in key:
? ? ? ? ? ? if x > frame-1 or x < 1:
? ? ? ? ? ? ? ? del line[x]
? ? #把坐標(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])
? ?
? ? #把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
? ? #畫圖
? ? draw(coordinate)
? ? print('')
? ?
? ? #移動(dòng)攝像機(jī)
? ? camera_move = input()
? ? if len(camera_move) == 1:
? ? ? ? if camera_move == 'w':
? ? ? ? ? ? camera = [camera[0],camera[1],camera[2]+step]
? ? ? ? if camera_move == 'a':
? ? ? ? ? ? camera = [camera[0]-step,camera[1],camera[2]]
? ? ? ? if camera_move == 's':
? ? ? ? ? ? camera = [camera[0],camera[1],camera[2]-step]
? ? ? ? if camera_move == 'd':
? ? ? ? ? ? camera = [camera[0]+step,camera[1],camera[2]]
? ? ? ? if camera_move == 'u':
? ? ? ? ? ? camera = [camera[0],camera[1]+step,camera[2]]
? ? ? ? if camera_move == 'h':
? ? ? ? ? ? camera = [camera[0],camera[1]-step,camera[2]]
? ? ? ? if camera_move == 'c':
? ? ? ? ? ? camera = [0,0,0]
? ? print('\n'*frame*2)

