欢迎光临散文网 会员登陆 & 注册

3D python v1.0 v1.1 v2.0

2022-09-11 23:20 作者:ICE27182  | 我要投稿

通过print()函数绘制3d图像



v1.0

v1.0 信不信由你 这是个3D图形 效果很差罢了

#立方体


#8个顶点的坐标

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维坐标转为2维 透视用的是占视野的比例 视野120°

#摄像机(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)


#计算12条棱分别经过的点坐标 (点斜式表示的直线方程 外加斜率不存在讨论)

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条棱的坐标 (感觉这可能才是难点? 虽然代码挺短)

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)


#画画 代码参考另一个程序 本来可以导入的 但是原来那个就不是为了当模块/函数用的

#所以...

#Ctrl+C Ctrl+V 稍微删点没用的东西

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)

v1.0代码 其实本来想的是这是0.1 但是 毕竟有成果了吧 所以 1.0

---------------------------------------------------------------------------------

---------------------------------------------------------------------------------




v2.0   一个让我很兴奋的东西

v2.0 效果图也许看起来一般 但是 实际还是很不错的 应该吧


#介绍

print('3d v2.0')

print('1 确定了画面分辨率 标了界限')

print('2 可以平移摄像机(巨大飞跃)')

print('3 很多数值都可以方便的调了 比如视野角度')

print('4 代码相对更整洁了 吧')


#函数区

import math

def str_int(list):   #把列表里的元素都变为int

    index = 0

    for n in list:

        list[index] = int(n)

        index+=1

    return(list)


def trans(camera,f,P):   #精髓 坐标变换 这版更高级(难 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:   #把空间直线和平面的交点转化为2个平面中2直线的交点问题

        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):   #基本就是上一个版的函数

    c_temp = {}

    if P[0] < Q[0]:   #还是和上次一样 这个条件和下一个其实只是步长不一样 函数解析式是一样的

        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=''):   #可以导入 但是没必要

    #不需要的功能 说不需要也需要 可以缩 但没要 反正能用 没这段还跑不起来 因为定义了变量

    #确保x连续 如果缺失了x值则自动填补

    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从小到大的序列

    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轴坐标

       

        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


    #显示所有点的坐标(其实没啥用 在这里 但是 何必删呢)

    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)   #摄像机到等效平面的距离


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))


    #输入两点坐标

    #A = input()

    A = '-20 -20 52'

    if len(A.split()) != 3:

        print('3个数')

        exit()


    #G = input()

    G = '20 20 84'

    if len(G.split()) != 3:

        print('3个数')

        exit()

    if A == G:

        print('= x')

        exit()


    A,G = str_int(A.split()),str_int(G.split())

    #计算其余6个点坐标

    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]]


    #计算对应的二维坐标

    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)


    #计算连线线的所有的点

    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 的值

    for line in all_lines:

        key = list(line.keys())

        for x in key:

            if x > frame-1 or x < 1:

                del line[x]


    #把坐标丢进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('')

   

    #移动摄像机

    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)

v2.0
v2.0 Who's the good code? U are the GOOOOD code


3D python v1.0 v1.1 v2.0的评论 (共 条)

分享到微博请遵守国家法律