Ad

How Can I Project A Cube Onto An Axis In A Quick Manner?

- 1 answer

I am going to get the projection of a cube onto an axis. Basically, what I am doing is to get the dot product of every vertex of the cube with the axis and then compare the results to find out the smallest and greatest values. At the end of the day, these two values will tell me from which point of the axis the projected starts and where it ends. I have written the following function for that; however, the thing is that there are a lot of comparisons in it and because I am going to call this function thousands of time my whole code runs so slow. I am looking for an optimization that make my code faster. This function has a lot of comparisons and I am wondering if there is any way that I can minimize the amount of comparisons in it. Any ideas?

The code is written in JavaScript but I am considering doing this on C++ and OpenGL so I am open to suggestions on different programming languages.

function projectCube (axis, cube) {

    Pro = dotProdcut(axis, cube.vertex0);
    minPro = Pro;
    maxPro = Pro;

    Pro = dotProdcut(axis, cube.vertex1);
    if (Pro < minPro) { minPro = Pro; }
    if (Pro > maxPro) { maxPro = Pro; }

    Pro = dotProdcut(axis, cube.vertex2);
    if (Pro < minPro) { minPro = Pro; }
    if (Pro > maxPro) { maxPro = Pro; }

    Pro = dotProdcut(axis, cube.vertex3);
    if (Pro < minPro) { minPro = Pro; }
    if (Pro > maxPro) { maxPro = Pro; }

    Pro = dotProdcut(axis, cube.vertex4);
    if (Pro < minPro) { minPro = Pro; }
    if (Pro > maxPro) { maxPro = Pro; }

    Pro = dotProdcut(axis, cube.vertex5);
    if (Pro < minPro) { minPro = Pro; }
    if (Pro > maxPro) { maxPro = Pro; }

    Pro = dotProdcut(axis, cube.vertex6);
    if (Pro < minPro) { minPro = Pro; }
    if (Pro > maxPro) { maxPro = Pro; }

    Pro = dotProdcut(axis, cube.vertex7);
    if (Pro < minPro) { minPro = Pro; }
    if (Pro > maxPro) { maxPro = Pro; }

    return [minPro, maxPro];

}
Ad

Answer

First of all, use local variables.

2nd. don't use enumerated properties, use Arrays instead. You will get into different situations where you have to process sth on every item of this list, and it is way more readable if you use a loop for this.

and sometimes it is faster to repeat yourself and don't extract anything into a utility-method, but only sometimes!

Well Function-calls have an overhead and therefore a performace-impact, on the other hand, if you inline everything and the function get's to big, the compiler won't even try to optimize (the execution of) your function. And here we're back at: check your bottlenecks with a profiler.

then getting a property off an object is (a tiny tiny bit) more expensive than accessing a local variable, but this are optimizations that only affect your code if you are in some mathematical envoirement, where your code runs several thousand times/frame. On the other hand, can this practice bloat your function, ...

Try this version:

function projectCube (axis, cube) {
    var x = axis.x, 
        y = axis.y, 
        z = axis.z, 
        v, dotProduct, min = Infinity, max = -Infinity, 
        vertices = cube.vertices;

    //in this example it doesn't matter that i am processing the vertices in reverse order,
    //and so i don't have to introduce a length-var and compare the index to it.
    for(var i = vertices.length; i--; ){
        v = vertices[i];
        dotProduct = x*v.x + y*v.y, z*v.z;
        if(dotProduct < min) min = dotProduct;
        if(dotProduct > max) max = dotProduct;
    }
    return [min, max];
}
Ad
source: stackoverflow.com
Ad