1

我有以下程序:它的作用是读取 xyz 坐标文件并将它们存储在列表中:

J
 -2000 379 -1817 # 21
J
 -1112 379 -1791 # 16
 -1112 379 -1817 # 22
J
 -589 379 -1896 # 7
 -79 379 -1896 # 23
 -79 405 -1870 # 25
 -589 405 -1870 # 8
J

然后我获取这些数据并将其缩放到我的 800x600 屏幕显示,并添加一些变换来缩放和移动图像。

import pygame
import sys, math
from itertools import groupby
from array import *
import re

# Define some colors
black    = (   0,   0,   0)
white    = ( 255, 255, 255)
green    = (   0, 255,   0)
red      = ( 255,   0,   0)
blue     = (   0,   0, 255)
yellow   = ( 255, 255,   0)
violet   = ( 255,   0, 255)
teal     = (   0, 255, 255)
orange   = ( 255, 102,   0)#x
tan      = ( 204, 153,  51)#X
pink     = ( 255, 186, 210)#y
grey     = ( 204, 207, 188)#Y
olive    = ( 134, 148,  42)#z
gold     = ( 218, 165,  32)#Z

#define a default color
color = white

#setup angles for rotation
angle = 1
rad = angle * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)

#Scale Factor
xrat = (800/4000)
yrat = -(600/4000)
zrat = 1

# Speed in pixels per frame
x_speed = 0
y_speed = 0

#scaling of x and y
x_scale = 1
y_scale = 1

# Function to draw our stick figure
def draw_figure(screen,unique_Xs,unique_Ys):
    pygame.draw.lines(screen, color, False, draw_xy, 1)

# Setup
pygame.init()

# Set the width and height of the screen [width,height]
size=[800,600]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Computer Graphics Machine Problem 2")

#Loop until the user clicks the close button.
done = False

# Used to manage how fast the111 screen updates
clock=pygame.time.Clock()

# Hide the mouse cursor
pygame.mouse.set_visible(0)

# Speed in pixels per frame
x_speed = 0
y_speed = 0
z_speed = 0

#file reader
with open('C:\\Python33\\PIXB.DAT', 'r') as f:
    #list1 = [line.strip().split('(')[0].split() for line in f]
    list1 = [re.split(r'[(#)]+', line.strip())[0].split() for line in f]
    points = [[list(map(float, var)) for var in g] for k, g in groupby(list1, key=lambda x: len(x)==1) if k != 1]

# -------- Main Program Loop -----------
while done == False:
    # ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENT
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done = True # Flag that we are done so we exit this loop
            # User pressed down on a key

        elif event.type == pygame.KEYDOWN | event.type == pygame.KEYUP:
            # Figure out if it was an arrow key. If so
            # adjust speed.
            if event.key == pygame.K_LEFT:
                x_speed -= 30
                color = green
            elif event.key == pygame.K_RIGHT:
                x_speed += 30
                color = blue
            elif event.key == pygame.K_UP:
                y_speed -= 30
                color = red
            elif event.key == pygame.K_DOWN:
                y_speed += 30
                color = yellow
            elif event.key == pygame.K_MINUS:
                y_scale -= (1/10)
                x_scale -= (1/10)
                color = teal
            elif event.key == pygame.K_EQUALS:
                y_scale += (1/10)
                x_scale += (1/10)
                color = violet

            if event.key == pygame.K_x:
                color = orange
            elif event.key == pygame.K_a:
                color = tan
            elif event.key == pygame.K_y:
                color = pink
            elif event.key == pygame.K_b:
                color = grey
            elif event.key == pygame.K_z:
                color = olive
            elif event.key == pygame.K_c:
                color = gold

    for point in points:

        drawPoints_xyz = [[l[0], l[1], l[2]] for l in point]
        drawPoints_xy = [[l[0], l[1]] for l in point]

        #split draw points into two seperate list called Xs, Ys
        Xs, Ys, Zs = zip(*drawPoints_xyz)
        Xs, Ys = zip(*drawPoints_xy)

        #rotation matrix for rotating Z
        rot_Z = Ys * cosa + Xs * -sina
        rot_z = Ys * sina + Xs * cosa

        #apply the scale factor to the x points to fit the screen
        unique_Xs = []
        [unique_Xs.append(((2000+((val)*x_scale))*xrat)) for val in Xs]

        #apply the scale factor to the y points to fit the screen
        unique_Ys = []
        [unique_Ys.append((-(2000+-(val*y_scale))*yrat)) for val in Ys]

        unique_Zs = []
        [unique_Zs.append(val) for val in Zs]

        #array to setup movements
        movedX = []
        movedY = []
        movedZ = []

        #move by the points in x by x_speed
        for x in unique_Xs:
            movedX+=[(x+x_speed)]
        #move by the points in y by y_speed
        for y in unique_Ys:
            movedY+=[(y+y_speed)]
        #move by the points in z by z_speed
        for z in unique_Zs:
            movedZ+=[(z+z_speed)]


        draw_figure(screen,movedX,movedY)


    # Go ahead and update the screen with what we've drawn.
    pygame.display.flip()
    screen.fill(black)
    clock.tick(10)


    # above this, or they will be erased with this command.
pygame.quit()

我的问题是我也试图在这里进行旋转,所以我可以沿所有轴旋转,但是当我尝试将我的 x 坐标乘以我的旋转矩阵时,我得到了错误:

TypeError: can't multiply sequence by non-int of type 'float'

在这条线上

rot_Z = Ys * cosa + Xs * -sina

我认为这是因为我将一个元组乘以一个浮点数,但如果是这种情况,我不知道如何将我的列表 Xs 和 Ys 从元组转换为浮点数,这样我就可以乘以我的旋转,从而旋转我的图纸。

4

1 回答 1

0

您可以像这样将一个元组与一个浮点数相乘:

new_tuple = tuple(multiplier*x for x in previous_tuple)

在你的情况下,这将是:

rot_Z = tuple(cosa*x for x in Ys) + tuple(-sina*x for x in Xs)
于 2013-11-04T19:09:13.020 回答