require 'bizzieLibrary' # uses linguistic approach # arithmetic def abs(x) if x < 0.0 return (-1.0 * x) else return x end end def square(x) return x ** 2 end def cube(x) return x ** 3 end def squareRoot(x) return x ** 0.5 end def cubeRoot(x) return x ** (1/3.to_f) end def invert(x) return 1.0 / x end def linearCombinationReals(x, y, epsilon) return ((1.0 - epsilon) * x + epsilon * y) end def compose(func1, func2) return lambda {|val| func1[func2[val]]} end # some nice functions $square = lambda {|val| if val.instance_of?(Proc) return compose($square, val) else return square(val) end } $cube = lambda {|val| if val.instance_of?(Proc) return compose($cube, val) else return cube(val) end } $power2 = lambda {|val| if val.instance_of?(Proc) return compose($power2, val) else return 2 ** val end } $invert = lambda {|val| if val.instance_of?(Proc) return compose($invert, val) else return invert(val) end } $flip = lambda {|val| if val.instance_of?(Proc) return compose($flip, val) else return 1.0 - val end } # helpers def sum(array) sum = 0.0 array.each do |x| sum += x end return sum end # constants $epsilonVal = 0.0000000001 $pi = Math::PI # paths #Paths def doRealPath(epsilon, startVal = 0.0, endVal = 1.0) val = startVal while val < endVal + $epsilonVal yield val val += epsilon end end def doRealPathGen(func, startVal, endVal) val = startVal while val <= endVal yield func[val], val val += 1 end end # vectors # mins/maxes def min(a, b) if a < b a else b end end def max(a, b) if a > b a else b end end # returns the cutoff of the value (rounds up to min, down to max) def cutoff(val, min, max) if val < min return min elsif val > max return max else return val end end # returns x in vals s.t. |x - val| is min def minDiff(val, vals) retVal = vals[0] retDiff = abs(val - vals[0]) vals.each do |v| if abs(v - val) < retDiff retVal = v retDiff = abs(v - val) end end return retVal end def minDiffIndex(val, vals) v = minDiff(val, vals) return vals.index(v) end def radiansToDegrees(radians) return (radians/(2.0 * Math::PI)) * 360.0 end def degreesToRadians(degrees) return (degrees/(360.0)) * 2 * Math::PI end def getAngle(x, y = nil) if x.is_a? Point2d y = x.y x = x.x end if x == 0.0 if y > 0 return 90.0 else return 270.0 end elsif x > 0 && y >= 0 return radiansToDegrees(Math.atan(y / x)) elsif x < 0 && y >= 0 return 180.0 - radiansToDegrees(Math.atan(y / (-1.0 * x))) elsif x < 0 && y < 0 return 180.0 + radiansToDegrees(Math.atan(y / x)) else return 360.0 + radiansToDegrees(Math.atan(y / x)) end end def inInterval?(x, a, b) return (min(a,b) <= x && x <= max(a,b)) end def subMin(a, b, c) diff = a - b if a - b < c return c else return diff end end def addMax(a, b, c) sum = a + b if sum > c return c else return sum end end # group theory #tests =begin puts "1, 0: " + getAngle(1.0, 0.0).to_s puts "1, 1: " + getAngle(1.0, 1.0).to_s puts "0, 1: " + getAngle(0.0, 1.0).to_s puts "-1, 1: " + getAngle(-1.0, 1.0).to_s puts "-1, 0: " + getAngle(-1.0, 0.0).to_s puts "-1, -1: " + getAngle(-1.0, -1.0).to_s puts "0, -1: " + getAngle(0.0, -1.0).to_s puts "1, -1: " + getAngle(1.0, -1.0).to_s puts "yo!" puts "point test: " + getAngle(Point2d.new(0.00001, 1.0)).to_s =end