diff --git a/Handler.java/Handler.java b/Handler.java/Handler.java new file mode 100644 index 0000000..f330918 --- /dev/null +++ b/Handler.java/Handler.java @@ -0,0 +1,181 @@ + +/** + * Receive messages from the BTCommunicator + */ +final Handler myHandler = new Handler() { + @Override + public void handleMessage(Message myMessage) { + switch (myMessage.getData().getInt("message")) { + case BTCommunicator.DISPLAY_TOAST: + showToast(myMessage.getData().getString("toastText"), Toast.LENGTH_SHORT); + break; + case BTCommunicator.STATE_CONNECTED: + connected = true; + programList = new ArrayList(); + connectingProgressDialog.dismiss(); + updateButtonsAndMenu(); + sendBTCmessage(BTCommunicator.NO_DELAY, BTCommunicator.GET_FIRMWARE_VERSION, 0, 0); + break; + case BTCommunicator.MOTOR_STATE: + + if (myBTCommunicator != null) { + byte[] motorMessage = myBTCommunicator.getReturnMessage(); + int position = byteToInt(motorMessage[21]) + (byteToInt(motorMessage[22]) << 8) + (byteToInt(motorMessage[23]) << 16) + + (byteToInt(motorMessage[24]) << 24); + showToast(getResources().getString(R.string.current_position) + position, Toast.LENGTH_SHORT); + } + + break; + + case BTCommunicator.STATE_CONNECTERROR_PAIRING: + connectingProgressDialog.dismiss(); + destroyBTCommunicator(); + break; + + case BTCommunicator.STATE_CONNECTERROR: + connectingProgressDialog.dismiss(); + case BTCommunicator.STATE_RECEIVEERROR: + case BTCommunicator.STATE_SENDERROR: + + destroyBTCommunicator(); + if (btErrorPending == false) { + btErrorPending = true; + // inform the user of the error with an AlertDialog + AlertDialog.Builder builder = new AlertDialog.Builder(thisActivity); + builder.setTitle(getResources().getString(R.string.bt_error_dialog_title)) + .setMessage(getResources().getString(R.string.bt_error_dialog_message)).setCancelable(false) + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + btErrorPending = false; + dialog.cancel(); + selectNXT(); + } + }); + builder.create().show(); + } + + break; + + case BTCommunicator.FIRMWARE_VERSION: + + if (myBTCommunicator != null) { + byte[] firmwareMessage = myBTCommunicator.getReturnMessage(); + // check if we know the firmware + boolean isLejosMindDroid = true; + for (int pos=0; pos<4; pos++) { + if (firmwareMessage[pos + 3] != LCPMessage.FIRMWARE_VERSION_LEJOSMINDDROID[pos]) { + isLejosMindDroid = false; + break; + } + } + if (isLejosMindDroid) { + mRobotType = R.id.robot_type_4; + setUpByType(); + } + // afterwards we search for all files on the robot + sendBTCmessage(BTCommunicator.NO_DELAY, BTCommunicator.FIND_FILES, 0, 0); + } + + break; + + case BTCommunicator.FIND_FILES: + + if (myBTCommunicator != null) { + byte[] fileMessage = myBTCommunicator.getReturnMessage(); + String fileName = new String(fileMessage, 4, 20); + fileName = fileName.replaceAll("\0",""); + + if (mRobotType == R.id.robot_type_4 || fileName.endsWith(".nxj") || fileName.endsWith(".rxe")) { + programList.add(fileName); + } + + // find next entry with appropriate handle, + // limit number of programs (in case of error (endless loop)) + if (programList.size() <= MAX_PROGRAMS) + sendBTCmessage(BTCommunicator.NO_DELAY, BTCommunicator.FIND_FILES, + 1, byteToInt(fileMessage[3])); + } + + break; + + case BTCommunicator.PROGRAM_NAME: + if (myBTCommunicator != null) { + byte[] returnMessage = myBTCommunicator.getReturnMessage(); + startRXEprogram(returnMessage[2]); + } + + break; + + case BTCommunicator.SAY_TEXT: + if (myBTCommunicator != null) { + byte[] textMessage = myBTCommunicator.getReturnMessage(); + // evaluate control byte + byte controlByte = textMessage[2]; + // BIT7: Language + if ((controlByte & 0x80) == 0x00) + mTts.setLanguage(Locale.US); + else + mTts.setLanguage(Locale.getDefault()); + // BIT6: Pitch + if ((controlByte & 0x40) == 0x00) + mTts.setPitch(1.0f); + else + mTts.setPitch(0.75f); + // BIT0-3: Speech Rate + switch (controlByte & 0x0f) { + case 0x01: + mTts.setSpeechRate(1.5f); + break; + case 0x02: + mTts.setSpeechRate(0.75f); + break; + + default: mTts.setSpeechRate(1.0f); + break; + } + + String ttsText = new String(textMessage, 3, 19); + ttsText = ttsText.replaceAll("\0",""); + showToast(ttsText, Toast.LENGTH_SHORT); + mTts.speak(ttsText, TextToSpeech.QUEUE_FLUSH, null); + } + + break; + + case BTCommunicator.VIBRATE_PHONE: + if (myBTCommunicator != null) { + byte[] vibrateMessage = myBTCommunicator.getReturnMessage(); + Vibrator myVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + myVibrator.vibrate(vibrateMessage[2]*10); + } + + break; + + /* NUEVO */ + case BTCommunicator.UPDATE_SENSOR: + /*String msg2str = ""; + Log.d("MINDDroidCV.java", "UPDATE SENSORS HANDLER");*/ + if(myBTCommunicator != null) { + byte[] sensor_message = myBTCommunicator.getReturnMessage(); + if(sensor_message[3] == 0){ + // Sensor de luz. + lightSensor = (sensor_message[9] << 8) + sensor_message[8]; + /*for(int i = 0; i < sensor_message.length; ++i) + msg2str += String.format("%02x ", sensor_message[i]); + msg2str = String.format("%s :: VALUE %d", msg2str, lightSensor);*/ + }else if(sensor_message[3] == 1){ + // Sensor de tacto. + touchSensor = (sensor_message[11] << 8) + sensor_message[10]; + /*for(int i = 0; i < sensor_message.length; ++i) + msg2str += String.format("%02x", sensor_message[i]); + msg2str = String.format("%s :: VALUE %d", msg2str, touchSensor);*/ + } + } + /*Log.d("MINDDroidCV.java", msg2str);*/ + + break; + /* NUEVO */ + } + } +}; diff --git a/Makefile/Makefile b/Makefile/Makefile new file mode 100644 index 0000000..4a5cdcd --- /dev/null +++ b/Makefile/Makefile @@ -0,0 +1,24 @@ +CXX = g++ +TARGET = +OBJECTS = +DEPENDS = $(OBJECTS:.o=.d) +CXXFLAGS = -ansi -pedantic -Wall +LDLIBS = + +all: CXXFLAGS += -O2 -D_NDEBUG +all: $(TARGET) + +debug: CXXFLAGS += -g +debug: $(TARGET) + +$(TARGET): $(OBJECTS) + $(CXX) -o $(TARGET) $(OBJECTS) $(CXXFLAGS) $(LDLIBS) + +-include $(DEPENDS) + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $*.cpp -o $*.o + $(CXX) -MM $(CXXFLAGS) $*.cpp > $*.d + +clean: + $(RM) $(TARGET) $(OBJECTS) $(DEPENDS) diff --git a/Makefile/README.md b/Makefile/README.md new file mode 100644 index 0000000..c678471 --- /dev/null +++ b/Makefile/README.md @@ -0,0 +1 @@ +A simple and common GNU Makefile template for C/C++ diff --git a/MotorTest.java/MotorTest.java b/MotorTest.java/MotorTest.java new file mode 100644 index 0000000..cc115dd --- /dev/null +++ b/MotorTest.java/MotorTest.java @@ -0,0 +1,120 @@ +import lejos.nxt.Button; +import lejos.nxt.LCD; +import lejos.nxt.Motor; + +public class MotorTest{ + private static final int MAX_CHOICES = 8; + private static final int MAX_ROTATION_DEGREES = 3600; + + public static void main(String[] args){ + boolean done = false; + int choice = 0; + + printMenu(choice); + + while(!done){ + switch(Button.waitForAnyPress()){ + case Button.ID_ENTER: + startMotors(choice); + break; + + case Button.ID_LEFT: + choice = (choice - 1 < 0) ? MAX_CHOICES - 1 : choice - 1; + break; + + case Button.ID_RIGHT: + choice = (choice + 1) % MAX_CHOICES; + break; + + default: + case Button.ID_ESCAPE: + done = true; + break; + } + + printMenu(choice); + } + } + + private static void printMenu(int choice){ + LCD.clear(); + LCD.drawString("Motors:", 0, 0); + printMotorChoiceLine(choice); + LCD.drawString("ENTER: EXEC", 0, 2); + LCD.drawString("ESC: QUIT", 0, 3); + } + + private static void startMotors(final int choice){ + Motor.A.stop(true); + Motor.B.stop(true); + Motor.C.stop(true); + + switch(choice){ + case 0: + Motor.A.rotate(MAX_ROTATION_DEGREES, true); + Motor.B.rotate(MAX_ROTATION_DEGREES, true); + Motor.C.rotate(MAX_ROTATION_DEGREES, true); + break; + case 1: + Motor.A.rotate(MAX_ROTATION_DEGREES, true); + Motor.B.rotate(MAX_ROTATION_DEGREES, true); + break; + case 2: + Motor.B.rotate(MAX_ROTATION_DEGREES, true); + Motor.C.rotate(MAX_ROTATION_DEGREES, true); + break; + case 3: + Motor.A.rotate(MAX_ROTATION_DEGREES, true); + Motor.C.rotate(MAX_ROTATION_DEGREES, true); + break; + case 4: + Motor.A.rotate(MAX_ROTATION_DEGREES, true); + break; + case 5: + Motor.B.rotate(MAX_ROTATION_DEGREES, true); + break; + case 6: + Motor.C.rotate(MAX_ROTATION_DEGREES, true); + break; + case 7: + Motor.A.stop(true); + Motor.B.stop(true); + Motor.C.stop(true); + break; + default: + break; + } + } + + private static void printMotorChoiceLine(final int choice){ + switch(choice){ + case 0: + LCD.drawString("A - B - C", 0, 1); + break; + case 1: + LCD.drawString("A - B", 0, 1); + break; + case 2: + LCD.drawString("B - C", 0, 1); + break; + case 3: + LCD.drawString("A - C", 0, 1); + break; + case 4: + LCD.drawString("A", 0, 1); + break; + case 5: + LCD.drawString("B", 0, 1); + break; + case 6: + LCD.drawString("C", 0, 1); + break; + case 7: + LCD.drawString("STOP ALL", 0, 1); + break; + default: + LCD.drawString("INVALID", 0, 1); + break; + } + } +} diff --git a/MotorTest.java/README.md b/MotorTest.java/README.md new file mode 100644 index 0000000..8b0f9ad --- /dev/null +++ b/MotorTest.java/README.md @@ -0,0 +1 @@ +A LejOS application to start/stop the motors of a LEGO Mindstorms NXT. \ No newline at end of file diff --git a/colorbarcode1.py/README.md b/colorbarcode1.py/README.md new file mode 100644 index 0000000..af1f310 --- /dev/null +++ b/colorbarcode1.py/README.md @@ -0,0 +1 @@ +A naive movie color barcode generator. \ No newline at end of file diff --git a/colorbarcode1.py/colorbarcode1.py b/colorbarcode1.py/colorbarcode1.py new file mode 100644 index 0000000..d28aad9 --- /dev/null +++ b/colorbarcode1.py/colorbarcode1.py @@ -0,0 +1,40 @@ +import os +import cv2 +import numpy as np + +def colorbarcode( path ): + if not os.access( path, os.R_OK ): + raise Exception( "File " + path + " does not exists or is not readable." ) + + video = cv2.VideoCapture( path ) + + if not video.isOpened(): + raise Exception( "File " + path + " is not a valid video file." ) + + barcode = [] + + ret = True + i = 1 + while ret: + ret, frame = video.read() + + if frame is None: + break + + col = cv2.resize( frame, ( 1, 480 ), fx = 0, fy = 0, interpolation = cv2.INTER_AREA ) + barcode.append( col ) + + if i % 100 == 0: + print "Processed %d frames " % i + i += 1 + + print "Processed %d frames " % i + + out = np.zeros( ( 480, 0, 3), dtype = barcode[ 0 ].dtype ) + + for i in xrange( len( barcode ) ): + out = np.hstack( ( out, barcode[ i ] ) ) + + cv2.imwrite( "barcode.png", out ) + + video.release() \ No newline at end of file diff --git a/combineBMP.java/README.md b/combineBMP.java/README.md new file mode 100644 index 0000000..335bf33 --- /dev/null +++ b/combineBMP.java/README.md @@ -0,0 +1 @@ +Combine two Android Bitmaps side by side. \ No newline at end of file diff --git a/combineBMP.java/combineBMP.java b/combineBMP.java/combineBMP.java new file mode 100644 index 0000000..1d155d4 --- /dev/null +++ b/combineBMP.java/combineBMP.java @@ -0,0 +1,23 @@ +/** + *

This method combines two images into one by rendering them side by side.

+ * + * @param left The image that goes on the left side of the combined image. + * @param right The image that goes on the right side of the combined image. + * @return The combined image. + */ +private Bitmap combineBitmaps(final Bitmap left, final Bitmap right){ + // Get the size of the images combined side by side. + int width = left.getWidth() + right.getWidth(); + int height = left.getHeight() > right.getHeight() ? left.getHeight() : right.getHeight(); + + // Create a Bitmap large enough to hold both input images and a canvas to draw to this + // combined bitmap. + Bitmap combined = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(combined); + + // Render both input images into the combined bitmap and return it. + canvas.drawBitmap(left, 0f, 0f, null); + canvas.drawBitmap(right, left.getWidth(), 0f, null); + + return combined; +} diff --git a/convertExposureTime.c/README.md b/convertExposureTime.c/README.md new file mode 100644 index 0000000..c095188 --- /dev/null +++ b/convertExposureTime.c/README.md @@ -0,0 +1 @@ +Exposure time conversion between two f-stops. \ No newline at end of file diff --git a/convertExposureTime.c/convertExposureTime.c b/convertExposureTime.c/convertExposureTime.c new file mode 100644 index 0000000..95af542 --- /dev/null +++ b/convertExposureTime.c/convertExposureTime.c @@ -0,0 +1,15 @@ +/* A function to convert the exposure time between two f-stops. + * Usefull for pinhole cameras. See http://www.pinhole.cz/en/pinholecameras/exposure_01.html + * + * Parameters: + * *) f_from: The f-stop to convert from. + * *) f_to: The f-stop to convert to. + * *) exp_time: The exposure time for the aperture f_from. + * + * Return: + * The exposure time for aperture f_to. + */ +float convertExposureTime(int f_from, int f_to, float exp_time){ + float aux = (float)f_to / (float)f_from; + return time * (aux * aux); +} diff --git a/cube.c/README.md b/cube.c/README.md new file mode 100644 index 0000000..36c03cc --- /dev/null +++ b/cube.c/README.md @@ -0,0 +1 @@ +Render a unit cube with classic OpenGL. TexCoords are a bit wonky. \ No newline at end of file diff --git a/cube.c/cube.c b/cube.c/cube.c new file mode 100644 index 0000000..1d2f686 --- /dev/null +++ b/cube.c/cube.c @@ -0,0 +1,69 @@ +static void render_cube() { + glBegin(GL_QUADS); { + /* Front face. */ + glNormal3f(-1.0f, 0.0f, 0.0f); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(-0.5f, 0.5f, -0.5); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(-0.5f, -0.5f, -0.5); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(-0.5f, -0.5f, 0.5f); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(-0.5f, 0.5f, 0.5f); + + /* Back Face. */ + glNormal3f(1.0f, 0.0f, 0.0f); + glTexCoord2f(0.0f, 0.0f); + glVertex3f( 0.5f, 0.5f, -0.5); + glTexCoord2f(0.0f, 1.0f); + glVertex3f( 0.5f, 0.5f, 0.5f); + glTexCoord2f(1.0f, 1.0f); + glVertex3f( 0.5f, -0.5f, 0.5f); + glTexCoord2f(1.0f, 0.0f); + glVertex3f( 0.5f, -0.5f, -0.5); + + /* Top. */ + glNormal3f(0.0f, 0.0f, 1.0f); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(-0.5f, -0.5f, 0.5f); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(0.5f, -0.5f, 0.5f); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(0.5f, 0.5f, 0.5f); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(-0.5f, 0.5f, 0.5f); + + /* Bottom. */ + glNormal3f(0.0f, 0.0f, -1.0f); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(-0.5f, -0.5f, -0.5f); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(-0.5f, 0.5f, -0.5f); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(0.5f, 0.5f, -0.5f); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(0.5f, -0.5f, -0.5f); + + /* Left side. */ + glNormal3f(0.0f, -1.0f, 0.0f); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(-0.5f, -0.5f, -0.5); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(0.5f, -0.5f, -0.5); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(0.5f, -0.5f, 0.5f); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(-0.5f, -0.5f, 0.5f); + + /* Right side. */ + glNormal3f(0.0f, 1.0f, 0.0f); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(-0.5f, 0.5f, -0.5); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(-0.5f, 0.5f, 0.5f); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(0.5f, 0.5f, 0.5f); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(0.5f, 0.5f, -0.5); + } glEnd(); +} diff --git a/exceptions.h/README.md b/exceptions.h/README.md new file mode 100644 index 0000000..b7551a4 --- /dev/null +++ b/exceptions.h/README.md @@ -0,0 +1 @@ +Some practice with setjmp and longjmp. \ No newline at end of file diff --git a/exceptions.h/exceptions.h b/exceptions.h/exceptions.h new file mode 100644 index 0000000..89a4a00 --- /dev/null +++ b/exceptions.h/exceptions.h @@ -0,0 +1,16 @@ +#ifndef EXCEPTIONS_H +#define EXCEPTIONS_H + +#include + +static jmp_buf env; + +typedef int exception_t; + +exception_t excptno; + +#define try if ((excptno = setjmp(env)) == 0) +#define catch else +#define throw(X) longjmp(env, X); + +#endif diff --git a/exceptions.h/main.c b/exceptions.h/main.c new file mode 100644 index 0000000..8198db5 --- /dev/null +++ b/exceptions.h/main.c @@ -0,0 +1,17 @@ +#include +#include "exceptions.h" + +void f() { + throw(89); + printf("All good.\n"); +} + +int main(void) { + try { + f(); + } catch { + printf("Caught %d!\n", excptno); + } + + return 0; +} diff --git a/glut_template.cpp/Makefile b/glut_template.cpp/Makefile new file mode 100644 index 0000000..2c499e8 --- /dev/null +++ b/glut_template.cpp/Makefile @@ -0,0 +1,17 @@ +TARGET = +OBJECTS = +HEADERS = +CXX = g++ +CXXFLAGS = -Wall -ansi -pedantic -g +LDLIBS = -lm -lglut -lGLU -lGL # GNU/Linux libs +# LDLIBS = -lm -framework OpenGL -framework GLUT # Os X libs + +.PHONY: all +all: $(TARGET) + +$(TARGET): $(OBJECTS) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS) + +.PHONY: clean +clean: + $(RM) $(TARGET) $(OBJECTS) diff --git a/glut_template.cpp/README.md b/glut_template.cpp/README.md new file mode 100644 index 0000000..f2ea4d3 --- /dev/null +++ b/glut_template.cpp/README.md @@ -0,0 +1 @@ +Template for glut applications on GNU/Linux and Os X. \ No newline at end of file diff --git a/glut_template.cpp/glut_template.cpp b/glut_template.cpp/glut_template.cpp new file mode 100644 index 0000000..b72df5b --- /dev/null +++ b/glut_template.cpp/glut_template.cpp @@ -0,0 +1,198 @@ +#include +#include +#include + +#include +#ifndef __APPLE__ + #include +#else + #include +#endif +#include +#include +#include +#include + +using namespace glm; + +static const char * APP_TITLE = "GLUT Template"; + +const float NEAR_CLIP_PLANE = 0.01f; +const float FAR_CLIP_PLANE = 100.0f; +const float FIELD_OF_VIEW = 45.0f; +const glm::vec4 CLEAR_COLOR = glm::vec4(0.25f, 0.25f, 0.4f, 1.0f); + +#define OUTPUT_REDIR +#ifdef OUTPUT_REDIR +static FILE * fout; +static FILE * ferr; +#endif + +static int win_width = 800; +static int win_height = 600; + +static glm::vec3 g_eye_position = glm::vec3(0.0f, 0.0f, -2.3f); +static int g_mouse_button = -1; +static int g_mouse_x = 0; +static int g_mouse_y = 0; +static float g_zoom_factor = 1.0f; +static float g_rotation_angle = 0.0f; +static float g_fov_mod = 1.0f; + +static glm::mat4 g_projection_matrix = glm::mat4(); +static glm::mat4 g_model_view_matrix = glm::mat4(); +static glm::mat4 g_rotation_matrix = glm::mat4(); + +static void init_gl(void); +static void reshape(int _w, int _h); +static void keyboard(unsigned char key, int x, int y); +static void release_key(unsigned char key, int x, int y); +static void mouse(int button, int state, int x, int y); +static void motion(int x, int y); +static void idle(void); +static void render_scene(void); +static void clean_up(void); + +int main(int argc, char ** argv) { +#ifdef OUTPUT_REDIR + fout = freopen("stdout.txt", "w", stdout); + ferr = freopen("stderr.txt", "w", stderr); +#endif + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); + glutInitWindowPosition(10, 10); + glutInitWindowSize(win_width, win_height); + glutCreateWindow(APP_TITLE); + glutKeyboardFunc(keyboard); + glutKeyboardUpFunc(release_key); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(idle); + glutDisplayFunc(render_scene); + glutReshapeFunc(reshape); + + if (!gladLoadGL()) { + printf("Something went wrong!\n"); + exit(EXIT_FAILURE); + } + + atexit(clean_up); + init_gl(); + + glutMainLoop(); + + return EXIT_SUCCESS; +} + +void init_gl(void) { + /* Enable back-face culling. */ + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + /* Enable Z-buffer. */ + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + + /* Set OpenGL state. */ + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} + +void reshape(int _w, int _h) { + /* Reset viewport */ + win_width = _w; + win_height = _h == 0 ? 1 : _h; + glViewport(0, 0, win_width, win_height); + + /* Recalculate projection matrix. */ + g_projection_matrix = glm::perspective( + FIELD_OF_VIEW * (g_fov_mod <= 0.5f ? 0.5f : g_fov_mod), + static_cast(win_width) / win_height, + NEAR_CLIP_PLANE, + FAR_CLIP_PLANE + ); + + glutPostRedisplay(); +} + +void keyboard(unsigned char key, int x, int y) { + switch (key) { + case 27: + exit(0); + break; + } + + glutPostRedisplay(); +} + +void release_key(unsigned char key, int x, int y) { + glutPostRedisplay(); +} + +void mouse(int button, int state, int x, int y) { + if (button == 3) { + // Zoom in when the user moves the mouse wheel up + if (state == GLUT_UP) return; + else g_zoom_factor *= 1.05f; + } + else if (button == 4) { + // Zoom out when the user moves the mouse wheel down + if (state == GLUT_UP) return; + else g_zoom_factor *= 0.95f; + } + else { + // Else, save the state of the mouse + g_mouse_x = x; + g_mouse_y = y; + g_mouse_button = button; + } + + glutPostRedisplay(); +} + +void motion(int x, int y) { + // Compute the movement vector of the mouse + glm::vec2 move_vector = glm::vec2(x - g_mouse_x, y - g_mouse_y); + + // Rotate when the user moves the mouse with the left button pressed + if (g_mouse_button == GLUT_LEFT_BUTTON) { + if (abs(x - g_mouse_x) > 0.01f || abs(y - g_mouse_y) > 0.01f) { + // Compute a rotation matrix using the movement vector as axis of rotation, and the length of the vector as the rotation angle + glm::mat4 rotation = glm::rotate(glm::mat4x4(), glm::length(move_vector) * 3.14f / 180.0f, glm::vec3(move_vector.y, move_vector.x, 0.0f)); + g_rotation_matrix = rotation * g_rotation_matrix; + } + } + else if (g_mouse_button == GLUT_RIGHT_BUTTON) { + // Compute a translation matrix with 1 percent of the movement vector and translate the eye + glm::mat4 translation_matrix = glm::translate(glm::mat4x4(), glm::vec3(move_vector.x * 0.01f, -move_vector.y * 0.01f, 0.0f)); + g_eye_position = translation_matrix * glm::vec4(g_eye_position.x, g_eye_position.y, g_eye_position.z, 1.0f); + } + + // Save the current mouse position + g_mouse_x = x; + g_mouse_y = y; + + glutPostRedisplay(); +} + +void idle(void) { + glutPostRedisplay(); +} + +void render_scene(void) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + + glFlush(); + glFinish(); + glutSwapBuffers(); +} + +void clean_up(void) { +#ifdef OUTPUT_REDIR + fclose(fout); + fclose(ferr); +#endif +} diff --git a/hash.sh/README.md b/hash.sh/README.md new file mode 100644 index 0000000..3a67122 --- /dev/null +++ b/hash.sh/README.md @@ -0,0 +1 @@ +A little toy shell script inspired by Bitcoin mining. \ No newline at end of file diff --git a/hash.sh/hash.sh b/hash.sh/hash.sh new file mode 100644 index 0000000..7bdf0ba --- /dev/null +++ b/hash.sh/hash.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +VAL="0" + +while : +do + echo `cat $1` "$VAL" | sha256sum | sha256sum | grep "^0\{$2\}" + if [[ $? -eq 0 ]] + then + break + fi + VAL=`expr $VAL + "1"` +done diff --git a/read_off.pl/README.md b/read_off.pl/README.md new file mode 100644 index 0000000..889ec13 --- /dev/null +++ b/read_off.pl/README.md @@ -0,0 +1 @@ +A little project to learn the basics of Perl. A Perl script that reads a 3D model in the OFF file format and spits it's data to standard output. \ No newline at end of file diff --git a/read_off.pl/read_off.pl b/read_off.pl/read_off.pl new file mode 100644 index 0000000..1410287 --- /dev/null +++ b/read_off.pl/read_off.pl @@ -0,0 +1,84 @@ +#! /usr/bin/env perl +use 5.010; +use strict; +use warnings; + +my $status = 0; + +foreach my $arg (0 .. $#ARGV){ + say "---------------------------------------------------------------------"; + say "FILE: $ARGV[$arg]"; + say "---------------------------------------------------------------------"; + $status = &read_off_file($ARGV[$arg]); +} + +exit $status; + +########################## +# SUBROUTINE DEFINITIONS # +########################## + +sub read_off_file { + return unless defined wantarray; + + # Local variable definitions. + my $v_ind = 0; + my $f_ind = 0; + my $status = 0; + my $meta_read = 0; + + my $arg = shift @_; + + open (my $file, '<', $arg) or die "$arg: $!"; + my $row = <$file>; + chomp $row; + + # Check if the first line in the file matches the "OFF" string. If it + # doesn't then this file is not a valid OFF file. + if(not $row =~ /OFF/){ + say "$arg is not an OFF file."; + $status = 1; + last; + }else{ + while($row = <$file>){ + chomp $row; + # Remove leading and trailing whitespace. + $row =~ s/^\s+|\s+$//g; + + if(not $meta_read and $row =~ /^(((\d+)(\s+)){2})(\d+)$/){ + # If the line is exactly three integers separated by arbitrary + # whitespace then it is the number of vertices, faces and edges. + my ($num_v, $num_f, $num_e) = split(/\s+/, $row); + say "Number of vertices: $num_v"; + say "Number of faces: $num_f"; + say "Number of edges: $num_e"; + $meta_read = 1; + + }elsif($row =~ /^(((\-?)(\d+)(\.(\d+))?(\s+)){2})((\-?)(\d+)(\.(\d+))?)$/){ + # If the line has three numbers (integer or floating point) + # surrounded by arbitrary whitespace then it is a vertex. + my ($x, $y, $z) = split(/\s+/, $row); + say "Vertex #$v_ind: ($x, $y, $z)"; + $v_ind = $v_ind + 1; + + }elsif($row =~ /(\d+)(((\s+)(\d+)){3,})/){ + # If the line has one integer followed by at least three or more + # integers, all of them separated by arbitrary whitespace, then + # it is a polygon. + my @face = split(/\s+/, $row); + print "Face $f_ind: Num vertices = $face[0] - "; + print "v::$face[$_] " foreach 1 .. $#face; + print "\n"; + $f_ind = $f_ind + 1; + }elsif($row =~ /^(\s*)#(.*)/ or $row =~ /^(s*)$/){ + say "Skipping comment or empty line."; + }else{ + say "Unrecognized line."; + } + } + } + + close $file; + + return $status; +} diff --git a/samplings.m/README.md b/samplings.m/README.md new file mode 100644 index 0000000..48f3d19 --- /dev/null +++ b/samplings.m/README.md @@ -0,0 +1 @@ +Based on explanations from scrathapixel.com, stackoverflow.com and Wolfram Mathworld. \ No newline at end of file diff --git a/samplings.m/samplings.m b/samplings.m/samplings.m new file mode 100644 index 0000000..ac93f63 --- /dev/null +++ b/samplings.m/samplings.m @@ -0,0 +1,46 @@ +function [nt, nb] = coord_system(n) + if abs(n(1)) > abs(n(2)) + nt = [n(3), 0, -n(1)] / norm([n(3), 0, -n(1)]); + else + nt = [0, -n(3), n(2)] / norm([0, -n(3), n(2)]); + endif + v = cross(n, nt); + nb = v / norm(v); +endfunction + +function [x, y, z] = disk_sampling(c, n, r) + rr = rand() * r; + [nt, nb] = coord_system(n); + + theta = rand() * 2 * pi; + x = c(1) + (rr * cos(theta) * nt(1)) + (rr * sin(theta) * nb(1)); + y = c(2) + (rr * cos(theta) * nt(2)) + (rr * sin(theta) * nb(2)); + z = c(3) + (rr * cos(theta) * nt(3)) + (rr * sin(theta) * nb(3)); +endfunction + +function [x, y, z] = sphere_sampling(c, r) + theta = rand() * 2 * pi; + u = (rand() * 2) - 1; + sqrt1muu = sqrt(1 - (u * u)); + x = (r * sqrt1muu * cos(theta)) + c(1); + y = (r * sqrt1muu * sin(theta)) + c(2); + z = (r * u) + c(3); +endfunction + +function test_sampling() + x = []; + y = []; + z = []; + for i = 1:5000 + %[sx, sy, sz] = disk_sampling([0, 0.75, -1], [0, -1, 0], 0.15); + [sx, sy, sz] = sphere_sampling([0, 0.75, -1], 0.15); + x(end + 1) = sx; + y(end + 1) = sy; + z(end + 1) = sz; + endfor + scatter3(x, y, z); + axis([-2, 2, -2, 2, -2, 2]); + xlabel('x'); + ylabel('y'); + zlabel('z'); +endfunction diff --git a/sendMessage.java/sendMessage.java b/sendMessage.java/sendMessage.java new file mode 100644 index 0000000..fd1ee51 --- /dev/null +++ b/sendMessage.java/sendMessage.java @@ -0,0 +1,18 @@ +private void sendToast(String toastText) { + Bundle myBundle = new Bundle(); + myBundle.putInt("message", DISPLAY_TOAST); + myBundle.putString("toastText", toastText); + sendBundle(myBundle); +} + +private void sendState(int message) { + Bundle myBundle = new Bundle(); + myBundle.putInt("message", message); + sendBundle(myBundle); +} + +private void sendBundle(Bundle myBundle) { + Message myMessage = myHandler.obtainMessage(); + myMessage.setData(myBundle); + uiHandler.sendMessage(myMessage); +}