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



131
132
133
# File 'lib/geometry/point.rb', line 131

def x
  @x
end

#yNumeric (readonly)

Returns Y-component.

Returns:

  • (Numeric)

    Y-component



137
138
139
# File 'lib/geometry/point.rb', line 137

def y
  @y
end

#zNumeric (readonly)

Returns Z-component.

Returns:

  • (Numeric)

    Z-component



143
144
145
# File 'lib/geometry/point.rb', line 143

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



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

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



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/geometry/point.rb', line 160

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



151
152
153
# File 'lib/geometry/point.rb', line 151

def +@
    self
end

#-(other) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/geometry/point.rb', line 178

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



155
156
157
# File 'lib/geometry/point.rb', line 155

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

#/(other) ⇒ Object



215
216
217
218
219
220
221
222
# File 'lib/geometry/point.rb', line 215

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)



125
126
127
# File 'lib/geometry/point.rb', line 125

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

#to_sObject



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

def to_s
    'Point' + @elements.to_s
end