Friday, May 11, 2012

Transmission Line and Transformer protection

http://www.youtube.com/watch?v=RJGtYddbVxU

The basics of protection schemes for transmission and distribution lines and transformers are covered in this presentation.

Sunday, April 22, 2012

Conway's Game of Life

So this dude, Conway, made a "zero-player" game because he's a mathematician and that's a good enough reason. He thinks a living cell dies when it's lonely or overpopulated. Humans just get severely annoyed.
Anyway, I implemented this game in C++ and OpenGL(glut) for a low-input-high-output semester project. Some call me lazy and I respect the opinions of others.
Constructive criticism is welcome.

// g++ ConwayWork.cpp -lglut
#include <iostream>
#include <GL/glut.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define ROW 100
#define COLUMN 100
int x_pos = 0, y_pos = 0, W, H;
bool gen = false;
void timerDraw(int foo);
void initGL()        //Initialize with the background color
{
   glClearColor(0.08, 0.08, 0.08, 1.0);
}
class Life
{
private:
    bool state;        //True is alive. False is dead.
public:
    Life()
    {
        state = false;
    }
    void make()
    {
        state = true;
    }
    void kill()
    {
        state = false;
    }
    bool isAlive()
    {
        return state;
    }
    friend void mouse(int button, int state, int x, int y);
    friend void keyboard(unsigned char a,int b,int c);
};
class World
{
private:
    Life colony[COLUMN][ROW];
public:
    World()
    {
        colony[3][3].make();
        colony[4][4].make();
        colony[5][4].make();
        colony[5][3].make();
        colony[5][2].make();
    }
    void populateRandom()
    {
        for(int i = 0; i < COLUMN; i++)
            for(int j = 0; j < ROW; j++)
                if(rand()%2)
                    colony[i][j].make();
                else
                    colony[i][j].kill();
    }
    void clear()
    {
        for(int i = 0; i < COLUMN; i++)
            for(int j = 0; j < ROW; j++)
                colony[i][j].kill();
    }
    void judgment()
    {
        World theDeparted;
        for(int i = 0; i < COLUMN; i++)
            for(int j = 0; j < ROW; j++)
                if(!colony[i][j].isAlive() && neighbours(i, j) == 3)    //If dead and 3 neighbours, create.
                    theDeparted.colony[i][j].make();
                else if(colony[i][j].isAlive() && (neighbours(i, j) == 2 || neighbours(i, j) == 3) )    //If alive and two or 3 neighbours, continue to live.
                    theDeparted.colony[i][j].make();
                else                    //Anything else, kill.
                    theDeparted.colony[i][j].kill();
        *this = theDeparted;
    }
    int neighbours(int i, int j)
    {
        int n = 0;
        if(i > 0 && j > 0 && i < COLUMN-1 && j < ROW-1)        //Inside
        {
            if(colony[i-1][j-1].isAlive())    //Down left
                n++;
            if(colony[i-1][j].isAlive())        //Left
                n++;
            if(colony[i-1][j+1].isAlive())    //Up left
                n++;
            if(colony[i][j+1].isAlive())        //Up
                n++;
            if(colony[i+1][j+1].isAlive())    //Up right
                n++;
            if(colony[i+1][j].isAlive())        //Right
                n++;
            if(colony[i+1][j-1].isAlive())    //Down right
                n++;
            if(colony[i][j-1].isAlive())        //Down
                n++;
            return n;
        }
        else if(i == 0 && j == 0)        //Lower left corner
        {
            if(colony[i][j+1].isAlive())        //Up
                n++;
            if(colony[i+1][j+1].isAlive())    //Up right
                n++;
            if(colony[i+1][j].isAlive())        //Right
                n++;
            return n;
        }
        else if(i == 0 && j == ROW-1)        //Top left corner
        {
            if(colony[i+1][j-1].isAlive())    //Down right
                n++;
            if(colony[i][j-1].isAlive())        //Down
                n++;
            if(colony[i+1][j].isAlive())        //Right
                n++;
            return n;
        }
        else if(i == COLUMN-1 && j == ROW-1)    //Top right corner
        {
            if(colony[i-1][j-1].isAlive())    //Down left
                n++;
            if(colony[i-1][j].isAlive())        //Left
                n++;
            if(colony[i][j-1].isAlive())        //Down
                n++;
            return n;
        }
        else if(i == COLUMN-1 && j == 0)    //Lower right corner
        {
            if(colony[i-1][j].isAlive())        //Left
                n++;
            if(colony[i-1][j+1].isAlive())    //Up left
                n++;
            if(colony[i][j+1].isAlive())        //Up
                n++;
            return n;
        }
        else if(i == 0)            //Left column
        {
            if(colony[i][j+1].isAlive())        //Up
                n++;
            if(colony[i+1][j+1].isAlive())    //Up right
                n++;
            if(colony[i+1][j].isAlive())        //Right
                n++;
            if(colony[i+1][j-1].isAlive())    //Down right
                n++;
            if(colony[i][j-1].isAlive())        //Down
                n++;
            return n;
        }
        else if(j == 0)        //Bottom row
        {
            if(colony[i-1][j].isAlive())        //Left
                n++;
            if(colony[i-1][j+1].isAlive())    //Up left
                n++;
            if(colony[i][j+1].isAlive())        //Up
                n++;
            if(colony[i+1][j+1].isAlive())    //Up right
                n++;
            if(colony[i+1][j].isAlive())        //Right
                n++;
            return n;
        }
        else if(i == COLUMN-1)        //Right column
        {
            if(colony[i-1][j-1].isAlive())    //Down left
                n++;
            if(colony[i-1][j].isAlive())        //Left
                n++;
            if(colony[i-1][j+1].isAlive())    //Up left
                n++;
            if(colony[i][j+1].isAlive())        //Up
                n++;
            if(colony[i][j-1].isAlive())        //Down
                n++;
            return n;
        }
        else if(j == ROW-1)        //Top row
        {
            if(colony[i-1][j-1].isAlive())    //Down left
                n++;
            if(colony[i-1][j].isAlive())        //Left
                n++;
            if(colony[i+1][j].isAlive())        //Right
                n++;
            if(colony[i+1][j-1].isAlive())    //Down right
                n++;
            if(colony[i][j-1].isAlive())        //Down
                n++;
            return n;
        }
    }
    friend void draw();
    friend void mouse(int button, int state, int x, int y);
    friend void keyboard(unsigned char a,int b,int c);
};
    World pluto;    //Create object.

void draw()
{
    static double color1 = 0.03, color2 = 1, color3 = 0;    //Colors for decoration only.
    glClear(GL_COLOR_BUFFER_BIT);
    for(int i = 0; i < COLUMN; i++)
    {
        for(int j = 0; j < ROW; j++)
            if(pluto.colony[i][j].isAlive())
            {
                glBegin(GL_POLYGON);        //Draw life square, size 10.
                glColor3d(1, color2-color1, color1+color2);
                glVertex2d(i*10,j*10);
                glVertex2d(i*10+10,j*10);
                glVertex2d(i*10+10,10*j-10);
                glVertex2d(i*10,j*10-10);
                glEnd();
                //cout<<"@";        //Cout for command line output, this slows the program considerably.
            }
            //else  
                //cout<<" ";
    //    cout<<endl;
    }

    glBegin(GL_POLYGON);        //Draw keyboard square size 10.
    glColor3d(1, color3, 0);
    glVertex2d(x_pos*10,y_pos*10);
    glVertex2d(x_pos*10+10,y_pos*10);
    glVertex2d(x_pos*10+10,10*y_pos-10);
    glVertex2d(x_pos*10,y_pos*10-10);
    glEnd();
    glutSwapBuffers();
    if(gen)
    {
        pluto.judgment();        //Show generation changes.
        color1 += 0.01;
        color2 -= 0.01;
        color3 = 1;
    }
    else
        color3 = 0;
    glutTimerFunc(200,timerDraw,0);
}
void reshape(int w, int h)
{
    W = w;        //W and H for use by mousefunction only.
    H = h;
    glClear(GL_COLOR_BUFFER_BIT);
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-10.0,COLUMN*10+10,-10.0,ROW*10+10,-1,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
void mouse(int button, int state, int x, int y)
{
    //Origin of window is top left, origin of OpenGL is bottom left. Y values thus corrected.
    if(button == GLUT_LEFT_BUTTON && state == GLUT_UP && x*COLUMN/W > 0 && x*COLUMN/W < COLUMN && (H-y)*ROW/H > 0 && (H-y)*ROW/H < ROW)
    {
        if(pluto.colony[x*COLUMN/W][(H-y)*ROW/H].isAlive())
            pluto.colony[x*COLUMN/W][(H-y)*ROW/H].kill();
        else
            pluto.colony[x*COLUMN/W][(H-y)*ROW/H].make();
    }
}
void keyboard(unsigned char a,int b,int c)
{
    switch(a)
    {
    case 'w': case 'W':
        if(y_pos < ROW-1)
            y_pos++;
        break;
    case 'a': case'A':
        if(x_pos > 0)
            x_pos--;
        break;
    case 's': case 'S':
        if(y_pos > 0)
            y_pos--;
        break;
    case 'd': case 'D':
        if(x_pos < COLUMN-1)
            x_pos++;
        break;
    case 'x': case 'X':
        if(pluto.colony[x_pos][y_pos].isAlive())
            pluto.colony[x_pos][y_pos].kill();
        else
            pluto.colony[x_pos][y_pos].make();
        break;
    case ' ':
        gen = !gen;
        break;
    case 'r': case 'R':
        pluto.populateRandom();
        break;
    case 'c': case 'C':
        pluto.clear();
        break;
    default:
        break;
    }
}
void timerDraw(int foo)
{
    glutMouseFunc(mouse);
    glutKeyboardFunc(keyboard);
    glutPostRedisplay();
}

int main(int argc, char** argv)        //Mandatory arguments for OpenGL
{
    srand (time(NULL));        //Seed the Random number generator.
    cout<<"Use WASD keys for navigation, 'x' to alter state, 'r' for random population, 'c' to clear, Space to start.\nMouse can also be used, although it is slightly inaccurate.\n";
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutCreateWindow("CONWAY");
    glutReshapeFunc(reshape);
    glutDisplayFunc(draw);
    glutSwapBuffers();
    initGL();
    glutMainLoop();
    return 0;
}