Skip to content

Instantly share code, notes, and snippets.

@lawrencejones
Created January 20, 2015 18:43
Show Gist options
  • Save lawrencejones/9b4b9275bcd1c77cf0ab to your computer and use it in GitHub Desktop.
Save lawrencejones/9b4b9275bcd1c77cf0ab to your computer and use it in GitHub Desktop.
/node_modules
_ = require('underscore')
cartesianFrom = (A, B, C) ->
AB = vectorFrom(A, B)
BC = vectorFrom(B, C)
coefs = [a, b, c] = crossProduct(AB, BC)
d = _
.zip(coefs, A)
.reduce (sum, [a, b]) ->
sum + (a * b)
, 0
factor = [a, b, c, d]
.map(Math.abs)
.reduce (factor, n) ->
GCD(factor, n)
{
a: a / factor
b: b / factor
c: c / factor
d: d / factor
}
vectorFrom = (A, B) ->
_.zip(A, B).map ([a, b]) -> b - a
crossProduct = ([aX, aY, aZ], [bX, bY, bZ]) ->
[
+ ( (aY * bZ) - (aZ * bY) )
- ( (aX * bZ) - (aZ * bX) )
+ ( (aX * bY) - (aY * bX) )
]
GCD = (a, b) ->
[min, max] = if a < b then [a, b] else [b, a]
if min is 0 then max
else GCD(max % min, min)
# Testing ############################################################
describe? 'cartesian', ->
require('should')()
THREE_VECTOR_REX = (/(\[[^\]]+\])\s*[-=]>\s*(\[[^\]]+\])\s*[-=]>\s*(\[[^\]]+\])/)
describe '#cartesianFrom', ->
cartesianTest = (testCase, expected) ->
[A, B, C] = testCase
.match(THREE_VECTOR_REX)
.slice(1)
.map(eval)
it testCase, -> cartesianFrom(A, B, C).should.eql(expected)
cartesianTest '[10, 20, 5] -> [15, 10, 10] -> [25, 20, 10]', {
a: -1
b: 1
c: 3
d: 25
}
describe '#vectorFrom', ->
vectorTest = (testCase) ->
[A, B, vector] = testCase
.match(THREE_VECTOR_REX)
.slice(1)
.map(eval)
it testCase, -> vectorFrom(A, B).should.eql(vector)
vectorTest '[1, 2, 3] -> [5, 5, 5] => [4, 3, 2]'
vectorTest '[5, 5, 5] -> [3, 2, 1] => [-2, -3, -4]'
describe '#crossProduct', ->
crossTest = (testCase) ->
[A, B, cross] = testCase
.match(THREE_VECTOR_REX)
.slice(1)
.map(eval)
it testCase, -> crossProduct(A, B).should.eql(cross)
crossTest '[1, -2, 1] -> [1, 1, 0] => [-1, 1, 3]'
describe '#GCD', ->
gcdTest = (testCase) ->
[a, b, expected] = testCase
.match(/(\d+),\s*(\d+)\s*->\s*(\d+)/)
.slice(1)
.map(Number)
it testCase, ->
GCD(a, b).should.equal(expected)
gcdTest '0, 5 -> 5'
gcdTest '3, 7 -> 1'
gcdTest '100, 10 -> 10'
gcdTest '1071, 462 -> 21'
{
"name": "cartesian",
"version": "1.0.0",
"description": "Cartesian plane calculator",
"main": "cartesian.coffee",
"scripts": {
"test": "mocha --compilers coffee:coffee-script/register cartesian.coffee",
"watch": "mocha --compilers coffee:coffee-script/register -w cartesian.coffee"
},
"author": "Lawrence Jones",
"license": "MIT",
"dependencies": {
"coffee-script": "^1.8.0",
"mocha": "^2.1.0",
"should": "^4.6.1",
"underscore": "^1.7.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment