Class: Geometry::Point
Overview
An object repesenting a Point in N-dimensional space
Supports all of the familiar Vector methods and adds convenience accessors for those variables you learned to hate in your high school geometry class (x, y, z).
Usage
Constructor
point = Geometry::Point[x,y]
Constant Summary
Constants inherited from Vector
Vector::X, Vector::Y, Vector::Z
Accessors collapse
-
#x ⇒ Numeric
readonly
X-component.
-
#y ⇒ Numeric
readonly
Y-component.
-
#z ⇒ Numeric
readonly
Z-component.
Accessors collapse
-
#[](*args) ⇒ Numeric
Element i (starting at 0).
Unary operators collapse
Class Method Summary collapse
-
.[](*array) ⇒ Object
Allow vector-style initialization, but override to support copy-init from Vector or another Point.
-
.iso(value, size = nil) ⇒ PointIso
Creates and returns a new PointIso instance.
-
.one(size = nil) ⇒ PointOne
Creates and returns a new PointOne instance.
-
.zero(size = nil) ⇒ PointZero
Creates and returns a new PointZero instance.
Instance Method Summary collapse
- #*(other) ⇒ Object
- #+(other) ⇒ Object
- #-(other) ⇒ Object
- #/(other) ⇒ Object
-
#<=>(other) ⇒ Point
Combined comparison operator.
-
#==(other) ⇒ Object
Allow comparison with an Array, otherwise do the normal thing.
-
#clone ⇒ Object
Return a copy of the Point.
- #coerce(other) ⇒ Object
-
#eql?(other) ⇒ Boolean
Allow comparison with an Array, otherwise do the normal thing.
- #inspect ⇒ Object
- #max(*args) ⇒ Number, Point
- #min(*args) ⇒ Number, Point
- #minmax(*args) ⇒ Array<Number>, Array<Point>
-
#pop(count = 1) ⇒ Point
Returns a new Point with the given number of elements removed from the end.
-
#push(*args) ⇒ Point
Returns a new Point with the given elements appended.
-
#shift(count = 1) ⇒ Point
Removes the first element and returns it.
- #to_s ⇒ Object
-
#unshift(*args) ⇒ Point
Prepend the given objects and return a new Point.
Methods inherited from Vector
Instance Attribute Details
#x ⇒ Numeric (readonly)
Returns X-component.
205 206 207 |
# File 'lib/geometry/point.rb', line 205 def x @x end |
#y ⇒ Numeric (readonly)
Returns Y-component.
211 212 213 |
# File 'lib/geometry/point.rb', line 211 def y @y end |
#z ⇒ Numeric (readonly)
Returns Z-component.
217 218 219 |
# File 'lib/geometry/point.rb', line 217 def z @z end |
Class Method Details
.[](x, y, z, ...) ⇒ Object .[](Array) ⇒ Object .[](Point) ⇒ Object .[](Vector) ⇒ Object
Allow vector-style initialization, but override to support copy-init from Vector or another Point
33 34 35 36 37 38 |
# File 'lib/geometry/point.rb', line 33 def self.[](*array) return array[0] if array[0].is_a?(Point) array = array[0] if array[0].is_a?(Array) array = array[0].to_a if array[0].is_a?(Vector) super *array end |
.iso(value, size = nil) ⇒ PointIso
Creates and returns a new Geometry::PointIso instance. Or, a Geometry::Point full of ones if the size argument is given.
44 45 46 |
# File 'lib/geometry/point.rb', line 44 def self.iso(value, size=nil) size ? Point[Array.new(size, 1)] : PointIso.new(value) end |
.one(size = nil) ⇒ PointOne
Creates and returns a new Geometry::PointOne instance. Or, a Geometry::Point full of ones if the size argument is given.
51 52 53 |
# File 'lib/geometry/point.rb', line 51 def self.one(size=nil) size ? Point[Array.new(size, 1)] : PointOne.new end |
.zero(size = nil) ⇒ PointZero
Creates and returns a new Geometry::PointZero instance. Or, a Geometry::Point full of zeros if the size argument is given.
58 59 60 |
# File 'lib/geometry/point.rb', line 58 def self.zero(size=nil) size ? Point[Array.new(size, 0)] : PointZero.new end |
Instance Method Details
#*(other) ⇒ Object
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/geometry/point.rb', line 270 def *(other) case other when NilClass nil when Numeric Point[@elements.map {|e| e * other}] when PointZero Point.zero else if other.respond_to?(:[]) raise OperationNotDefined, "#{other.class} must respond to :size" unless other.respond_to?(:size) raise DimensionMismatch, "Can't multiply #{self} by #{other}" if size != other.size Point[Array.new(size) {|i| @elements[i] * other[i] }] else Point[@elements.map {|e| e * other}] end end end |
#+(other) ⇒ Object
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/geometry/point.rb', line 234 def +(other) case other when Numeric Point[@elements.map {|e| e + other}] when PointIso value = other.value Point[@elements.map {|e| e + value}] when PointOne Point[@elements.map {|e| e + 1}] when PointZero, NilClass self.dup else raise OperationNotDefined, "#{other.class} must respond to :size and :[]" unless other.respond_to?(:size) && other.respond_to?(:[]) raise DimensionMismatch, "Can't add #{other} to #{self}" if size != other.size Point[Array.new(size) {|i| @elements[i] + other[i] }] end end |
#+@ ⇒ Object
225 226 227 |
# File 'lib/geometry/point.rb', line 225 def +@ self end |
#-(other) ⇒ Object
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/geometry/point.rb', line 252 def -(other) case other when Numeric Point[@elements.map {|e| e - other}] when PointIso value = other.value Point[@elements.map {|e| e - value}] when PointOne Point[@elements.map {|e| e - 1}] when PointZero, NilClass self.dup else raise OperationNotDefined, "#{other.class} must respond to :size and :[]" unless other.respond_to?(:size) && other.respond_to?(:[]) raise DimensionMismatch, "Can't subtract #{other} from #{self}" if size != other.size Point[Array.new(size) {|i| @elements[i] - other[i] }] end end |
#-@ ⇒ Object
229 230 231 |
# File 'lib/geometry/point.rb', line 229 def -@ Point[@elements.map {|e| -e }] end |
#/(other) ⇒ Object
289 290 291 292 293 294 295 296 |
# File 'lib/geometry/point.rb', line 289 def /(other) case other when Matrix, Vector, Point, Size, NilClass, PointZero, SizeZero raise OperationNotDefined, "Can't divide #{self} by #{other}" else Point[@elements.map {|e| e / other}] end end |
#<=>(other) ⇒ Point
Combined comparison operator
101 102 103 |
# File 'lib/geometry/point.rb', line 101 def <=>(other) Point[self.to_a.zip(other.to_a).map {|a,b| a <=> b}.compact] end |
#==(other) ⇒ Object
Allow comparison with an Array, otherwise do the normal thing
84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/geometry/point.rb', line 84 def ==(other) if other.is_a?(Array) @elements.eql? other elsif other.is_a?(PointIso) value = other.value @elements.all? {|e| e.eql? value } elsif other.is_a?(PointOne) @elements.all? {|e| e.eql? 1 } elsif other.is_a?(PointZero) @elements.all? {|e| e.eql? 0 } else super other end end |
#[](*args) ⇒ Numeric
Returns Element i (starting at 0).
199 200 201 |
# File 'lib/geometry/point.rb', line 199 def [](*args) @elements[*args] end |
#clone ⇒ Object
Return a copy of the Geometry::Point
63 64 65 |
# File 'lib/geometry/point.rb', line 63 def clone Point[@elements.clone] end |
#coerce(other) ⇒ Object
105 106 107 108 109 110 111 112 113 |
# File 'lib/geometry/point.rb', line 105 def coerce(other) case other when Array then [Point[*other], self] when Numeric then [Point[Array.new(self.size, other)], self] when Vector then [Point[*other], self] else raise TypeError, "#{self.class} can't be coerced into #{other.class}" end end |
#eql?(other) ⇒ Boolean
Allow comparison with an Array, otherwise do the normal thing
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/geometry/point.rb', line 68 def eql?(other) if other.is_a?(Array) @elements.eql? other elsif other.is_a?(PointIso) value = other.value @elements.all? {|e| e.eql? value } elsif other.is_a?(PointOne) @elements.all? {|e| e.eql? 1 } elsif other.is_a?(PointZero) @elements.all? {|e| e.eql? 0 } else super other end end |
#inspect ⇒ Object
115 116 117 |
# File 'lib/geometry/point.rb', line 115 def inspect 'Point' + @elements.inspect end |
#max(*args) ⇒ Number, Point
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/geometry/point.rb', line 126 def max(*args) if args.empty? @elements.max else args = args.first if 1 == args.size case args when PointIso then self.class[@elements.map {|e| [e, args.value].max }] when PointOne then self.class[@elements.map {|e| [e, 1].max }] when PointZero then self.class[@elements.map {|e| [e, 0].max }] else self.class[@elements.zip(args).map(&:max)] end end end |
#min(*args) ⇒ Number, Point
145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/geometry/point.rb', line 145 def min(*args) if args.empty? @elements.min else args = args.first if 1 == args.size case args when PointIso then self.class[@elements.map {|e| [e, args.value].min }] when PointOne then self.class[@elements.map {|e| [e, 1].min }] when PointZero then self.class[@elements.map {|e| [e, 0].min }] else self.class[@elements.zip(args).map(&:min)] end end end |
#minmax(*args) ⇒ Array<Number>, Array<Point>
164 165 166 167 168 169 170 |
# File 'lib/geometry/point.rb', line 164 def minmax(*args) if args.empty? @elements.minmax else [min(*args), max(*args)] end end |
#pop(count = 1) ⇒ Point
Returns a new Geometry::Point with the given number of elements removed from the end
174 175 176 |
# File 'lib/geometry/point.rb', line 174 def pop(count=1) self.class[to_a.pop(count)] end |
#push(*args) ⇒ Point
Returns a new Geometry::Point with the given elements appended
180 181 182 |
# File 'lib/geometry/point.rb', line 180 def push(*args) self.class[to_a.push(*args)] end |
#shift(count = 1) ⇒ Point
Removes the first element and returns it
186 187 188 |
# File 'lib/geometry/point.rb', line 186 def shift(count=1) self.class[to_a.shift(count)] end |
#to_s ⇒ Object
118 119 120 |
# File 'lib/geometry/point.rb', line 118 def to_s 'Point' + @elements.to_s end |
#unshift(*args) ⇒ Point
Prepend the given objects and return a new Geometry::Point
192 193 194 |
# File 'lib/geometry/point.rb', line 192 def unshift(*args) self.class[to_a.unshift(*args)] end |