# Rotation matrix defcalculateX(x, y, z): return x * cosB * cosC \ + y * (sinA * sinB * cosC - cosA * sinC) \ + z * (cosA * sinB * cosC + sinA * sinC)
defcalculateY(x, y, z): return x * cosB * sinC \ + y * (sinA * sinB * sinC + cosA * cosC) \ + z * (cosA * sinB * sinC - sinA * cosC) defcalculateZ(x, y, z): return - x * sinB + y * sinA * cosB + z * cosA * cosB
# Project 3D cube on 2D screen defproject(_x, _y, _z, char): # Apply rotation transformations x = calculateX(_x, _y, _z) y = calculateY(_x, _y, _z) z = calculateZ(_x, _y, _z) + distance_to_cube # Perspective projection z_ratio = distance_to_screen/z xp = round(width/2 + x*2*z_ratio) # x*2 becasue Letterspacing is smaller than Linespacing yp = round(height/2 + y*z_ratio)
# Store the points nearest to us if (0<=xp<width and0<=yp<height and z_ratio>buffer[yp][xp]): buffer[yp][xp] = z_ratio charbuffer[yp][xp] = char if __name__ == "__main__": print("\x1b[2J")
# Initialize buffers to store projected points buffer = [[0]*width for _ inrange(height)] charbuffer = [[' ']*width for _ inrange(height)]
# Project each point of the cube onto the screen for x inrange(-cubeWidth, cubeWidth+1): for y inrange(-cubeWidth, cubeWidth+1): project(x, y, -cubeWidth, "#") project(x, y, cubeWidth, "%") project(x, cubeWidth, y, "&") project(x, -cubeWidth, y, "@") project(cubeWidth, x, y, "*") project(-cubeWidth, x, y, "+") # Clear the screen and print the current state of the 2D projection print("\x1b[H") for row in charbuffer: for char in row: print(char, end='') print()
# Increment rotation angles for the next frame A += 0.05 B += 0.07 C += 0.02