require 'bizzieLibrary' # represents an ordered collection of points in space # subclasses need to implement some form of doPath, doReversePath, etc. class Path end class ContinuousPath < Path def initialize(pathFunc = nil) @pathFunc = pathFunc end def doPath(epsilon) doRealPath(epsilon) { |val| yield doPathPoint(val), val } end def doPathReverse(epsilon) doRealPath(epsilon) { |val| yield doPathPoint(1.0 - val), 1.0 - val } end def doPathGen(func, startVal, endVal) doRealPathGen(func, startVal, endVal) {|epsilon, val| yield doPathPoint(epsilon), val } end def doPathGenReverse(func, startVal, endVal) doRealPathGen(func, startVal, endVal) {|epsilon, val| yield doPathPoint(1 - epsilon), endVal - val } end def points(epsilon) p = PathAccumulator.new doPath(epsilon) { |pt, val| p.doPoint(pt) } return p.points end def toDiscretePath(epsilon) return DiscretePath.new(points(epsilon)) end def doPathPoint(epsilon) if @pathFunc != nil @pathFunc[epsilon] end end def reverse return ReverseContinuousPath.new(self) end def +(path) return CompositePath.new([self, path]) end end class DiscretePath < Path def initialize(points = []) @points = points end def doPath @points.each_index do |ptIndex| yield @points[ptIndex], ptIndex end end def points @points end def addPoint(pt) @points << pt end def doPathPoint(num) @points[num] end def reverse return DiscretePath.new(@points.reverse) end def +(path) return DiscretePath.new(@points + path.points) end end def getDiscretePathArray(array) index = 0 ptArray = [] while index < array.length ptArray << Point2d.new(array[index], array[index + 1]) index += 2 end return DiscretePath.new(ptArray) end # changes behavior of doPathPoint to reverse the path class ReverseContinuousPath < ContinuousPath def initialize(path) @path = path end def doPathPoint(epsilon) return @path.doPathPoint(1.0 - epsilon) end end class CompositePath < ContinuousPath def initialize(paths) @paths = [] # add each path - unless it is a composite path, in which case flatten it! paths.each do |path| if path.instance_of?(CompositePath) path.paths.each do |p| @paths << p end else @paths << path end end end def numPaths @paths.length end def paths @paths end def doPathPoint(epsilon) newEps = epsilon * numPaths floor = newEps.floor if (floor >= numPaths) floor = numPaths - 1 end return paths[floor].doPathPoint(newEps - floor) end end class ParallelPath def initialize(paths) @paths = paths end def paths @paths end def doPaths(epsilon) doParallelPaths(paths, epsilon) end def doPathsGen(func, startVal, endVal) doParallelPathsGen(paths, func, startVal, endVal) end end def doPathsParallel(paths, epsilon) doRealPath(epsilon) { |val| sendVals = [] paths.each do |path| sendVals << path.doPathPoint(val) end yield sendVals, val } end def doPathsParallelGen(paths, func, startVal, endVal) doRealPathGen(func, startVal, endVal) {|epsilon, val| sendVals = [] paths.each do |path| sendVals << path.doPoint(epsilon) end yield sendVals, val } end def doPathsParallelPoints(paths, val) pts = [] paths.each do |path| pts << path.doPathPoint(val) end return pts end class PathDrawer def doPoint(point) if (@point) drawLine(@point, point) end @point = point end def init @point = nil end end class PathAccumulator def doPoint(point) if (!@points) @points = [] end @points << point end def init @points = [] end def points return @points end end class NPointAccumulator def initialize(n) @n = n end def doPoint(point) if (!@points) @points = [] end @points << point if @points.length >= @n yield @points @points.delete_at(0) end end def init @points = [] end end #functions on paths def doPath(path, epsilon) path.doPath(epsilon) end def doPathGen(path, func, startVal, endVal) path.doPathGen(func, startVal, endVal) end def doPaths(paths, epsilon) doRealPath(epsilon) { |val| sendVals = [] paths.each do |path| sendVals << path.doPathPoint(val) end yield sendVals, val } end def doPathsGen(paths, func, startVal, endVal) val = startVal while val <= endVal sendVals = [] paths.each do |path| sendVals << path.doPathPoint(func[val]) end yield sendVals, val val += 1 end end