Pregunta

I am wanting to use the baseTriangle and baseSquare variables in my for loops in the rotateshape(), but when they are put in, the funnction seems to alter them, meaning that they get bigger with every loop. not sure why it does this, please help!!!

    #! /usr/bin/env python

    import Image, ImageDraw
    import math

    # functions

    def rotateShape(shapeXCoordinates, shapeYCoordinates, baseXCoordinates, baseYCoordinates):

        # Written by: some guy who had to do this once and thought it better to share rather than let other people suffer through the monotony

        # This function below takes a shape and rotates, scales and translates it so that the first two coordinates are equal to the baseCoordinates

        # Make sure that the distance between the first two shape coordinates is 1 and that they lie on the x-axis



        # Find the dx, dy and the length of the baseCoordinates pair
        #print 'Base coordinates: ' + str(zip(baseXCoordinates, baseYCoordinates))
        dx = baseXCoordinates[1] - baseXCoordinates[0]
        #print 'dx: ' + str(dx)
        dy = baseYCoordinates[1] - baseYCoordinates[0]
        #print 'dy: ' + str(dy)
        magnitude = math.sqrt(dx**2+dy**2)
        #print 'magnitude: ' + str(magnitude)

        #print 'Start: ' + str(zip(shapeXCoordinates, shapeYCoordinates))

        # Rotate the matrix
        a = dx/magnitude
        b = -dy/magnitude
        c = dy/magnitude
        d = dx/magnitude

        for i in range(0,len(shapeXCoordinates)):

            # Find the new x value
            newX = a*shapeXCoordinates[i]+b*shapeYCoordinates[i]

            # Find the new y value
            newY = c*shapeXCoordinates[i]+d*shapeYCoordinates[i]

            # Replace the old with the new
            shapeXCoordinates[i] = newX
            shapeYCoordinates[i] = newY

        #print 'After rotate: ' + str(zip(shapeXCoordinates, shapeYCoordinates))

        # Scale the matrix
        for i in range(0,len(shapeXCoordinates)):

            shapeXCoordinates[i] = shapeXCoordinates[i]*magnitude
            shapeYCoordinates[i] = shapeYCoordinates[i]*magnitude

        #print 'After scale: ' + str(zip(shapeXCoordinates, shapeYCoordinates))

        # Translate the matrix
        for i in range(0,len(shapeXCoordinates)):

            shapeXCoordinates[i] = shapeXCoordinates[i]+baseXCoordinates[0]
            shapeYCoordinates[i] = shapeYCoordinates[i]+baseYCoordinates[0]

        #print 'After translate: ' + str(zip(shapeXCoordinates, shapeYCoordinates))
        return (shapeXCoordinates, shapeYCoordinates)

    # create a bitmap

    img = Image.new('RGB', (3840, 2160))
    draw = ImageDraw.Draw(img)

    # setting up the varibales

    # insert angle

    angle = 30
    angle_2 = 90 - angle
    a = math.sin(angle_2) * 1

    # working out the Y of the triangle

    y = math.sin(angle) * a

    # working out the X of Y

    x = math.tan(angle)/y

    baseTriangle_X = [0, 1, x]
    baseTriangle_Y = [0, 0, y]

    baseSquare_X = [0, 1, 1, 0]
    baseSquare_Y = [0, 0, 1, 1]

    startPosition_X = [1800, 2200] # flipped numbers as bitmap counts from the top left so that tree is created downwards
    startPosition_Y = [0, 0]

    # set number of iterations

    numberOfIterations = 10

    # set colour

    redStart = 255
    greenStart = 253
    blueStart = 208

    redEnd = 228
    greenEnd = 82
    blueEnd = 0

    # colour change

    redChange =(redEnd - redStart)/numberOfIterations
    greenChange =(greenEnd - greenStart)/numberOfIterations
    blueChange =(blueEnd - blueStart)/numberOfIterations

    # set up the list of squares to make (fill with the start position)

    squaresToMake_X = []
    squaresToMake_Y = []

    squaresToMake_X.extend(startPosition_X)
    squaresToMake_Y.extend(startPosition_Y)

    # set up the list of triangles

    trianglesToMake_X = []
    trianglesToMake_Y = []

    # creating the tree

    print '//////////////////////////////'
    print '//     //     //     //     //'
    print '//// //// ////// ////// //////'
    print '//// //// //////     //     //'
    print '//// //// ////// ////// //////'
    print '//// //// //////     //     //'
    print '//////////////////////////////'

    # background colour

    draw.rectangle((0,0,3839,2759), fill=(220, 255, 250))

    for i in xrange(0, numberOfIterations):

        redCurrent =  redStart + redChange  * i
        greenCurrent =  greenStart + greenChange  * i
        blueCurrent =  blueStart + blueChange  * i

        # making squares

        for j in xrange(0, len(squaresToMake_X)/2):

            print 'Iteration ' + str(i) + ' of ' + str(numberOfIterations) + '. Square ' + str(j) + ' of ' +  str(len(squaresToMake_X)/2)
            k = j * 2

            newVertices_X, newVertices_Y = rotateShape([0, 1, 1, 0], [0, 0, 1, 1], squaresToMake_X[k:k+2], squaresToMake_Y[k:k+2])

            # merge x and y
            combinedVertices = zip(newVertices_X, newVertices_Y) 

            # draw 
            #print 'Drawing square:'
            #print combinedVertices
            draw.polygon(combinedVertices, fill = (redCurrent, greenCurrent, blueCurrent))

            trianglesToMake_X.extend([newVertices_X[3], newVertices_X[2]])
            trianglesToMake_Y.extend([newVertices_Y[3], newVertices_Y[2]])

            #print 'Triangles to make:'
            #print zip(trianglesToMake_X, trianglesToMake_Y)

        squaresToMake_X = []
        squaresToMake_Y = []

        # making triangles

        for j in xrange(0, len(trianglesToMake_X)/2):

            print 'Iteration ' + str(i) + ' of ' + str(numberOfIterations) + '. Triangle ' + str(j) + ' of ' +  str(len(trianglesToMake_X)/2)
            k = j * 2
            newVertices_X, newVertices_Y = rotateShape([0, 1, 0.5], [0, 0, 0.5], trianglesToMake_X[k:k+2], trianglesToMake_Y[k:k+2])

            # merge x and y
            combinedVertices = zip(newVertices_X, newVertices_Y)

            # draw
            #print 'Drawing triangle:'
            #print combinedVertices
            draw.polygon(combinedVertices, fill = (redCurrent, greenCurrent, blueCurrent))

            squaresToMake_X.extend([newVertices_X[0], newVertices_X[2], newVertices_X[2], newVertices_X[1]])
            squaresToMake_Y.extend([newVertices_Y[0], newVertices_Y[2], newVertices_Y[2], newVertices_Y[1]])

            #print 'Squares to make:'
            #print zip(squaresToMake_X, squaresToMake_Y)

        trianglesToMake_X = []
        trianglesToMake_Y = []


        print '----------'

    img2=img.rotate(180)
    img2.show()
¿Fue útil?

Solución

list objects are mutable, so when you pass them into a function, a reference to the original list is passed, rather than a copy. Therefore when you modify the list, such as with shapeXCoordinates[i] = newX, you're modifying the original list at the same time.

If you only want modifications to stay local to the function, without changing the original, you need to make a copy of the list first:

shapeX = shapeXCoordinates[:]

Then reference shapeX everywhere in the function, rather than shapeXCoordinates.

Obviously name the variables however makes sense to you.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top