import pygame
from pygame. locals import *
import sys
import math
# 初始化Pygame
pygame. init ( )
# 设置窗口大小
width, height = 800 , 600
screen = pygame. display. set_mode ( ( width, height) )
pygame. display. set_caption ( '3D Triangle Fill with Barycentric Coordinates')
# 定义三角形的三个顶点坐标(包含z坐标)
v0 = ( 200 , 100 , 0 )
v1 = ( 400 , 500 , 0 )
v2 = ( 600 , 200 , 0 )
img= pygame. image. load ( "11.jpg" ) . convert_alpha ( )
# 定义旋转角度
angle_x = 0
angle_y = 0
angle_z = 0
rotation_speed = 0.01 # 每帧旋转的速度
def rotate_x ( vertex, angle) :
x, y, z = vertex
new_y = y * math. cos ( angle) - z * math. sin ( angle)
new_z = y * math. sin ( angle) + z * math. cos ( angle)
return x, new_y, new_z
def rotate_y ( vertex, angle) :
x, y, z = vertex
new_x = x * math. cos ( angle) + z * math. sin ( angle)
new_z = - x * math. sin ( angle) + z * math. cos ( angle)
return new_x, y, new_z
def rotate_z ( vertex, angle) :
x, y, z = vertex
new_x = x * math. cos ( angle) - y * math. sin ( angle)
new_y = x * math. sin ( angle) + y * math. cos ( angle)
return new_x, new_y, z
# 对三角形顶点进行旋转变换
def rotate_triangle ( ) :
global v0, v1, v2, angle_x, angle_y, angle_z
v0 = rotate_x ( v0, angle_x)
v1 = rotate_x ( v1, angle_x)
v2 = rotate_x ( v2, angle_x)
v0 = rotate_y ( v0, angle_y)
v1 = rotate_y ( v1, angle_y)
v2 = rotate_y ( v2, angle_y)
v0 = rotate_z ( v0, angle_z)
v1 = rotate_z ( v1, angle_z)
v2 = rotate_z ( v2, angle_z)
# 渲染三角形
def render_triangle ( v0, v1, v2) :
for x in range ( int ( min ( v0[ 0 ] , v1[ 0 ] , v2[ 0 ] ) ) , int ( max ( v0[ 0 ] , v1[ 0 ] , v2[ 0 ] ) ) ) :
for y in range ( int ( min ( v0[ 1 ] , v1[ 1 ] , v2[ 1 ] ) ) , int ( max ( v0[ 1 ] , v1[ 1 ] , v2[ 1 ] ) ) ) :
u, v, w = barycentric_coordinates ( ( x, y) , v0, v1, v2)
if u >= 0 and v >= 0 and w >= 0 :
z = u * v0[ 2 ] + v * v1[ 2 ] + w * v2[ 2 ]
screen. set_at ( ( x, y) , ( ( int ( u* 255 ) , int ( v* 255 ) , int ( w* 255 ) ) ) )
def barycentric_coordinates ( p, v0, v1, v2) :
u = ( ( v1[ 1 ] - v2[ 1 ] ) * ( p[ 0 ] - v2[ 0 ] ) + ( v2[ 0 ] - v1[ 0 ] ) * ( p[ 1 ] - v2[ 1 ] ) ) / \
( ( v1[ 1 ] - v2[ 1 ] ) * ( v0[ 0 ] - v2[ 0 ] ) + ( v2[ 0 ] - v1[ 0 ] ) * ( v0[ 1 ] - v2[ 1 ] ) )
v = ( ( v2[ 1 ] - v0[ 1 ] ) * ( p[ 0 ] - v2[ 0 ] ) + ( v0[ 0 ] - v2[ 0 ] ) * ( p[ 1 ] - v2[ 1 ] ) ) / \
( ( v1[ 1 ] - v2[ 1 ] ) * ( v0[ 0 ] - v2[ 0 ] ) + ( v2[ 0 ] - v1[ 0 ] ) * ( v0[ 1 ] - v2[ 1 ] ) )
w = 1 - u - v
return u, v, w
# 主循环
while True:
for event in pygame. event. get ( ) :
if event. type == QUIT:
pygame. quit ( )
sys. exit ( )
keys = pygame. key. get_pressed ( )
if keys[ pygame. K_UP] :
f = True
if event. type == pygame. KEYUP:
f = False
# 清空屏幕
screen. fill ( ( 0 , 0 , 0 ) )
# 旋转三角形
rotate_triangle ( )
# 渲染并填充三角形
render_triangle ( v0, v1, v2)
# 更新角度
angle_x += rotation_speed
angle_y += rotation_speed
angle_z += rotation_speed
pygame. display. flip ( )