Sunrise, Motion & Blending Colors

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • wasp
    New Member
    • Nov 2012
    • 1

    Sunrise, Motion & Blending Colors

    Using the code below I need to make a movie of a new function Sunrise it should: (A) Cause the sun to come up from behind the horizon up into the sky. The horizon line is a black line at the common edge of the sky and the ground.
    (B) As the sun comes up, the sky must change from black to cyan and the ground from dark gray to orange. It should be 320x240 but should be written so the size of the canvas is a variable.

    I can only make the Canvas, other wise I'm lost. Any contributions, ideas would be helpful. Thank You!

    Code:
    import time
    
    def INT(N):
        return int(round(N))
    
    def Interpolate (N0,N1,T=0.5):
        return (N1 - N0) * float(T) + N0
        
    def InterpInt (N0,N1,T=0.5):
        return INT(Interpolate(N0,N1,T))
        
    
    def Parabola (N0,N1,N2,T=0.5):
        A = +2.0*N0 - 4.0*N1 + 2.0*N2
        B = -3.0*N0 + 4.0*N1 - N2
        C = N0
        return (A * T * T) + (B * T) + C
    
    def ParabolaInt (N0,N1,N2,T=0.5):
        return INT(Parabola(N0,N1,N2,T))
    
    
    def BlendPoints2D(P0,P1,T=0.5):
        X = InterpInt(P0[0],P1[0],T)
        Y = InterpInt(P0[1],P1[1],T)
        return [X,Y]
        
    
    def BlendPoints3D(P0,P1,T=0.5):
        X = InterpInt(P0[0],P1[0],T)
        Y = InterpInt(P0[1],P1[1],T)
        Z = InterpInt(P0[2],P1[2],T)
        return [X,Y,Z]
        
    
    def BlendColor(C0,C1,T=0.5):
        R = InterpInt(C0.getRed(),   C1.getRed(),   T)
        G = InterpInt(C0.getGreen(), C1.getGreen(), T)
        B = InterpInt(C0.getBlue(),  C1.getBlue(),  T)
        return makeColor(R,G,B)
    
    #--------------------------------------------------
    
    def BlendParabola2D(P0,P1,P2,T=0.5):
        X = ParabolaInt(P0[0],P1[0],P2[0],T)
        Y = ParabolaInt(P0[1],P1[1],P2[1],T)
        return [X,Y]
        
    
    def BlendParabola3D(P0,P1,P2,T=0.5):
        X = ParabolaInt(P0[0],P1[0],P2[0],T)
        Y = ParabolaInt(P0[1],P1[1],P2[1],T)
        Z = ParabolaInt(P0[2],P1[2],P2[2],T)
        return [X,Y,Z]
    
    #--------------------------------------------------
    
    def BlendParabolaColor(C0,C1,C2,T=0.5):
        R = ParabolaInt(C0.getRed(),   C1.getRed(),   C2.getRed(),   T)
        G = ParabolaInt(C0.getGreen(), C1.getGreen(), C2.getGreen(), T)
        B = ParabolaInt(C0.getBlue(),  C1.getBlue(),  C2.getBlue(),  T)
        return makeColor(R,G,B)
    
        
    def addCircleFilled (Canvas, Xc,Yc,R,NewColor=black):
        addOvalFilled(Canvas,INT(Xc-R),INT(Yc-R),INT(2*R+1),INT(2*R+1),NewColor)
        return
    
            
    def addEllipseFilled (Canvas, Xc,Yc,Rx,Ry,NewColor=black):
        addOvalFilled(Canvas,INT(Xc-Rx),INT(Yc-Ry),INT(2*Rx+1),INT(2*Ry+1),NewColor)
        return
        
    #--------------------------------------------------
    # These routines all use 2D points as arguments
    # instead of explicit X and Y values, while again
    # keeping in the same style as the built-in JES
    # routines.  All routines in this category start
    # with the prefix "plot".  Some directly map onto
    # JES routines, others implement new funtionality
    # (such as triangles and polygons).
    #--------------------------------------------------
    
    def plotLine (Canvas,P,Q,NewColor=black):
        addLine(Canvas,INT(P[0]),INT(P[1]),INT(Q[0]),INT(Q[1]),NewColor)
        return
    
            
    def plotRect (Canvas,P,Q,NewColor=black):
        addRect(Canvas,INT(P[0]),INT(P[1]),INT(Q[0]-P[0]+1),INT(Q[1]-P[1]+1),NewColor)
        return
        
    
    def plotRectFilled (Canvas,P,Q,NewColor=black):
        addRectFilled(Canvas,INT(P[0]),INT(P[1]),INT(Q[0]-P[0]+1),INT(Q[1]-P[1]+1),NewColor)
        return
    
    
    def plotOval (Canvas,P,Q,NewColor=black):
        addOval(Canvas,INT(P[0]),INT(P[1]),INT(Q[0]-P[0]+1),INT(Q[1]-P[1]+1),NewColor)
        return
        
    
    def plotOvalFilled (Canvas,P,Q,NewColor=black):
        addOvalFilled(Canvas,INT(P[0]),INT(P[1]),INT(Q[0]-P[0]+1),INT(Q[1]-P[1]+1),NewColor)
        return
        
    
    def plotCircleFilled (Canvas,Center,Radius,NewColor=black):
        addCircleFilled(Canvas,Center[0],Center[1],Radius,NewColor)
        return
        
    
    def plotTriangle(Canvas,P,Q,R,NewColor=black):
        plotLine(Canvas,P,Q,NewColor)
        plotLine(Canvas,Q,R,NewColor)
        plotLine(Canvas,R,P,NewColor)
        return
        
    
    def plotCenteredTriangle(Canvas,P,Radius,NewColor=black):                       
        Offset = sqrt(3)/2.0 * Radius
        P0 = [P[0], P[1]-Offset]
        P1 = [P[0]+Offset,P[1]+Radius/2.0]
        P2 = [P[0]-Offset,P[1]+Radius/2.0]
        plotTriangle(Canvas,P0,P1,P2,NewColor)
        return
        
    
    def plotCenteredPolygon(Canvas,P,Radius,Sides,NewColor=black):
        Step = 2 * pi / Sides
        Angle = 0.0
        Last = [P[0] + Radius, P[1]]
        for I in range(Sides):
            Angle = Angle + Step
            Next  = [P[0] + Radius * cos(Angle), P[1] - Radius * sin(Angle)]
            plotLine(Canvas, Last, Next, NewColor)
            Last  = Next
        return
    
    
    Origin = [0,0]    # Global, 2D position on screen
    
    
    def Ortho(P3D):
    #    Angle = 30.0 * pi / 180.0
        X = P3D[0]
        Y = P3D[1]
        Z = P3D[2]
        NewX = X + Z * 0.8660254
        NewY = -(Y + Z * 0.5)
        return [NewX,NewY]
        
    
    def add3D (P3D,Q3D):
        return [P3D[0]+Q3D[0],P3D[1]+Q3D[1],P3D[2]+Q3D[2]]
        
    
    
    def add2D (P2D,Q2D):
        return [P2D[0]+Q2D[0],P2D[1]+Q2D[1]]
    
    #--------------------------------------------------
        
    def SetOrigin (X,Y):
        global Origin
        Origin = [X,Y]
        return
        
    
    def Line3D (Canvas,P3D,Q3D,NewColor=black):
        global Origin
        plotLine(Canvas,add2D(Origin,Ortho(P3D)), add2D(Origin,Ortho(Q3D)), NewColor)
        return
       
        
    def Axes (Canvas,Size,Separation,Tic=5):
        Line3D(Canvas,[-Size,0,0],[+Size,0,0])
        Line3D(Canvas,[0,-Size,0],[0,+Size,0])
        Line3D(Canvas,[0,0,-Size],[0,0,+Size])
        N = 0
        while (N <= Size):
            Line3D(Canvas,[+N,0,-Tic],[+N,0,+Tic])
            Line3D(Canvas,[-N,0,-Tic],[-N,0,+Tic])
            Line3D(Canvas,[0,+N,-Tic],[0,+N,+Tic])
            Line3D(Canvas,[0,-N,-Tic],[0,-N,+Tic])
            Line3D(Canvas,[-Tic,0,+N],[+Tic,0,+N])
            Line3D(Canvas,[-Tic,0,-N],[+Tic,0,-N])
            N = N + Separation
        return
        
    
    def addCircleXY (Canvas, Center, Radius, NewColor=black):
        Steps = 60
        StepAngle = 2.0 * pi / Steps
        Last = [Center[0]+Radius, Center[1], Center[2]]
        for I in range(Steps):
            Angle = (I+1) * StepAngle
            X = Radius * cos(Angle)
            Y = Radius * sin(Angle)
            Current = [Center[0]+X,Center[1]+Y,Center[2]]
            Line3D(Canvas, Last, Current, NewColor)
            Last = Current
        return
    
    
    def addCircleXZ (Canvas, Center, Radius, NewColor=black):
        Steps = 60
        StepAngle = 2.0 * pi / Steps
        Last = [Center[0]+Radius, Center[1], Center[2]]
        for I in range(Steps):
            Angle = (I+1) * StepAngle
            X = Radius * cos(Angle)
            Y = Radius * sin(Angle)
            Current = [Center[0]+X,Center[1],Center[2]+Y]
            Line3D(Canvas, Last, Current, NewColor)
            Last = Current
        return
        
    
    
    def addCircleYZ (Canvas, Center, Radius, NewColor=black):
        Steps = 60
        StepAngle = 2.0 * pi / Steps
        Last = [Center[0], Center[1]+Radius, Center[2]]
        for I in range(Steps):
            Angle = (I+1) * StepAngle
            X = Radius * cos(Angle)
            Y = Radius * sin(Angle)
            Current = [Center[0],Center[1]+X,Center[2]+Y]
            Line3D(Canvas, Last, Current, NewColor)
            Last = Current
        return
    
    
    def addSimpleSphere (Canvas, Center, Radius, NewColor=black):
        addCircleXY(Canvas, Center, Radius, NewColor)
        addCircleXZ(Canvas, Center, Radius, NewColor)
        addCircleYZ(Canvas, Center, Radius, NewColor)        
        return
    
    
    def addSphere (Canvas, Center, Radius, NewColor=black):
        Angle = -90.0
        while (Angle <= 90.0):
            Radians = Angle / 180.0 * pi
            NewRadius    = Radius * cos(Radians)
            NewOffset    = Radius * sin(Radians)   
            NewCenter    = add3D(Center, [NewOffset,0,0])
            addCircleYZ(Canvas, NewCenter, NewRadius, NewColor)
            NewCenter    = add3D(Center, [0,NewOffset,0])
            addCircleXZ(Canvas, NewCenter, NewRadius, NewColor)
            NewCenter    = add3D(Center, [0,0,NewOffset])
            addCircleXY(Canvas, NewCenter, NewRadius, NewColor)
            Angle = Angle + 15.0
        return
    
    
    def BounceSpheres():
        Canvas = makeEmptyPicture(640,480)
        SetOrigin(320,240)
        
        Radius = 30         # Radius of sphere
        Size   = 100        # Size of cube
        Center = [5,7,-3]   # Original center of sphere
        DeltaX = 3          # Change in X per step
        DeltaY = 7          # Change in X per step
        DeltaZ = 5          # Change in X per step
        Trails = []         # List of previous centers
        
        while (True):
            # Clear previous image
            setAllPixelsToAColor(Canvas,white)
            
            # Paint back "wall" of the cube
            Line3D(Canvas,[-Size,+Size,+Size],[+Size,+Size,+Size],gray)
            Line3D(Canvas,[-Size,-Size,+Size],[+Size,-Size,+Size],gray)
            Line3D(Canvas,[-Size,+Size,+Size],[-Size,-Size,+Size],gray)
            Line3D(Canvas,[+Size,+Size,+Size],[+Size,-Size,+Size],gray)
            
            # Plot the center of the cube and the current
            # position of the sphere.
            Axes(Canvas,10,10,2)
            addSphere(Canvas, Center, Radius, blue)
            
            # Plot the remaining edges of the cube.
            Line3D(Canvas,[-Size,+Size,-Size],[+Size,+Size,-Size],gray)
            Line3D(Canvas,[-Size,-Size,-Size],[+Size,-Size,-Size],gray)
            Line3D(Canvas,[-Size,+Size,-Size],[-Size,-Size,-Size],gray)
            Line3D(Canvas,[+Size,+Size,-Size],[+Size,-Size,-Size],gray)
            
            Line3D(Canvas,[-Size,-Size,-Size],[-Size,-Size,+Size],gray)
            Line3D(Canvas,[-Size,+Size,-Size],[-Size,+Size,+Size],gray)
            Line3D(Canvas,[+Size,-Size,-Size],[+Size,-Size,+Size],gray)
            Line3D(Canvas,[+Size,+Size,-Size],[+Size,+Size,+Size],gray)
            
            # Keep a list of upto the last 50 positions
            # of the sphere, then plot those positions
            # as a color spot, <R,G,B> color depending on
            # the <X,Y,Z> position.
            Trails = Trails + [Center]
            if (len(Trails) > 50): Trails = Trails[1:len(Trails)]
            for P in Trails:
                Q = add2D(Origin,Ortho(P))
                RR = int(float(P[0]+Size)/float(2*Size)*255.0)
                GG = int(float(P[1]+Size)/float(2*Size)*255.0)
                BB = int(float(P[2]+Size)/float(2*Size)*255.0)
                plotCircleFilled(Canvas, Q, 3, makeColor(RR,GG,BB))
                
            # Update the position of the sphere,
            # bouncing off a wall as needed.
            Center = add3D(Center, [DeltaX,DeltaY,DeltaZ])
            if (abs(Center[0])+Radius > Size): DeltaX = -DeltaX
            if (abs(Center[1])+Radius > Size): DeltaY = -DeltaY
            if (abs(Center[2])+Radius > Size): DeltaZ = -DeltaZ
    
            # Display updated screen and hold.
            repaint(Canvas)
            time.sleep(0.01)
        return
        
    
    def Exercise2():
        Canvas = makeEmptyPicture(640,480)
        SetOrigin(320,240)
        addSimpleSphere(Canvas, [+100,10,0], 100, blue)
        show(Canvas)
        time.sleep(0.1)
        addSimpleSphere(Canvas, [+100,10,0], 50, blue)
        repaint(Canvas)
        time.sleep(0.1)
        addSimpleSphere(Canvas, [+100,10,0], 40, red)
        repaint(Canvas)
        addSimpleSphere(Canvas, [+100,10,0], 30, green)
        addSimpleSphere(Canvas, [+100,10,0], 20, orange)
        addSimpleSphere(Canvas, [-100,0,0], 50, blue)
        repaint(Canvas)
        return
        
    
    def TraceParabola():
        Canvas = makeEmptyPicture(640,480)
        SetOrigin(getWidth(Canvas)/2,getHeight(Canvas)/2)
        Center = [0,0,0]
        P0 = [-90,40,80]
        P1 = [10,-50,10]
        P2 = [90,70,60]
        Steps = 100
        Points = [P0]
        MyStyle = makeStyle(serif, bold+italic, 24)
        for I in range(Steps):
            setAllPixelsToAColor(Canvas,white)
            T = float(I)/(Steps-1)
            P = BlendParabola3D(P0,P1,P2,T)
            X = P[0]
            Y = P[1]
            Z = P[2]
            Points = Points + [P]
            Line3D(Canvas, [X,0,0], [X,0,Z], red)
            Line3D(Canvas, [X,Y,Z], [X,0,Z], red)
            Line3D(Canvas, [0,0,Z], [X,0,Z], red)
            Last = Points[0]
            for P in Points:
                Line3D(Canvas, Last, P, blue)
                Last = P
            Axes(Canvas,200,200,2)
            plotCircleFilled(Canvas, add2D(Origin,Ortho(P0)), 3, green)
            plotCircleFilled(Canvas, add2D(Origin,Ortho(P1)), 3, green)
            plotCircleFilled(Canvas, add2D(Origin,Ortho(P2)), 3, green)
            addTextWithStyle(Canvas, 10, getHeight(Canvas)-10, "P = <" + str(P[0]) + "," + str(P[1]) + "," + str(P[2]) + ">", MyStyle)
            repaint(Canvas)
            time.sleep(0.3)
        return
    Last edited by Rabbit; Nov 26 '12, 09:19 PM. Reason: Please use code tags when posting code.
  • dwblas
    Recognized Expert Contributor
    • May 2008
    • 626

    #2
    I see no point to posting a 373 line program for us to wade through. I am not, so this is a simplified example of what one would do without any reference to any functions in the code you posted.
    Code:
    try:
        import Tkinter as tk     ## Python 2.x
    except ImportError:
        import tkinter as tk     ## Python 3.x
    
    class Sunrise(object):
        def __init__(self):
            self.window = tk.Tk()
            self.canvas = tk.Canvas(self.window, width = 300, height = 300)
            self.canvas.pack()
     
            self.create_objects()
            deltax = 1
            deltay = -2
            ctr = 0
            self.colors_list = ["orange", "blue", "black"]
            while True:
                self.canvas.move('Sun', deltax, deltay)
    
                ## test for off the edge
                x1, y1, x2, y2 = self.canvas.coords(self.circle)
                print x1, y2
                if x1 > 300 or y2 < 1:
                    self.exit()
                    break
    
                ## change background color
                ctr += 1
                ctr=self.change_bg(ctr)
                self.canvas.after(30)
                self.canvas.update()
    
            self.window.mainloop()
    
    
        def create_objects(self):
            ## horizon
            line_x1=10
            line_y1=200
            line_x2=290
            self.canvas.create_line(line_x1, line_y1, line_x2, line_y1, width=3)
    
            ## background sky
            self.sky=self.canvas.create_rectangle(0, 0, 300, line_y1, outline='white', 
                               fill='gray50')
    
            ## sun
            x1=75
            y1=100
            self.circle=self.canvas.create_oval(x1, y1, x1+100, y1+100, fill="yellow", 
                                           tag='Sun')
    
            b1 = tk.Button(text="Exit", bg='lightblue', command=self.exit)
            b1.pack()
    
        def change_bg(self, ctr):
            if ctr > 25:
                ctr = 0
                if len(self.colors_list):
                    self.canvas.itemconfigure(self.sky, fill=self.colors_list[0])
                    del self.colors_list[0]
            return ctr
    
        def exit(self):
            self.window.after(100)  ## allow other updates to finish
            self.window.destroy()
            self.window.quit()
    
    SR=Sunrise()

    Comment

    Working...