Friday, May 23, 2014

Final post

Three things I learned in independent study this year:
1. Basic python coding
2. Pygame coding
3. This is my favorite class

Best experience in computer science:
It'll sound lame, but I really enjoyed everything about my four years with you, Sming (except grid-world, faq grid-world). Creating a game at the end of CS1 was just as much fun as making star steps for the hundredth time in AP.

Worst experience in computer science:
Grid-world, that sucked.

The topic I understand the best would probably be arrays and sorting.

The only thing I really didn't get very well was grid-world. I'm not sure whether or not you've noticed yet, but I didn't like that unit.

The only thing that you could do to improve computer science is continue offering independent study. I get that they need you other places, but this was one of the most productive classes of my high school career. It reinforced everything I've learned over the past three years by making me do it all myself.

I am going to Shippensburg University for a BS in software engineering

Stick with it. Computer science was by far my favorite class throughout all four years at CV. There are two periods I can say that I truthfully look forward to, the first being lunch, the second being computer science.

Friday, April 25, 2014

04.21.2014 - 04.25.2014

First I added some badass new polygons to the screen:
Next, I changed the background to black... cause shadows n' stuff:
Then I changed the visible area color to white... cause light n' stuff:
Then I removed the polygon outlines so you can't see them in the 'shadows':
Finally, I took out the rays... cause fuq it yolo n' stuff:
The dynamic shadows look pretty cool in action, if I do say so myself.

Friday, April 11, 2014

04.07.14 - 04.11.14

What I did this week:

What I actually did:
I found python code for "sight and light", a program to simulate fields of vision and how they react with polygons, I plan on going through the code and seeing if there's anything I can do with it.

import pygame
import pygame.gfxdraw
import math

class SightAndLight():
    def __init__(self):
        # initialize pygame
        pygame.init()
        self.screen = pygame.display.set_mode((640, 360))
        pygame.display.set_caption("SIGHT & LIGHT Demo - Python/PyGame")

        # mouse position
        self.mouse_pos = (0, 0)

        # general
        self.fps_clock = pygame.time.Clock()
        self.running = True
        self.update_shadows = True # only call update on mouse movement

        # segments
        self.segments = [
                # Border
                {"a":{"x":0,"y":0}, "b":{"x":640,"y":0}},
                {"a":{"x":640,"y":0}, "b":{"x":640,"y":360}},
                {"a":{"x":640,"y":360}, "b":{"x":0,"y":360}},
                {"a":{"x":0,"y":360}, "b":{"x":0,"y":0}},

                # Polygon #1
                {"a":{"x":100,"y":150}, "b":{"x":120,"y":50}},
                {"a":{"x":120,"y":50}, "b":{"x":200,"y":80}},
                {"a":{"x":200,"y":80}, "b":{"x":140,"y":210}},
                {"a":{"x":140,"y":210}, "b":{"x":100,"y":150}},

                # Polygon #2
                {"a":{"x":100,"y":200}, "b":{"x":120,"y":250}},
                {"a":{"x":120,"y":250}, "b":{"x":60,"y":300}},
                {"a":{"x":60,"y":300}, "b":{"x":100,"y":200}},

                # Polygon #3
                {"a":{"x":200,"y":260}, "b":{"x":220,"y":150}},
                {"a":{"x":220,"y":150}, "b":{"x":300,"y":200}},
                {"a":{"x":300,"y":200}, "b":{"x":350,"y":320}},
                {"a":{"x":350,"y":320}, "b":{"x":200,"y":260}},

                # Polygon #4
                {"a":{"x":340,"y":60}, "b":{"x":360,"y":40}},
                {"a":{"x":360,"y":40}, "b":{"x":370,"y":70}},
                {"a":{"x":370,"y":70}, "b":{"x":340,"y":60}},

                # Polygon #5
                {"a":{"x":450,"y":190}, "b":{"x":560,"y":170}},
                {"a":{"x":560,"y":170}, "b":{"x":540,"y":270}},
                {"a":{"x":540,"y":270}, "b":{"x":430,"y":290}},
                {"a":{"x":430,"y":290}, "b":{"x":450,"y":190}},

                # Polygon #6
                {"a":{"x":400,"y":95}, "b":{"x":580,"y":50}},
                {"a":{"x":580,"y":50}, "b":{"x":480,"y":150}},
                {"a":{"x":480,"y":150}, "b":{"x":400,"y":95}}

                #Polygon #7
                #{"a":{"x":380,"y":75}, "b":{"x":560,"y":30}},
                #{"a":{"x":560,"y":30}, "b":{"x":460,"y":130}},
                #{"a":{"x":460,"y":130}, "b":{"x":380,"y":75}}
        ]

        # Intersects
        self.intersects = []

        # Points
        self.points = []

    def run(self):
        while self.running:
            self.main_loop()

    def main_loop(self):
        self.handle_input()
        if self.update_shadows:
            self.update()
            self.update_shadows = False
        
        self.render_frame()


    def update(self):
        # Clear old points
        self.points = []

        # Get all unique points
        for segment in self.segments:
            self.points.append((segment['a'], segment['b']))

        unique_points = []
        for point in self.points:
            if point not in unique_points:
                unique_points.append(point)

        # Get all angles
        unique_angles = []
        for point in unique_points:
            angle = math.atan2(point[0]["y"]-self.mouse_pos[1], point[0]["x"]-self.mouse_pos[0])
            point[0]["angle"] = angle
            unique_angles.append(angle-0.00001)
            unique_angles.append(angle)
            unique_angles.append(angle+0.00001)

        # RAYS IN ALL DIRECTIONS
        self.intersects = []
        for angle in unique_angles:
            # Calculate dx & dy from angle
            dx = math.cos(angle)
            dy = math.sin(angle)

            # Ray from center of screen to mouse
            ray = {
                    "a": {"x":self.mouse_pos[0], "y": self.mouse_pos[1]},
                    "b": {"x": self.mouse_pos[0]+dx, "y": self.mouse_pos[1]+dy}
            }

            # Find CLOSEST intersection
            closest_intersect = None
            for segment in self.segments:
                intersect = self.get_intersection(ray, segment)
                if not intersect: continue
                if not closest_intersect or intersect["param"] < closest_intersect["param"]:
                    closest_intersect = intersect

            # Intersect angle
            if not closest_intersect: continue
            closest_intersect["angle"] = angle

            # Add to list of intersects
            self.intersects.append(closest_intersect)

        # Sort intersects by angle
        self.intersects = sorted(self.intersects, key=lambda k: k['angle'])

    def render_frame(self):
        self.screen.fill((255, 255, 255))

        # draw segments
        for segment in self.segments:
            pygame.draw.aaline(self.screen, (153, 153, 153), (segment['a']['x'], segment['a']['y']), (segment['b']['x'], segment['b']['y']))

        self.draw_polygon(self.intersects, (221, 56, 56))

        # draw debug lines
        for intersect in self.intersects:
            pygame.draw.aaline(self.screen, (255, 85, 85), self.mouse_pos, (intersect['x'], intersect['y']))

        # limit fps
        self.fps_clock.tick(60)

        # update screen
        pygame.display.update()

    def handle_input(self):
        pygame.event.pump()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
                print("quit")
                break

            # KEYBOARD
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE or event.key == pygame.K_q:
                    self.running = False

            # MOUSE
            elif event.type == pygame.MOUSEMOTION:
                self.mouse_pos = event.pos
                self.update_shadows = True

    def get_intersection(self, ray, segment):
        ''' Find intersection of RAY & SEGMENT '''
        # RAY in parametric: Point + Direction*T1
        r_px = ray['a']['x']
        r_py = ray['a']['y']
        r_dx = ray['b']['x'] - ray['a']['x']
        r_dy = ray['b']['y'] - ray['a']['y']

        # SEGMENT in parametric: Point + Direction*T2
        s_px = segment['a']['x']
        s_py = segment['a']['y']
        s_dx = segment['b']['x'] - segment['a']['x']
        s_dy = segment['b']['y'] - segment['a']['y']

        # Are they parallel? If so, no intersect
        r_mag = math.sqrt(r_dx*r_dx+r_dy*r_dy)
        s_mag = math.sqrt(s_dx*s_dx+s_dy*s_dy)
        if r_dx/r_mag == s_dx/s_mag and r_dy/r_mag == s_dy/s_mag:
            return None

        # SOLVE FOR T1 & T2
        # r_px+r_dx*T1 = s_px+s_dx*T2 && r_py+r_dy*T1 = s_py+s_dy*T2
        # ==> T1 = (s_px+s_dx*T2-r_px)/r_dx = (s_py+s_dy*T2-r_py)/r_dy
        # ==> s_px*r_dy + s_dx*T2*r_dy - r_px*r_dy = s_py*r_dx + s_dy*T2*r_dx - r_py*r_dx
        # ==> T2 = (r_dx*(s_py-r_py) + r_dy*(r_px-s_px))/(s_dx*r_dy - s_dy*r_dx)

        # todo: fix zerodivision error handling
        try:
            T2 = (r_dx*(s_py-r_py) + r_dy*(r_px-s_px))/(s_dx*r_dy - s_dy*r_dx)
        except ZeroDivisionError:
            T2 = (r_dx*(s_py-r_py) + r_dy*(r_px-s_px))/(s_dx*r_dy - s_dy*r_dx-0.01)

        try:
            T1 = (s_px+s_dx*T2-r_px)/r_dx
        except ZeroDivisionError:
            T1 = (s_px+s_dx*T2-r_px)/(r_dx-0.01)

        # Must be within parametic whatevers for RAY/SEGMENT
        if T1 < 0: return None
        if T2 < 0 or T2>1: return None

        # Return the POINT OF INTERSECTION
        return {
                "x": r_px+r_dx*T1,
                "y": r_py+r_dy*T1,
                "param": T1
        }

    def draw_polygon(self, polygon, color):
        # collect coordinates for a giant polygon
        points = []
        for intersect in polygon:
            points.append((intersect['x'], intersect['y']))
        
        # draw as a giant polygon
        pygame.gfxdraw.aapolygon(self.screen, points, color)
        pygame.gfxdraw.filled_polygon(self.screen, points, color)

if __name__ == "__main__":
    demo = SightAndLight()
    demo.run()


Friday, April 4, 2014

03.31.2014 - 04.04.2014

This week, I made a basic calculator program (TI84) and a simple paint program in Python. Next week I hope to improve upon both of them.

import pygame, random, sys
from pygame.locals import *

WINDOWWIDTH=600
WINDOWHEIGHT=600
BACKGROUNDCOLOR=(255,255,255)
FPS=50
PLAYERMOVERATE=5

def terminate():
    pygame.quit()
    sys.exit()

pygame.init()
mainClock=pygame.time.Clock()
windowSurface=pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Paint')
pygame.mouse.set_visible(False)
windowSurface.fill(BACKGROUNDCOLOR)

down=False

BLUE=(0, 0, 255)

while True:
    moveLeft=moveRight=moveUp=moveDown=False

    while True:
        for event in pygame.event.get():
            if event.type==QUIT:
                terminate()

            if event.type==KEYDOWN:
                if event.key==K_ESCAPE:
                    terminate()
                if event.key==event.key==ord('x'):
                   windowSurface.fill(BACKGROUNDCOLOR) 

        if event.type==MOUSEBUTTONDOWN:
            down=True
        if event.type==MOUSEBUTTONUP:
            down=False

        if event.type==MOUSEMOTION and down:
            pygame.draw.circle(windowSurface,BLUE, (event.pos[0], event.pos[1]), 10, 0)


        #windowSurface.fill(BACKGROUNDCOLOR)
        pygame.display.update()

        mainClock.tick(FPS)

Monday, March 31, 2014

Marking period wrap up

Over the past two weeks, I finished nearly all of the python programs on codingbat. That's pretty much it

Friday, March 14, 2014

03.10.14 - 03.14.14

Played around with some rotational vectors in pygame:
import pygame, random, sys
from pygame.locals import *

WINDOWWIDTH=600
WINDOWHEIGHT=600
BACKGROUNDCOLOR=(0, 0, 0)
FPS=40

def terminate():
    pygame.quit()
    sys.exit()

pygame.init()
mainClock=pygame.time.Clock()
windowSurface=pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Test program')
pygame.mouse.set_visible(False)

image1=pygame.image.load('arrowUp.png')
width1, height1=image1.get_size()

while True:
    #playerRect.topleft=(WINDOWWIDTH/2, WINDOWHEIGHT/2)

    while True:
        image2=pygame.transform.rotate(image1, 5)
        width2, height2=image2.get_size()
        for event in pygame.event.get():
            if event.type==QUIT:
                terminate()

            if event.type==KEYDOWN:
                if event.key==K_RIGHT:
                    image2=pygame.transform.rotate(image1, 5)
                    width2, height2=image2.get_size()
                if event.key==K_ESCAPE:
                    terminate()

        windowSurface.fill(BACKGROUNDCOLOR)
        windowSurface.blit(image2, [round(WINDOWWIDTH/2-(width1-width2)/2), round(WINDOWHEIGHT/2-(height1-height2)/2)])
        pygame.display.update()

        mainClock.tick(FPS)

I also got images to change when certain actions are taken
import pygame, random, sys
from pygame.locals import *

WINDOWWIDTH=600
WINDOWHEIGHT=600
BACKGROUNDCOLOR=(0, 0, 0)
FPS=40
PLAYERMOVERATE=5

def terminate():
    pygame.quit()
    sys.exit()

#Initalize
pygame.init()
mainClock=pygame.time.Clock()
windowSurface=pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Test program')
pygame.mouse.set_visible(False)

playerImage=pygame.image.load('arrowUp.png')
playerRect=playerImage.get_rect()

while True:
    playerRect.topleft=(WINDOWWIDTH/2, WINDOWHEIGHT-50)
    moveLeft=moveRight=moveUp=moveDown=False

    while True:
        for event in pygame.event.get():
            if event.type==QUIT:
                terminate()

            if event.type==KEYDOWN:
                if event.key==K_UP and event.key==K_RIGHT:
                    playerImage=pygame.image.load('arrowUpRight.png')
                if event.key==K_LEFT:
                    playerImage=pygame.image.load('arrowLeft.png')
                    moveRight=False
                    moveLeft=True
                if event.key==K_RIGHT:
                    playerImage=pygame.image.load('arrowRight.png')
                    moveLeft=False
                    moveRight=True
                if event.key==K_UP:
                    playerImage=pygame.image.load('arrowUp.png')
                    moveDown=False
                    moveUp=True
                if event.key==K_DOWN:
                    playerImage=pygame.image.load('arrowDown.png')
                    moveUp=False
                    moveDown=True

            if event.type==KEYUP:
                if event.key==K_LEFT:
                    moveLeft=False
                if event.key==K_RIGHT:
                    moveRight=False
                if event.key==K_UP:
                    moveUp=False
                if event.key==K_DOWN:
                    moveDown=False
                if event.key==K_ESCAPE:
                    terminate()
                   
            if event.type==MOUSEMOTION:
                playerRect.move_ip(event.pos[0] - playerRect.centerx, event.pos[1] - playerRect.centery)


        if moveLeft and playerRect.left>0:
            playerRect.move_ip(-1*PLAYERMOVERATE, 0)
        if moveRight and playerRect.right<WINDOWWIDTH:
            playerRect.move_ip(PLAYERMOVERATE, 0)
        if moveUp and playerRect.top>0:
            playerRect.move_ip(0, -1*PLAYERMOVERATE)
        if moveDown and playerRect.bottom<WINDOWHEIGHT:
            playerRect.move_ip(0, PLAYERMOVERATE)

        pygame.mouse.set_pos(playerRect.centerx, playerRect.centery)

        windowSurface.fill(BACKGROUNDCOLOR)
        windowSurface.blit(playerImage, playerRect)
        pygame.display.update()

        mainClock.tick(FPS)








         


Friday, March 7, 2014

03.03.2014 - 03.07.2014

After finishing the first python book last week, I started tinkering around with some of the pygame stuff not taught in the book. Here are the programs I made / edited.

Moving background program:
import pygame, random, sys
from pygame.locals import *
#import pygame.sprite as sprite

theClock = pygame.time.Clock()

WINDOWHEIGHT=600
WINDOWWIDTH=600

background = pygame.image.load('starBackground.jpg')

#background_size = background.get_size()
background_rect = background.get_rect()
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
#w,h = background_size
x = 0
y = 0

x1 = 0
y1 = -WINDOWHEIGHT

def terminate():
    pygame.quit()
    sys.exit()

running = True

while running:
    screen.blit(background,background_rect)
    pygame.display.update()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    y1 += 5
    y += 5
    screen.blit(background,(x,y))
    screen.blit(background,(x1,y1))
    if y > WINDOWHEIGHT:
        y = -WINDOWHEIGHT
    if y1 > WINDOWHEIGHT:
        y1 = -WINDOWHEIGHT
    #pygame.display.flip()
    pygame.display.update()
    theClock.tick(100)

    if event.type==KEYDOWN:
        if event.key==K_ESCAPE:
            terminate()

   
and this

import pygame, random, sys
from pygame.locals import *

theClock=pygame.time.Clock()

HEIGHT=600
WIDTH=600

r=0
g=0
b=0
BACKGROUNDCOLOR=(r, g, b)

reverse=False

windowSurface=pygame.display.set_mode((WIDTH, HEIGHT))

def terminate():
    pygame.quit()
    sys.exit()

running=True

while running:
    windowSurface.fill(BACKGROUNDCOLOR)

    for event in pygame.event.get():
        if event.type==KEYDOWN:
            if event.key==K_ESCAPE:
                terminate()

    if reverse==False:
        if r<255 and b==255:
            r+=1
        elif g<255 and r==255:
            g+=1
        elif b<255:
            b+=1
        elif r==255 and b==255 and g==255:
            reverse=True
    elif reverse==True:
        if r>0 and b==0:
            r-=1
        elif g>0 and r==0:
            g-=1
        elif b>0:
            b-=1
        elif r==0 and b==0 and g==0:
            reverse=False

    BACKGROUNDCOLOR=(r, g, b)
   
    pygame.display.update()
    theClock.tick(200)