Wednesday, January 20, 2010

ColorModel.java ~ A program to translate between various colorspaces

/** Color translation class
Daniel Tanner
January 14th, 2010
CMPT 360
*/

/**
This program will allow for the user to translate
back and forth between different colorspaces.
*/

//import statements
import java.text.*;
import java.util.*;
import java.io.*;

public class ColorModel {
// unless otherwise stated, all color values are
// given as doubles in the range 0.0 - 1.0

// all methods throw an IllegalArgumentException if an unexpected argument is encountered

/**
* converts 'additive' RGB to 'subtractive' CMY
* @param rgb - color in RGB space
* @return color in CMY space
*/
public static double[] RGBtoCMY (double[] rgb) {
for(int index = 0; index < 3; index++)
rgb[index] = 1.0 - rgb[index];
return rgb;
}

/**
* converts 'subtractive' CMY to 'additive' RGB
* @param cmy - color in CMY space
* @return color in RGB space
*/
public static double[] CMYtoRGB (double[] cmy) {
for(int index = 0; index < 3; index++)
cmy[index] = 1.0 - cmy[index];
return cmy;
}

/**
* converts color from RGB to HSV color space
* hue will be a number between 0..360
* @param rgb - color in RGB space
* @return color in HSV space
*/
public static double[] RGBtoHSV (double[] rgb)
{
double min = rgb[0], max = rgb[0], h = 0, s = 0, v = 0;

//find the max and the min
for(int index = 1; index < 3; index++)
{
if(max < rgb[index])
max = rgb[index];
if(min > rgb[index])
min = rgb[index];
}

//finding h (according to wikipedia)
if(max == min)
h = 0;

if(max == rgb[0]) //if max = r
h = (60 * ((rgb[1] - rgb[2])/(max - min)) + 360) % 360;

if(max == rgb[1]) //if max = g
h = (60 * (rgb[2] - rgb[0])/(max - min)) + 120;

if(max == rgb[2]) //if max = b
h = (60 * (rgb[0] - rgb[1])/(max - min)) + 240;

//determine s
if(max == 0)
s = 0;
else
s = (max - min)/max;
v = max;
//put all variables into array

rgb[0] = h; rgb[1] = s; rgb[2] = v;
return rgb;
}

/**
* converts color from HSV to RGB color space
* hue will be a number between 0..360
* @param hsv - color in HSV space
* @return color in RGB space
*/
public static double[] HSVtoRGB (double[] hsv)
{
//using same variable names as wikipedia's article
double i = (hsv[0] / 60) % 6;
double f = (hsv[0] / 60) - (hsv[0] / 60);
double p = hsv[2] * (1 - hsv[1]);
double q = hsv[2] * (1- f * hsv[1]);
double t = hsv[2] * (1 - (1 - f) * hsv[1]);
double v = hsv[2];

//compute RGB based on i
switch((int)i)
{
case 0:
hsv[0] = v; hsv[1] = t; hsv[2] = p;
break;
case 1:
hsv[0] = q; hsv[1] = v; hsv[2] = p;
break;
case 2:
hsv[0] = p; hsv[1] = v; hsv[2] = t;
break;
case 3:
hsv[0] = p; hsv[1] = q; hsv[2] = v;
break;
case 4:
hsv[0] = t; hsv[1] = p; hsv[2] = v;
break;
case 5:
hsv[0] = v; hsv[1] = p; hsv[2] = q;
break;
}
return hsv;
}

/**
* converts color from RGB to YIQ color space
* @param rgb - color in RGB space
* @return color in YIQ space
*/
public static double[] RGBtoYIQ (double[] rgb)
{
//create Matrices
double [][] toYIQNums = {{.299, .587, .114}, {.596, -.275, -.321}, {.212, -.523, .311}};
Matrix linearTransform = new Matrix(toYIQNums);
Matrix rGBMatrix = new Matrix(rgb, 3);

//run the linear transformation (matrix multiplication)
linearTransform = linearTransform.times(rGBMatrix);
rgb = linearTransform.getRowPackedCopy();

return rgb;
}


/**
* converts color from YIQ to RGB color space
* @param yiq - color in YIQ space
* @return color in RGB space
*/
public static double[] YIQtoRGB (double[] yiq)
{
//create Matrices
double [][] toRGBNums = {{1.0, .956, .621}, {1.0, -.272, -.647}, {1.0, -1.105, 1.702}};
Matrix linearTransform = new Matrix(toRGBNums);
Matrix yIQMatrix = new Matrix(yiq, 3);

//run the linear transformation (matrix multiplication)
linearTransform = linearTransform.times(yIQMatrix);
yiq = linearTransform.getRowPackedCopy();
return yiq;
}

/**
* converts color from RGB to CIE XYZ color space
* @param rgb - color in RGB space
* @return color in CIE XYZ space
*/
public static double[] RGBtoXYZ (double[] rgb)
{
//create Matrices
double [][] toXYZNums = {{.412453, .357580, .180423}, {.212671, .715160, .072169}, {.019334, .119193, .950227}};
Matrix linearTransform = new Matrix(toXYZNums);
Matrix rGBMatrix = new Matrix(rgb, 3);

//run the linear transformation (matrix multiplication)
linearTransform = linearTransform.times(rGBMatrix);
rgb = linearTransform.getRowPackedCopy();
return rgb;
}


/**
* converts color from CIE XYZ to RGB color space
* @param xyz - color in XYZ space
* @return color in RGB space
*/
public static double[] XYZtoRGB (double[] xyz)
{
//Create Matrices
double [][] toRGBNums = {{3.240479, -1.537150, -0.498535}, {-.969256, 1.875992, .041556}, {.055648, -.204043, 1.057311}};
Matrix linearTransform = new Matrix(toRGBNums);
Matrix xYZMatrix = new Matrix(xyz, 3);

//run the linear transformation (matrix multiplication)
linearTransform = linearTransform.times(xYZMatrix);
xyz = linearTransform.getRowPackedCopy();
return xyz;
}

/**
* converts color from RGB to CIE Lab color space
* @param rgb - color in RGB space
* @return color in CIE Lab space
*/
public static double[] RGBtoCIELab (double[] rgb)
{
//start by converting to XYZ colorspace
rgb = RGBtoXYZ(rgb);

//Create variables needed for functions
double ySubN = 100.000;
double xSubN = 95.047;
double zSubN = 108.883;
double uSubN = .2009;
double vSubN = .4610;

/* At this point we use the function f(t)
such that:
f(t) = t^(1/3) t > (6/29)^3
f(t) = (1/3(29/6)^2)t + 4/29 t <= (6/29)^3
for x, y, and z and then plug the resulting number
into a function for L*, a*, and b* as pulled from wikipedia
*/

double functX = rgb[0] / xSubN;
double functY = rgb[1] / ySubN;
double functZ = rgb[2] / zSubN;

if(functX > Math.pow(6.0/29.0, 3.0))
functX = Math.pow(functX, 1.0/3.0);
else
functX = (1.0/3.0)*(Math.pow(29.0 / 6.0, 2.0)*(functX) + 4.0 / 29.0);

if(functY > Math.pow(6.0/29.0, 3.0))
functY = Math.pow(functY, 1.0/3.0);
else
functY = (1.0/3.0)*(Math.pow(29.0 / 6.0, 2.0)*(functY) + 4.0 / 29.0);

if(functZ > Math.pow(6.0/29.0, 3.0))
functZ = Math.pow(functZ, 1.0/3.0);
else
functZ = (1.0/3.0)*(Math.pow(29.0 / 6.0, 2.0)*(functZ) + 4.0 / 29.0);

//using functions from Wikipedia to get L, A, and B
double l = 116.0 * functY - 16;
double a = 500.0 * (functX - functY);
double b = 200.0 * (functY - functZ);
rgb[0] = l; rgb[1] = a; rgb[2] = b;

return rgb;
}


/**
* converts color from CIE Lab to RGB color space
* @param lab - color in CIE Lab space
* @return color in RGB space
*/
public static double[] CIELabtoRGB (double[] lab)
{
//Create variables
double x = 0, y = 0, z = 0;
double ySubN = 100.000;
double xSubN = 95.047;
double zSubN = 108.883;
double uSubN = .2009;
double vSubN = .4610;
double delta = 6.0 / 29.0;

//Create functions pulled from wikipedia (steps 1-6)
double functY = (lab[0] + 16) / 116.0;
double functX = functY + lab[1] / 500.0;
double functZ = functY - lab[2] / 200.0;

if(functY > delta)
y = ySubN * Math.pow(functY, 3.0);
else
y = (functY - 16.0/116.0) * 3.0 * Math.pow(delta, 2.0) * ySubN;

if(functX > delta)
x = xSubN * Math.pow(functX, 3.0);
else
x = (functX - 16.0/116.0) * 3 * Math.pow(delta, 2.0) * xSubN;

if(functZ > delta)
z = zSubN * Math.pow(functZ, 3.0);
else
z = (functZ - 16.0 / 116.0) * 3 * Math.pow(delta, 2.0) * zSubN;

lab[0] = x; lab[1] = y; lab[2] = z;

//end by converting from xyz to rgb
lab = XYZtoRGB(lab);
return lab;
}

/**
* converts color from RGB to CIE Luv color space
* @param rgb - color in RGB space
* @return color in CIE Luv space
*/
public static double[] RGBtoCIELuv (double[] rgb)
{
//start by converting to XYZ
rgb = RGBtoXYZ(rgb);

//Create Variables
double ySubN = 100.000;
double xSubN = 95.047;
double zSubN = 108.883;
double uSubN = .2009;
double vSubN = .4610;
double l = 0, u = 0, v = 0;
double delta = 6.0 / 29.0;

//functions according to wikipedia
double functY = rgb[1] / ySubN;
double uPrime = 4.0 * rgb[0] / (rgb[0] + 15.0 * rgb[1] + 3.0 * rgb[2]); //IE u' = 4x / (x + 15y + 3z)
double vPrime = 9.0 * rgb[1] / (rgb[0] + 15.0 * rgb[1] + 3.0 * rgb[2]);

if(functY > Math.pow(delta, 3.0))
l = 116.0 * Math.pow(functY, 1.0/3.0) - 16.0;
else
l = Math.pow(29.0 / 3.0, 3.0) * functY;

u = 13.0 * l * (uPrime - uSubN);
v = 13.0 * l * (vPrime - vSubN);

//Toss results into the array
rgb[0] = l; rgb[1] = u; rgb[2] = v;

return rgb;
}


/**
* converts color from CIE Luv to RGB color space
* @param luv - color in CIE Luv space
* @return color in RGB space
*/
public static double[] CIELuvtoRGB (double[] luv)
{
//Create Variables
double ySubN = 100.000;
double xSubN = 95.047;
double zSubN = 108.883;
double uSubN = .2009;
double vSubN = .4610;
double x = 0, y = 0, z = 0;

//Create functions as per wikipedia's instructions
double uPrime = luv[1] / 13 * luv[0] + uSubN;
double vPrime = luv[2] / 13 * luv[0] + vSubN;

if(luv[0] > 8.0)
y = ySubN * (9.0 * uPrime / 4.0 * vPrime);
else
y = ySubN * luv[0] * Math.pow(3.0 / 29.0, 3.0);

x = y * (9.0 * uPrime / 4.0 * vPrime);
z = y * ((12.0 - 3.0 * uPrime - 20.0 * vPrime) / 4.0 * vPrime);

//toss the xyz results into the array
luv[0] = x; luv[1] = y; luv[2] = z;

//end by converting from XYZ to RGB
luv = XYZtoRGB(luv);
return luv;
}
}

ColorModelTest.java ~ Unit Test Program

/** Unit Test for ColorModel
Author: Daniel J. Tanner
Date: 1/20/2010
Class: CMPT 360 - Computer Graphics
*/

/** This program extends the jUnit TestCase,
in order to test out the colormodel class.
It should be noted that since the colormodel program
deals with doubles, we cannot test that changing from RGB
to some other colorspace and back again will result in
exactly the same value, so we must come up with a way
of determining that said value is close enough to the
original value entered. We will do this by assuming
a standard deviation within .0001 to be accurate enough.
*/

import junit.framework.TestCase;

public class ColorModelTest extends TestCase
{
//Create variables
private double[] someRGB = {1, .5, .5};

/*isCloseEnough function - returns true if there is < .0001 difference
between two doubles
*/
public boolean isCloseEnough(double x, double y)
{
if(Math.abs(x - y) < .01)
return true;
else
return false;
}

/**********************************************************************

Testing Functions

***********************************************************************/
public void testHSV()
{
double[] someHSV = ColorModel.RGBtoHSV(someRGB);
someHSV = ColorModel.HSVtoRGB(someHSV);
for(int index = 0; index < 3; index++)
assertTrue(isCloseEnough(someRGB[index], someHSV[index]));
}

public void testCMY()
{
//Test RGB to CMY and CMY to RGB
double[] someCMY = ColorModel.RGBtoCMY(someRGB);
someCMY = ColorModel.CMYtoRGB(someCMY);
for(int index = 0; index < 3; index++)
assertTrue(isCloseEnough(someRGB[index], someCMY[index]));
}

public void testXYZ()
{
//Test RGB to XYZ and XYZ to RGB
double[] someXYZ = ColorModel.RGBtoXYZ(someRGB);
someXYZ = ColorModel.XYZtoRGB(someXYZ);
for(int index = 0; index < 3; index++)
assertTrue(isCloseEnough(someRGB[index], someXYZ[index]));
}

public void testYIQ()
{
//test YIQ
double[] someYIQ = ColorModel.RGBtoYIQ(someRGB);
someYIQ = ColorModel.YIQtoRGB(someYIQ);
for(int index = 0; index < 3; index++)
assertTrue(isCloseEnough(someRGB[index], someYIQ[index]));
}

public void testLAB()
{
//test L*A*B*
double[] someLAB = ColorModel.RGBtoCIELab(someRGB);
someLAB = ColorModel.CIELabtoRGB(someLAB);
for(int index = 0; index < 3; index++)
assertTrue(isCloseEnough(someRGB[index], someLAB[index]));
}

public void testLUV()
{
//test LUV
double[] someLUV = ColorModel.RGBtoCIELuv(someRGB);
someLUV = ColorModel.CIELuvtoRGB(someLUV);
for(int index = 0; index < 3; index++)
assertTrue(isCloseEnough(someRGB[index], someLUV[index]));
}
}

Wednesday, January 13, 2010

Program for Copying a file (yay Java!)

/** Copy Program
Daniel Tanner
January 13th, 2009
CMPT 352
*/

/** Program description:
This program will take 2 filenames as command line input and copy the first file into the second.
Error will be thrown if the file to be copied does not exist.
User will be asked to confirm if overwriting a file.
*/

//include statements
import java.io.*;
import java.nio.*;

//function prototypes


public class Copy
{
//Main function
public static void main(String[] args) throws IOException
{
//Check to make sure input was entered in the correct format from command line
if(args.length != 2)
{
System.out.println("An error has occured. Please input the file you want to copy from and the file you want to name the copy in the form:");
System.out.println("\"Copy file_to_be_copied.ext new_filename.ext\"");
System.out.print("\n\n");
System.exit(0);
}

//Create variables
FileOutputStream outFile = null;
FileInputStream inFile = null;
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));

//try to open the input file
try
{
inFile = new FileInputStream(args[0]);
}

catch(IOException e)
{
System.err.print(e);
}

//try to open the output file
try
{
outFile = new FileOutputStream(args[1]);
}

catch(IOException e)
{
System.err.println(e);
System.exit(0);
}

//copy operation
try
{
int temp = 0;
while((temp = inFile.read()) != -1)
{
outFile.write(temp);
}
}

catch(IOException e)
{
System.err.println(e);
System.exit(0);
}

//close files
finally
{
if(inFile != null)
inFile.close();
if(outFile != null)
outFile.close();
}
}
}

Tuesday, January 5, 2010

Apologies...

Sorry for the lack of posts lately; I'm back in school now and starting up some new programming classes so I should have some more code up in the near future. I've been itching to write about a number of more political and socioeconomic issues, but I fear I have little to say that I haven't already seen or read elsewhere. Anyways, Happy New Years!

Tuesday, December 8, 2009

Finding a Path Algorithm - Driver Program

The following (and the 3-4 posts before) is an incomplete, not-working-quite-right program I wrote in the equivalent of a CMPT 306 class while at Snow; just tossing it up here to get some feedback on it. Take a gander if ya like, though it's not my best work...

/*
Title: Programming Project 5 - Maze and Creature
Author: Daniel J. Tanner
Class: CS 2420 - Data Abstraction & Problem Solving w/ C++
Date: October 17th, 2005 (latest update)
*/

#include
#include
#include
#include "TannMaze.h"
#include "TannCreature.h"
#include
using namespace std;

//function declarations
void displayGreeting();

int main()
{
displayGreeting();

//set variables
Coord start, end;
int width, height;
char choice;
string filename;
TannMaze basicMaze;
TannCreature bob;
bool success;

//Find out if user has a file he'd like to use or if he'd like to
//manually input the data
cout << "Would you like to get the data from a file?:(y/n) "; cin >> choice;
if(toupper(choice) != 'Y')
{
//get width and height
cout << "input the width: "; cin >> width;
cout << "input the height: "; cin >> height;

//get start and exit
cout << "Please enter the coordinates for the entrance of your\n" << "maze in the form (x y): "; cin >> start.x >> start.y;
cout << "Do the same for the exit: "; cin >> end.x >> end.y;

//adjust for proper array usage
start.x--; start.y--;
end.x--; end.y--;

//generate maze
basicMaze.generateMaze(width, height, start, end);
}
else
{
//get filename
cout << "Please input the name of your file, including the extension: "; cin >> filename;

//generate maze based on file
basicMaze.generateMaze(filename);
}

//create a creature and have it go through the maze after displaying it
cout << "Your maze appears as follows: \n\n";
basicMaze.displayMaze();
cout << endl;
bob.setMaze(basicMaze);

//show the solution to the maze:
cout << "The solution to your maze is as follows: \n\n";
success = bob.findExit();
if(!success)
cout << "Unfortunately your maze is unsolveable.\n\n";
else
{
basicMaze.displayMaze();
cout << endl << endl;
}


return 0;
}

void displayGreeting()
{
cout << "Greetings! This program will generate a maze and provide a solution\n"
<< "should there be one. You can tell the program the width and height\n"
<< "yourself or you can open a file that you've already input the data\n"
<< "into.\n\n";
}

Finding a Path - Creature Class Definition

/*
Title: Creature Class Function Definitions
Author: Daniel J. Tanner
Class: CS 2420 - Data Abstraction & Problem Solving w/ C++
Date: October 17th, 2005 (latest update)
*/

#include
#include
#include
#include "TannCreature.h"
using namespace std;

//Function definitions

/* Default Constructor
Sets the creature to (0,0) and makes the maze pointer point to NULL
*/
TannCreature::TannCreature()
{
position_.y = 0; position_.x = 0;
maze_ = NULL;
}

/* Explicit value constructor
Purpose: This functions will take a maze as a parameter and set the position
of the creature to the start of the maze
Rec./Ref: an instance of the maze class
*/
TannCreature::TannCreature(TannMaze &maze)
{
maze_ = &maze;
position_ = maze.getStart();
}

/* set function
Purpose: this function will do the same as the explicit value constructor, but
will allow it to be done after initialization
*/
void TannCreature::setMaze(TannMaze &maze)
{
maze_ = &maze;
position_ = maze.getStart();
}

/* findExit function
Purpose: This function will begin a set of recursive calls that will take the
creature from the start to the end if possible. It will return a bool
representing success or failure.
Return: bool representing success or failure
*/
bool TannCreature::findExit()
{
//Book problem had a way to have start and end at same point but this program
//doesn't, so it does not make a check to see if the start is the end
if(goNorth())
return true;
else if(goWest())
return true;
else if(goEast())
return true;
else
return false;
}

/* movement functions
Purpose: These functions will move the creature north, west, south, or east,
and return a bool representing success or failure. failure is when
the move north is blocked by a wall or is not inside the maze
If the creature can move in a specified direction, it marks the new
space as path...if it has to backtrack, it marks the space as 'visited'
Return: A bool representing success or failure
*/
//move North function
bool TannCreature::goNorth()
{
if(position_.y - 1 > 0
&& maze_->checkCoord(position_.x, position_.y - 1) != WALL
&& maze_->checkCoord(position_.x, position_.y - 1) != VISITED)
{
position_.y--;
if(maze_->checkCoord(position_.x, position_.y) == EXIT)
return true;
else
{
maze_->mark(position_, PATH);
if(goNorth())
return true;
else if(goWest())
return true;
else if(goEast())
return true;
else
{
maze_->mark(position_, VISITED);
position_.y++;
return false;
}
}
}
else
return false;
}

//move West function
bool TannCreature::goWest()
{
if(position_.x - 1 > 0
&& maze_->checkCoord(position_.x - 1, position_.y) != WALL
&& maze_->checkCoord(position_.x - 1, position_.y) != VISITED)
{
position_.x--;
if(maze_->checkCoord(position_.x, position_.y) == EXIT)
return true;
else
{
maze_->mark(position_, PATH);
if(goNorth())
return true;
else if(goWest())
return true;
else if(goSouth())
return true;
else
{
maze_->mark(position_, VISITED);
position_.x++;
return false;
}
}
}
else
return false;
}

//move East Function
bool TannCreature::goEast()
{
if(position_.x + 1 <>getWidth()
&& maze_->checkCoord(position_.x + 1, position_.y) != WALL
&& maze_->checkCoord(position_.x + 1, position_.y) != VISITED)
{
position_.x++;
if(maze_->checkCoord(position_.x, position_.y) == EXIT)
return true;
else
{
maze_->mark(position_, PATH);
if(goNorth())
return true;
else if(goEast())
return true;
else if(goSouth())
return true;
else
{
maze_->mark(position_, VISITED);
position_.x--;
return false;
}
}
}
else
return false;
}

//move South Function
bool TannCreature::goSouth()
{
if(position_.y + 1 <>getHeight()
&& maze_->checkCoord(position_.x, position_.y + 1) != WALL
&& maze_->checkCoord(position_.x, position_.y + 1) != VISITED)
{
position_.y++;
if(maze_->checkCoord(position_.x, position_.y) == EXIT)
return true;
else
{
maze_->mark(position_, PATH);
if(goWest())
return true;
else if(goEast())
return true;
else if(goSouth())
return true;
else
{
maze_->mark(position_, VISITED);
position_.y--;
return false;
}
}
}
else
return false;
}

Finding a Path Algorithm - Maze Class Definition

/*
Title: Maze Class Function Definitions
Author: Daniel J. Tanner
Class: CS 2420 - Data Abstraction & Problem Solving w/ C++
Date: October 17th, 2005 (latest update)
*/

#include
#include
#include
#include
#include
#include
#include "TannMaze.h"
using namespace std;

//Maze Class Definitions
//Destructor
TannMaze::~TannMaze()
{
delete [] maze;
}

//Constructors
/* Default
Purpose : This constructor will simply create an instance of the Maze
class
and have the 2-d array pointer point to null
Rec./Ref.: N/A
*/
TannMaze::TannMaze()
{
try
{
mazeHeight_ = 5; mazeWidth_ = 5;
start_.x = 2; start_.y = 4;
end_.x = 2; end_.y = 0;
generateMaze();
}
catch(MazeError error)
{throw(error);}
}

/* Explicit Value Constructor
Purpose: To accept from the user a height, a width, and a start and an end
and then to redirect this information to the generateMaze function
Rec.: height, width, start coord and end coord
Call: function generateMaze(height, width, start, end)
*/
TannMaze::TannMaze(int width, int height, Coord &start, Coord &end)
{
cout << "using explicit input constructor to generate maze..." << endl;
try
{
generateMaze(width, height, start, end);
}
catch(MazeError error){throw error;}
}

/* Filename Constructor
Purpose: This constructor will redirect the program to the generateMaze
function that deals with files directly
Rec/Ref: the filename of the file that will be opened and read from
Send: that same filename to the appropriate maze generator function
*/
TannMaze::TannMaze(string filename)
{
try{
generateMaze(filename);
}
catch(MazeError error)
{
throw(error);
}
}

//Maze generation functions
/* Explicit Value Maze Generator
This function will set all the different variables at once and then redirect
the program to the default generateMaze function
*/
void TannMaze::generateMaze(int width, int height, Coord &start, Coord &end)
{
mazeHeight_ = height; mazeWidth_ = width; start_ = start; end_ = end;
try{generateMaze();}
catch(MazeError error)
{ throw(error);}
}

/* Explicit Value (from file) Maze Generator
This function will set all the variables based on a file as described by the
problem definition in the book
*/
void TannMaze::generateMaze(string filename)
{
fstream fileIn(filename.c_str());
if(!fileIn)
throw MazeError("Error opening file " + filename);
int height, width;
Coord start, end;
fileIn >> width >> height >> end.x >> end.y >> start.x >> start.y;
mazeHeight_ = height; mazeWidth_ = width; start_ = start; end_ = end;
try{generateMaze();}
catch(MazeError error)
{ throw(error);}
}



/* Default Maze Generator
This is THE main maze generator function
Purpose: To generate a 2-dimensional array-based maze made up of ascii
characters, and then randomly fill it with walls and open spaces
along with a specific startpoint and a specific endpoint.
Precondition: The height, width, start, and end variables must have already
been assigned to the class' variables for this to work
correctly
it is therefore only able to be called by member functions which
already assign those properties.
*/
void TannMaze::generateMaze()
{
//create the 2d array, throwing an error if there's not enough memory
try
{
maze = new mazeSquare*[mazeWidth_];
for(int index = 0; index < mazeWidth_; index++)
maze[index] = new mazeSquare[mazeHeight_];
}
catch(bad_alloc error) {throw MazeError("Error allocating memory");}

//set up random number generator to be based off current time
srand(unsigned(time(NULL)));

//fill the maze with squares of either WALL or CLEAR
for(int heightCount = 0; heightCount < mazeHeight_; heightCount++)
{
for(int widthCount = 0; widthCount < mazeWidth_; widthCount++)
{
switch(rand() % 2)
{
case 0:
maze[widthCount][heightCount] = WALL;
break;
case 1:
maze[widthCount][heightCount] = CLEAR;
break;
}
}
}

//set the start and end
maze[start_.x][start_.y] = START;
maze[end_.x][end_.y] = EXIT;
}

void TannMaze::displayMaze()const
{
for(int hIndex = 0; hIndex < mazeHeight_; hIndex++)
{
for(int wIndex = 0; wIndex < mazeWidth_; wIndex++)
{
switch(maze[wIndex][hIndex])
{
case WALL:
cout << 'X';
break;
case CLEAR:
cout << ' ';
break;
case EXIT:
cout << 'E';
break;
case START:
cout << 'S';
break;
case PATH:
cout << '@';
break;
case VISITED:
cout << '*';
break;
default:
break;
}
}
cout << endl;
}
}

/* Mark Function
Purpose: This function will change the status of one maze square to visited or to path
Rec.: the location of the square as a coord, and the new status
*/
void TannMaze::mark(const Coord &sqLoc, enum mazeSquare demarcation)
{
maze[sqLoc.x][sqLoc.y] = demarcation;
}

Finding a Path algorithm - Maze Class Declaration

/*
Title: Maze Class Declaration
Author: Daniel J. Tanner
Class: CS 2420 - Data Abstraction & Problem Solving w/ C++
Date: October 17th, 2005 (latest update)
*/

#ifndef TANNMAZE_H
#define TANNMAZE_H

/*This maze will be made up of several individual squares (represented by
characters).
C = a clear space the creature can walk thru
P = the correct path as travelled by the creature from the entrance to the
exit
X = exit of maze
W = a wall that the creature cannot walk through.
S = start of maze
V = a clear space that the creature has visited, but lead to a dead end.
*/

#include
#include
#include
#include
#include
using namespace std;

//Define enumerated data type for squares
enum mazeSquare{CLEAR, WALL, EXIT, START, PATH, VISITED};

//Special structure for handling incoming and outgoing squares
struct Coord
{
int x, y;
};

//Class TannMaze Declaration
class TannMaze
{
private:
mazeSquare **maze;
int mazeHeight_;
int mazeWidth_;
Coord start_;
Coord end_;

public:
//Error class
class MazeError
{
private:
string problem_;
public:
MazeError(string problem) {problem_ = problem;}
string getProblem() {return problem_;}
};

void mark(const Coord &sqLoc, mazeSquare demarcation);
void displayMaze()const;

//inline get & set functions
int getHeight()const {return mazeHeight_;}
int getWidth()const {return mazeWidth_;}
Coord getStart()const {return start_;}
Coord getEnd()const {return end_;}
mazeSquare checkCoord(int y, int x) {return maze[y][x];}
void setStart(Coord &start) {start_ = start;}
void setEnd(Coord &end) {end_ = end;}
void setHeight(int height) {mazeHeight_ = height;}
void setWidth(int width) {mazeWidth_ = width;}

//Maze Generator functions
void generateMaze(int width, int height, Coord &start, Coord &end);
void generateMaze(string filename);
void generateMaze();

//Constructors
TannMaze();
TannMaze(int width, int height, Coord &start, Coord &end);
TannMaze(string filename);

//Destructor
~TannMaze();
};

#endif

Finding a path algorithm - Creature Class Declaration

/*
Title: Creature Class Declaration
Author: Daniel J. Tanner
Class: CS 2420 - Data Abstraction & Problem Solving w/ C++
Date: October 17th, 2005 (latest update)
*/

#include
#include
#include
#include "TannMaze.h"
using namespace std;

//Class declaration
class TannCreature
{
private:
Coord position_;
TannMaze *maze_;
bool goNorth();
bool goSouth();
bool goWest();
bool goEast();

public:
TannCreature();
TannCreature(TannMaze &maze);
void setMaze(TannMaze &maze);
bool findExit();
};

Tuesday, December 1, 2009

Analytical Report on 5 Topics from Speech Class

The following is an analytical report I had to write for my speech class, covering 5 things over 5 pages we studied in class and my opinions/experience with them. Some of it may be kind of common sense stuff and thus rather boring, but lemme know what ye webonauts out there think via comments.

Maslow’s Heirarchy of Needs – The Boomerang Effect

Among the more interesting concepts discussed in our Speech class this semester was “The Boomerang Effect.” This is, basically, a turnaround of a person’s opinion after they have given deeper thought to something they were convinced of earlier on a Peripheral basis. (Peripheral referring to quick-response decisions made when offered reciprocation, consistency, social proof, etc). In my own experiences I have seen and heard many such peripheral persuasions, and my own sense of pride makes me prejudice any argument presented this way, especially after I have agreed to do something based on said agreements. For example, whenever my elder sister asks me for some favor or another (such as recently when she got me to drive her dryer down to a shop to get fixed and back up to her apartment) by way of a “guilt trip” (usually suggesting she’d get my father to carry out said errand, even at the risk of possible injury), I usually find myself resenting her for it. So, yes, the boomerang effect is a real psychological aftereffect.









“It’s For The Children!!” And Other Appeals to Emotion – Logical Fallacy?

Prior to presenting persuasive speeches, we went over a variety of logical fallacies to avoid in making arguments, and while “Appeal to Emotion” isn’t technically a logical fallacy per se, I think it fits in a bit with what we were just discussing (Boomerang Effect) and is thus, well, kind of a logical fallacy. While I can not speak for others, when I hear politicians on television or the internet making arguments based around emotionalism (usually accompanied by a little bit of exaggerated hyperbole) I find myself discouraged from listening to whatever otherwise logical arguments they were trying to make to support a given course of action. A good example of this in recent memory is found in the healthcare debate, where many politicians are using an ever-changing number of “millions of people” who are uninsured as a reason to further regulate hospitals, doctors, and related insurance companies. While it is not necessarily a logical fallacy to point out a societal problem and ask for empathy on behalf of the afflicted, it is at the least distasteful to use the existence of said problem as a reason to “do something.” So, again, while appeal to emotion is not a logical fallacy in and of itself, I think it is fair to say that it could cause a boomerang effect in an audience and is inadvisable, or at least merits careful thought before using.






On Powerpoint Usage – Keep It Simple!

When presenting a speech on a given topic we were advised against using very complex and fancy powerpoints; advice which in my experience is right on the money. A recent project I was doing for my Corporate Finance class required a powerpoint to accompany a ten minute presentation on whether or not starting a software development company was a worthwhile investment. How lucky I was to be in Speech class at the same time! Where many of my classmates had used a wide variety of colors in their powerpoints, and images that often obscured the spreadsheets and numerical figures which were supposed to be the meat of the research; my partner and I had a simple, straight-to-the-point set of slides to get across our main points. While the grades have yet to come in I am reasonably confident that we probably scored fairly well overall, and likely got full points for the powerpoint. Therefore, I have to agree with the book and lectures on powerpoint presentations, that conciseness and clarity are far more important than boisterous effects and fashionista design.









Cultivation Theory – How Accurate Are Our “Informed” Perceptions?

Do TV and the Internet present an accurate image of the world around us? Most of us would likely agree that television and movies give people over-exaggerated perceptions of the kinds of physical beauty and intelligence they should expect in potential mates, for starters. Certainly not every guy has as clean a face as Brad Pitt and certainly not all women are as curvaceous as Angelina Jolie, yet I wonder how many marriages have been broken because one spouse or the other thinks not only that they can find someone better, but that they deserve someone better than whomever they are currently paired with? I have personally seen such “entitled” behavior present in my sisters and female cousins (granted, their chosen beaus are often rather unimpressive individuals…perhaps that is only my own twisted perceptions speaking, though), where they always seem to think that “the grass is greener” someplace or with someone else.
Of course, looks are not the only things that are perceived improperly; I doubt you would find it surprising that a number of political positions held by a number of people are often misrepresented on a daily basis. It almost seems that the more fallacious an argument, the more news coverage it gets. As a for instance, a strong memory of mine is scenes of people pulling cots and mattresses into the House of Representatives back in the middle of the nineties, when Clinton, the president at the time, was vetoing and trying to shut out Republicans from important budget votes. I can not tell you how many people I have run into who credit Clinton with the budget and the net surplus that was arrived at as a result of that moment in history. Then again, maybe it is I who have been given “a spin” on that particular bit of history.

Uses and Gratification Theory

How easy is it to close your ears, hum to yourself, and ignore everything you do not want to hear, only paying attention to the sources you want to listen to? Far too easy, according to our Speech textbook. The idea that people in this day and age who use social media on the internet tend to close their circle off to other points of view is certainly easy to imagine. And surely, there is a bubble I could lock myself into on the net. Take twitter, for example, the much-maligned 140-word-limit social media service. There exists a way of “tweeting” to a certain set of individuals and only that certain set, and you can block and ignore anyone who would say something you do not want to hear. In particular, there’s a “channel” of sorts on twitter known as “#p2” which is full of people who generally hold ‘liberal’ points of view… and a channel called “#tcot” typically representing the opposing side. So here we have two bubbles of mutually exclusive groups and a method available to tune out opposing sides. Does this happen in practice? Surprisingly, no. You see, internet communication has a long history of “trolling,” “flame wars,” and “baiting” in which people go online with the sole purpose of debating people on the other side, either to ridicule them by baiting them into an argument where they look foolish, or to ‘win’ an argument, thus showing off supposed intellectual fortitude. All in all, I think this meme-like behavior will prevent social media users to ever completely cordon themselves off (though some certainly give a good effort).