Wednesday 14 December 2011

Math, Can't Outrun It

So my next big push is going to involve, adding a new function clone() to gladius.math to allow for cloning of matrices without incurring a new allocation. New branch created for this:  https://github.com/saecob/gladius.math/tree/alpha

Simple enough with a source and destination parameter, copy one into the other.  The next step is to bring transform.js in line with the api.  The difficulty now is understanding the linear algebra used.
  • Scale()
  • Rotate()
  • Translate()
Coming up with some clever tests and resources for this bit of code will be part of the challenge.

After getting things sorted out with transform, one last pass over the unit tests to add some variety will need to be done.  After this maybe it will be time to take a look at our Algorithm scripts.

Monday 12 December 2011

Progress Central

Today after my exam i decided to knock out a bunch of implementations for Gladius.Math.  We now have a 90% complete implementation of the new API and its exciting. Check it out here: https://github.com/saecob/gladius.math

The main work was done to Matrices of the 3x3 and 4x4 variety and of course the ever loved test scripts to go along with them.  The biggest change to get used to is definitely the addition of matrix lists as parameters for almost all of the matrix implementations.

Because of this, i decided to iterate through the matrix list in each respective function and call the base Matrix class to complete the additions.  This looping system may have a pretty big impact on performance for long lists of matrices but for now it seems to be working fine.

Along the way while updating Matrix4, i managed to break the transform methods as they were relying on the old method calls to multiply.  A simple fix but it will go in along with my next big update.  All i would need to do is to add the 2 matrices being multiplied to a list and pass that parameter.

The next big update will include Quaternion and Transform method implementations and tests, along with some way to allow a developer to clone a matrix/vector without incurring a new allocation.

Thursday 1 December 2011

End In Sight

So the end of the school term is fast approaching and I am definitely feeling the crunch.  I pushed up a new commit to my Github account (https://github.com/saecob/gladius.math/tree/develop) under the develop branch in preparation for a major pull request for implementations of all Matrix functions.

Everything seems to be working fine, except for inverse().

Not exactly sure what is wrong yet but i think i may have missed a movement of some sort with the matrix indexes.  Ill take a look at it during the day today.

Next up: Matrix3 and finally Matrix4 which already has implementations but needs to be brought in line with the API.
Also, I need to change some of the tests for Matrix as the API now states that our functions should accept an array of Matrices which is not being tested as of yet.

Check back tonight.

Sunday 27 November 2011

The Matrix, Is Out There

After getting started with the new matrix implementations, having the input parameters as a list of matrices is turning out to be a bit more of a pain than anticipated.

The main downside is the fact that we now have to iterate through the list of matrices in order to perform add(), subtract(), multiply() on each.  We also have to save the results of the previous additions and pass those on for the next set. Something like this:





I haven't run any speed tests but this seems like it may be slow, but for now it will have to do.

Now for my two concerns regarding the API and reality.

  1. Our add(), subtract(), and multiply() functions all take 2 parameters, ml, the list of matrices and result, the optional variable in which we will store our result.  The API specifies that if the list is only one matrix long then we will return the one matrix.  What if the result parameter has values in it and the list only has one matrix? then we will not add the two properly.  Maybe this will never happen, ill wait to ask in iRC.
  2. The inverse(m) function returns the inverse of the given matrix.  A square matrix will only have an inverse if the determinant of that matrix is not zero.  This situation is not covered in the api.
That is about it for now, going to get these cleared up and then move forward.

Thursday 24 November 2011

Boys Are Back In Town

So I've managed to get myself in gear and get contributing to Math.Gladius again.  The math library underwent a massive refactoring in which it was broken down in to small chunks consisting of a script for each size of Vector and Matrix object.

When I left off, work had been completed to Vector through to Vector4 tests included.  Now I am beginning to work on the Matrix functions. There are a few differences in the way we deal with matrices, such as the operation functions (+, -, /, *) taking a list of matrices.

Check it out: https://github.com/alankligman/gladius.math/wiki/Math-api-reference

I will assume the input is always valid, so from there I'll just have to figure out a clever way of:
  • Finding out how many Matrices there are in the list
  • Performing the required operation quickly and efficiently
I'll have more later tonight.

Thursday 10 November 2011

Motivation, Or Lack Therof

Well, during the last month I found myself more and more regularly making excuses not to work on my blog and open source project.  I believe a lack of motivation and poor performance in my remaining 5 courses have lead me to this point.

Now that I have caught up with other assignments for the most part, its time to get back to work on open source.

My first order of business was to get involved with Mozilla Firefox by trying to understand the build process.

This task was much more difficult than initially anticipated, partly because of the Windows machine I am working on. I have a virtual Linux machine which i will also try it on. More specifics coming right up.

Tuesday 4 October 2011

Equality Among Floats

Well the Gladius Math library is coming along swimmingly and is taking shape very quickly now that we have the API outline almost complete.  (https://github.com/alankligman/gladius.math) Check out the wiki section.

After implementing the functions for 2 dimensional vectors [x,y] an interesting issue presented itself in the form of one glaring logic error and a unit test case issue.
  1. In our library we have a function, normalize(v1, result); which returns a unit vector with same direction as the given vector v1.  Result is the optional parameter in which we store the resulting vector.  Our code for this function was as follows:
// Return a Vector(result) with same direction as v having unit length
normalize: function( v, result ) {
   for( var i = 0, len = v.length; i < len; ++ i ) {
     result[i] = v[i] / len;
   }

   return result;
}
 Normalizing a vector is done by calculating its length and dividing each component by the length.  At first glance this code looks to be correct but we will quickly see how a small flaw ruins any results this function returns.
The problem caused by len = v.length. When we use v.length it is in fact returning the length of the array holding our vector, in this case [x,y] which would cause the function to just divide components by 2.
By changing the code to  len = vector.length(v); we open up the next set of problems.  Vector lengths (http://en.wikipedia.org/wiki/Euclidean_vector#Length)
  • By calculating the absolute length of vectors, some pretty unpleasant numbers can be returned as a result.  For example, when we call normalize() for the vector v1 = [12,-5] the resulting vector is expressed as v2 = [(12/13), (-5/13)].  This would not be a problem if a computer were able to show the results as the above expression but of course it can not and it will return a float with a set number of decimals.
  • This problem is compounded when you start to add other operations on the resulting vector which will continue to use the float representation of the result.  This is very evident in the unit tests:
 You can see above that the expected results and the computed results are identical up until the sixth digit after the decimal.  For all intensive purposes this is "equal", we now have to add an equal(v1, v2, e) function which will compare 2 vectors up to a set number of decimals for use to call them equal.

And that is what i'm working on now, as well as figuring out how to compare only a set number of decimals in the Qunit tests.