Class: Geometry::Point

Inherits:
Vector
  • Object
show all
Defined in:
lib/geometry/point.rb

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

Accessors collapse

Unary operators collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Vector

#cross

Instance Attribute Details

#xNumeric (readonly)

Returns X-component.

Returns:

  • (Numeric)

    X-component



169
170
171
# File 'lib/geometry/point.rb', line 169

def x
  @x
end

#yNumeric (readonly)

Returns Y-component.

Returns:

  • (Numeric)

    Y-component



175
176
177
# File 'lib/geometry/point.rb', line 175

def y
  @y
end

#zNumeric (readonly)

Returns Z-component.

Returns:

  • (Numeric)

    Z-component



181
182
183
# File 'lib/geometry/point.rb', line 181

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.

Parameters:

  • value (Number)

    the value of the elements

  • size (Number) (defaults to: nil)

    the size of the new Geometry::Point full of ones

Returns:



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.

Parameters:

  • size (Number) (defaults to: nil)

    the size of the new Geometry::Point full of ones

Returns:



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.

Parameters:

  • size (Number) (defaults to: nil)

    the size of the new Geometry::Point full of zeros

Returns:



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



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/geometry/point.rb', line 234

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



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/geometry/point.rb', line 198

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



189
190
191
# File 'lib/geometry/point.rb', line 189

def +@
    self
end

#-(other) ⇒ Object



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/geometry/point.rb', line 216

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



193
194
195
# File 'lib/geometry/point.rb', line 193

def -@
    Point[@elements.map {|e| -e }]
end

#/(other) ⇒ Object



253
254
255
256
257
258
259
260
# File 'lib/geometry/point.rb', line 253

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

Returns:

  • (Point)

    The <=> operator is applied to the elements of the arguments pairwise and the results are returned in a Point



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).

Parameters:

Returns:

  • (Numeric)

    Element i (starting at 0)



163
164
165
# File 'lib/geometry/point.rb', line 163

def [](*args)
    @elements[*args]
end

#cloneObject

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

Returns:

  • (Boolean)


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

#inspectObject



115
116
117
# File 'lib/geometry/point.rb', line 115

def inspect
    'Point' + @elements.inspect
end

#max(*args) ⇒ Number, Point

Returns:



126
127
128
129
130
131
132
133
# File 'lib/geometry/point.rb', line 126

def max(*args)
    if args.empty?
	@elements.max
    else
	args = args.first if 1 == args.size
	self.class[@elements.zip(args).map(&:max)]
    end
end

#min(*args) ⇒ Number, Point

Returns:



139
140
141
142
143
144
145
146
# File 'lib/geometry/point.rb', line 139

def min(*args)
    if args.empty?
	@elements.min
    else
	args = args.first if 1 == args.size
	self.class[@elements.zip(args).map(&:min)]
    end
end

#minmax(*args) ⇒ Array<Number>, Array<Point>

Returns:



152
153
154
155
156
157
158
# File 'lib/geometry/point.rb', line 152

def minmax(*args)
    if args.empty?
	@elements.minmax
    else
	[min(*args), max(*args)]
    end
end

#to_sObject



118
119
120
# File 'lib/geometry/point.rb', line 118

def to_s
    'Point' + @elements.to_s
end