-
-
Save thomasballinger/5750952 to your computer and use it in GitHub Desktop.
console.log("collide.js loaded"); | |
function Ray(dx, dy, dz, x, y, z){ | |
if (x === undefined){x = 0}; | |
if (y === undefined){y = 0}; | |
if (z === undefined){z = 0}; | |
this.dx = dx; | |
this.dy = dy; | |
this.dz = dz; | |
this.x = x; | |
this.y = y; | |
this.z = z; | |
} | |
function Sphere(x, y, z, r){ | |
this.x = x; | |
this.y = y; | |
this.z = z; | |
this.r = r; | |
} | |
Sphere.prototype = { | |
getIntersections : function(ray){ | |
var x1 = ray.x; | |
var y1 = ray.y; | |
var z1 = ray.z; | |
var x2 = ray.x + ray.dx; | |
var y2 = ray.y + ray.dy; | |
var z2 = ray.z + ray.dz; | |
var x3 = this.x; | |
var y3 = this.y; | |
var z3 = this.z; | |
var r = this.r; | |
var pow = Math.pow | |
var a = pow(x2 - x1, 2) + pow(y2 - y1, 2) + pow(z2 - z1, 2); | |
var b = 2*((x2 - x1)*(x1 - x3) + (y2 - y1)*(y1 - y3) + (z2 - z1)*(z1 - z3) ); | |
var c = x3 * x3 + y3 * y3 + z3 * z3 + x1 * x1 + y1 * y1 + z1 * z1 - 2*(x3*x1 + y3*y1 + z3*z1) - r * r; | |
var radicand = b * b - 4*a*c | |
var xyz_from_u = function(u) { | |
return [x1 + u * (x2 - x1), y1 + u * (y2 - y1), z1 + u * (z2 - z1)]; | |
} | |
if (radicand < 0){ | |
return []; | |
} else if (radicand == 0){ | |
return [xyz_from_u(-b / (2*a))]; | |
} else if (radicand > 0){ | |
return [xyz_from_u((-b + Math.sqrt(radicand)) / (2*a)), xyz_from_u((-b - Math.sqrt(radicand)) / (2*a))]; | |
} else { | |
throw "logic error!"; | |
} | |
} | |
}; | |
function assertEqual(thing1, thing2){ | |
if (thing1 !== thing2){ | |
throw {message: ""+thing1+" is not equal to "+thing2, name : "Failed Test"}; | |
} else { | |
console.log("test passed: "+thing1+" is equal to "+thing2); | |
} | |
} | |
function test_sphere_intersection(){ | |
var sphere = new Sphere(4,0,0,1); | |
var ray = new Ray(1,0,0); | |
var intersections = sphere.getIntersections(ray); | |
intersections.sort(); | |
assertEqual(intersections[0][0], 3); | |
assertEqual(intersections[0][1], 0); | |
assertEqual(intersections[0][2], 0); | |
assertEqual(intersections[1][0], 5); | |
assertEqual(intersections[1][1], 0); | |
assertEqual(intersections[1][2], 0); | |
} | |
test_sphere_intersection(); |
I also have some minor comments.
line 35: I find that 'static function imports' like this (that's effectively what you're doing) are most readable at the top of the program.
line 53: I assume this is just in case you get a DNE number or some weird javascript type-ing? Might be worth throwing a slightly more descriptive error.
I think some of the math you're doing in lines 37-39 would be more readable if you created some more separate functions. Although you'll be making your code more verbose to do so, so that's up to you. Some that I would consider creating, a 'square' function (maybe call it sq()), something to do this for you: (y2 - y1)*(y1 - y3) given 3 variables.
Final minor point: I think you exceeded 80 columns (or is it 100 in github?) in line 39 which forces readers to use their scroll buttons (the horror!).
Two super minor comments:
Instead of
if (x === undefined){x = 0};
you could saythis.x = x || 0
Instead of specifying many properties in your constructor, like:
You could pass the constructor function an arguments object and iterate over each property to assign it to the new object. Like:
To be honest I have no idea if other people think this is "good" or "bad" practice (if anyone else at HS is reading this and thinks I'm nuts I'd love to know!), but it seems more efficient to me?