lib/cyberarm_engine/lib/vector.rb in cyberarm_engine-0.2.0 vs lib/cyberarm_engine/lib/vector.rb in cyberarm_engine-0.3.0
- old
+ new
@@ -1,8 +1,7 @@
module CyberarmEngine
class Vector
-
def initialize(x = 0, y = 0, z = 0, weight = 0)
@x, @y, @z, @weight = x, y, z, weight
end
def x; @x; end
@@ -15,14 +14,10 @@
def z=(n); @z = n; end
def weight; @weight; end
def weight=(n); @weight = n; end
- # def xy=(nx, ny); @x = nx; @y = ny; end
- # def xyz=(nx, ny, nz); @x = nx; @y = ny; @z = nz; end
- # def xyzw=(nx, ny, nz, nw); @x = nx; @y = ny; @z = nz; @weight = nw; end
-
def ==(other)
if other.is_a?(Numeric)
@x == other &&
@y == other &&
@z == other &&
@@ -33,58 +28,130 @@
@z == other.z &&
@weight == other.weight
end
end
+ # Performs math operation, excluding @weight
+ def operator(function, other)
+ if other.is_a?(Numeric)
+ Vector.new(
+ @x.send(:"#{function}", other),
+ @y.send(:"#{function}", other),
+ @z.send(:"#{function}", other)
+ )
+ else
+ Vector.new(
+ @x.send(:"#{function}", other.x),
+ @y.send(:"#{function}", other.y),
+ @z.send(:"#{function}", other.z)
+ )
+ end
+ end
+
+ # Adds Vector and Numberic or Vector and Vector, excluding @weight
def +(other)
- Vector.new(
- @x + other.x,
- @y + other.y,
- @z + other.z,
- @weight + other.weight
- )
+ operator("+", other)
end
+ # Subtracts Vector and Numberic or Vector and Vector, excluding @weight
def -(other)
- Vector.new(
- @x - other.x,
- @y - other.y,
- @z - other.z,
- @weight - other.weight
- )
+ operator("-", other)
end
+ # Multiplies Vector and Numberic or Vector and Vector, excluding @weight
def *(other)
- Vector.new(
- @x * other.x,
- @y * other.y,
- @z * other.z,
- @weight * other.weight
+ operator("*", other)
+ end
+
+ # Divides Vector and Numberic or Vector and Vector, excluding @weight
+ def /(other)
+ # Duplicated to protect from DivideByZero
+ if other.is_a?(Numeric)
+ Vector.new(
+ (@x == 0 ? 0 : @x / other),
+ (@y == 0 ? 0 : @y / other),
+ (@z == 0 ? 0 : @z / other)
)
+ else
+ Vector.new(
+ (@x == 0 ? 0 : @x / other.x),
+ (@y == 0 ? 0 : @y / other.y),
+ (@z == 0 ? 0 : @z / other.z)
+ )
end
+ end
- def /(other)
- # Endeavors to prevent division by zero
+ def dot(other)
+ product = 0
+
+ a = self.to_a
+ b = other.to_a
+
+ 3.times do |i|
+ product = product + (a[i] * b[i])
+ end
+
+ return product
+ end
+
+ def cross(other)
+ a = self.to_a
+ b = other.to_a
+
Vector.new(
- @x == 0 || other.x == 0 ? 0 : @x / other.x,
- @y == 0 || other.y == 0 ? 0 : @y / other.y,
- @z == 0 || other.z == 0 ? 0 : @z / other.z,
- @weight == 0 || other.weight == 0 ? 0 : @weight / other.weight
+ b[2] * a[1] - b[1] * a[2],
+ b[0] * a[2] - b[2] * a[0],
+ b[1] * a[0] - b[0] * a[1]
)
end
+ # returns degrees
+ def angle(other)
+ Math.acos( self.normalized.dot(other.normalized) ) * 180 / Math::PI
+ end
+
# returns magnitude of Vector, ignoring #weight
def magnitude
Math.sqrt((@x * @x) + (@y * @y) + (@z * @z))
end
def normalized
mag = magnitude
self / Vector.new(mag, mag, mag)
end
+ def direction
+ # z is pitch
+ # y is yaw
+ # x is roll
+ _x = -Math.sin(@y.degrees_to_radians) * Math.cos(@z.degrees_to_radians)
+ _y = Math.sin(@z.degrees_to_radians)
+ _z = Math.cos(@y.degrees_to_radians) * Math.cos(@z.degrees_to_radians)
+
+ Vector.new(_x, _y, _z)
+ end
+
+ def inverse
+ Vector.new(1.0 / @x, 1.0 / @y, 1.0 / @z)
+ end
+
def sum
- @x + @y + @z + @weight
+ @x + @y + @z
+ end
+
+ # 2D distance using X and Y
+ def distance(other)
+ Math.sqrt((@x-other.x)**2 + (@y-other.y)**2)
+ end
+
+ # 2D distance using X and Z
+ def gl_distance2d(other)
+ Math.sqrt((@x-other.x)**2 + (@z-other.z)**2)
+ end
+
+ # 3D distance using X, Y, and Z
+ def distance3d(other)
+ Math.sqrt((@x-other.x)**2 + (@y-other.y)**2 + (@z-other.z)**2)
end
def to_a
[@x, @y, @z, @weight]
end
\ No newline at end of file